diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 3c8ddbcac..1e6ca4c99 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -348,6 +348,8 @@ if(CONFIG_BT_ENABLED) "esp_ble_mesh/mesh_common/mesh_buf.c" "esp_ble_mesh/mesh_common/mesh_common.c" "esp_ble_mesh/mesh_common/mesh_kernel.c" + "esp_ble_mesh/mesh_common/mesh_mutex.c" + "esp_ble_mesh/mesh_common/mesh_timer.c" "esp_ble_mesh/mesh_common/mesh_util.c" "esp_ble_mesh/mesh_core/storage/settings_nvs.c" "esp_ble_mesh/mesh_core/access.c" 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 984d31d5a..832e03dbb 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 @@ -17,8 +17,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "btc/btc_manage.h" - #include "esp_err.h" #include "btc_ble_mesh_prov.h" diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c index 5d86dda5a..95a8039ff 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c @@ -14,8 +14,6 @@ #include -#include "btc/btc_manage.h" - #include "esp_err.h" #include "btc_ble_mesh_prov.h" diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c index c4942b4a6..23bebe595 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c @@ -14,8 +14,6 @@ #include -#include "btc/btc_manage.h" - #include "esp_err.h" #include "btc_ble_mesh_prov.h" 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 0f36723e5..080cf190d 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 @@ -15,8 +15,6 @@ #include #include -#include "btc/btc_manage.h" - #include "esp_err.h" #include "btc_ble_mesh_prov.h" @@ -71,9 +69,9 @@ static esp_err_t ble_mesh_model_send_msg(esp_ble_mesh_model_t *model, } if (act == BTC_BLE_MESH_ACT_MODEL_PUBLISH) { - mic_len = 4; + mic_len = ESP_BLE_MESH_MIC_SHORT; } else { - mic_len = ctx->send_rel ? 8 : 4; + mic_len = ctx->send_rel ? ESP_BLE_MESH_MIC_LONG : ESP_BLE_MESH_MIC_SHORT; } if (op_len + length + mic_len > MIN(ESP_BLE_MESH_SDU_MAX_LEN, ESP_BLE_MESH_TX_SDU_MAX)) { diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c index b1f19cb91..9fbbd6b59 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c @@ -15,8 +15,6 @@ #include #include -#include "btc/btc_manage.h" - #include "esp_err.h" #include "btc_ble_mesh_prov.h" diff --git a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c index 071e0e37f..31a3aa9ab 100644 --- a/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c +++ b/components/bt/esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c @@ -15,8 +15,6 @@ #include #include -#include "btc/btc_manage.h" - #include "esp_err.h" #include "btc_ble_mesh_prov.h" 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 acc8a818e..531f96eeb 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 @@ -38,6 +38,12 @@ extern "C" { /*!< The maximum length of a BLE Mesh message, including Opcode, Payload and TransMIC */ #define ESP_BLE_MESH_SDU_MAX_LEN 384 +/*!< Length of a short Mesh MIC. */ +#define ESP_BLE_MESH_MIC_SHORT 4 + +/*!< Length of a long Mesh MIC. */ +#define ESP_BLE_MESH_MIC_LONG 8 + /*!< The maximum length of a BLE Mesh provisioned node name */ #define ESP_BLE_MESH_NODE_NAME_MAX_LEN 31 @@ -369,7 +375,8 @@ typedef struct { uint16_t publish_addr; /*!< Publish Address. */ uint16_t app_idx:12, /*!< Publish AppKey Index. */ - cred:1; /*!< Friendship Credentials Flag. */ + cred:1, /*!< Friendship Credentials Flag. */ + send_rel:1; /*!< Force reliable sending (segment acks) */ uint8_t ttl; /*!< Publish Time to Live. */ uint8_t retransmit; /*!< Retransmit Count & Interval Steps. */ 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 20a86c8fa..f5bb75edb 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 @@ -15,11 +15,9 @@ #include #include -#include "foundation.h" -#include "mesh_common.h" -#include "cfg_cli.h" - #include "btc_ble_mesh_config_model.h" +#include "foundation.h" +#include "cfg_cli.h" #include "esp_ble_mesh_config_model_api.h" #define CID_NVAL 0xffff 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 a9e0d9049..7a9c5348f 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 @@ -15,10 +15,8 @@ #include #include -#include "mesh_common.h" -#include "generic_client.h" - #include "btc_ble_mesh_generic_model.h" +#include "generic_client.h" #include "esp_ble_mesh_generic_model_api.h" /* Generic Client Models related functions */ 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 769d2e3f6..2eb1cf4d2 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 @@ -15,13 +15,11 @@ #include #include +#include "btc_ble_mesh_health_model.h" #include "foundation.h" -#include "mesh_common.h" #include "health_srv.h" #include "health_cli.h" - -#include "btc_ble_mesh_health_model.h" -#include "esp_ble_mesh_defs.h" +#include "esp_ble_mesh_health_model_api.h" extern s32_t health_msg_timeout; 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 7737f2bfd..881693144 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 @@ -15,10 +15,8 @@ #include #include -#include "mesh_common.h" -#include "lighting_client.h" - #include "btc_ble_mesh_lighting_model.h" +#include "lighting_client.h" #include "esp_ble_mesh_lighting_model_api.h" /* Lighting Client Models related functions */ 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 f136b615a..d4c063011 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 @@ -15,10 +15,16 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" +#include "btc_ble_mesh_prov.h" +#include "btc_ble_mesh_config_model.h" +#include "btc_ble_mesh_health_model.h" +#include "btc_ble_mesh_generic_model.h" +#include "btc_ble_mesh_time_scene_model.h" +#include "btc_ble_mesh_sensor_model.h" +#include "btc_ble_mesh_lighting_model.h" #include "adv.h" +#include "mesh_kernel.h" #include "mesh_proxy.h" #include "mesh.h" #include "access.h" @@ -39,15 +45,6 @@ #include "client_common.h" #include "state_binding.h" -#include "btc_ble_mesh_prov.h" -#include "btc_ble_mesh_config_model.h" -#include "btc_ble_mesh_health_model.h" -#include "btc_ble_mesh_generic_model.h" -#include "btc_ble_mesh_time_scene_model.h" -#include "btc_ble_mesh_sensor_model.h" -#include "btc_ble_mesh_lighting_model.h" - -#include "esp_ble_mesh_defs.h" #include "esp_ble_mesh_common_api.h" #include "esp_ble_mesh_provisioning_api.h" #include "esp_ble_mesh_networking_api.h" @@ -1965,8 +1962,8 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg) break; } case BTC_BLE_MESH_ACT_SERVER_MODEL_SEND: { - /* arg->model_send.length contains opcode & message, 4 is used for TransMIC */ - struct net_buf_simple *buf = bt_mesh_alloc_buf(arg->model_send.length + 4); + /* 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) { BT_ERR("%s, Failed to allocate memory", __func__); break; @@ -1983,8 +1980,8 @@ void btc_ble_mesh_model_call_handler(btc_msg_t *msg) } case BTC_BLE_MESH_ACT_CLIENT_MODEL_SEND: { bt_mesh_role_param_t common = {0}; - /* arg->model_send.length contains opcode & message, 4 is used for TransMIC */ - struct net_buf_simple *buf = bt_mesh_alloc_buf(arg->model_send.length + 4); + /* 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) { BT_ERR("%s, Failed to allocate memory", __func__); break; 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 cc906d76d..2021f81a0 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 @@ -15,10 +15,8 @@ #include #include -#include "mesh_common.h" -#include "sensor_client.h" - #include "btc_ble_mesh_sensor_model.h" +#include "sensor_client.h" #include "esp_ble_mesh_sensor_model_api.h" /* Sensor Client Models related functions */ 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 d33702edd..6dd93b31a 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 @@ -15,10 +15,8 @@ #include #include -#include "mesh_common.h" -#include "time_scene_client.h" - #include "btc_ble_mesh_time_scene_model.h" +#include "time_scene_client.h" #include "esp_ble_mesh_time_scene_model_api.h" /* Time and Scenes Client Models related functions */ 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 2f7540e91..62f52ccee 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 @@ -16,6 +16,7 @@ #define _BTC_BLE_MESH_PROV_H_ #include "btc/btc_manage.h" +#include "mesh_byteorder.h" #include "mesh_main.h" #include "provisioner_prov.h" #include "esp_ble_mesh_defs.h" diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h index 9609698be..bcc7b513a 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h @@ -12,6 +12,7 @@ #define _BLE_MESH_BUF_H_ #include "mesh_slist.h" +#include "mesh_compiler.h" #ifdef __cplusplus extern "C" { @@ -241,6 +242,30 @@ void net_buf_simple_add_le16(struct net_buf_simple *buf, u16_t val); */ void net_buf_simple_add_be16(struct net_buf_simple *buf, u16_t val); +/** + * @brief Add 24-bit value at the end of the buffer + * + * Adds 24-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 24-bit value to be added. + */ +void net_buf_simple_add_le24(struct net_buf_simple *buf, u32_t val); + +/** + * @brief Add 24-bit value at the end of the buffer + * + * Adds 24-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 24-bit value to be added. + */ +void net_buf_simple_add_be24(struct net_buf_simple *buf, u32_t val); + /** * @brief Add 32-bit value at the end of the buffer * @@ -265,6 +290,54 @@ void net_buf_simple_add_le32(struct net_buf_simple *buf, u32_t val); */ void net_buf_simple_add_be32(struct net_buf_simple *buf, u32_t val); +/** + * @brief Add 48-bit value at the end of the buffer + * + * Adds 48-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 48-bit value to be added. + */ +void net_buf_simple_add_le48(struct net_buf_simple *buf, u64_t val); + +/** + * @brief Add 48-bit value at the end of the buffer + * + * Adds 48-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 48-bit value to be added. + */ +void net_buf_simple_add_be48(struct net_buf_simple *buf, u64_t val); + +/** + * @brief Add 64-bit value at the end of the buffer + * + * Adds 64-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 64-bit value to be added. + */ +void net_buf_simple_add_le64(struct net_buf_simple *buf, u64_t val); + +/** + * @brief Add 64-bit value at the end of the buffer + * + * Adds 64-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 64-bit value to be added. + */ +void net_buf_simple_add_be64(struct net_buf_simple *buf, u64_t val); + /** * @brief Push data to the beginning of the buffer. * @@ -310,6 +383,94 @@ void net_buf_simple_push_be16(struct net_buf_simple *buf, u16_t val); */ void net_buf_simple_push_u8(struct net_buf_simple *buf, u8_t val); +/** + * @brief Push 24-bit value to the beginning of the buffer + * + * Adds 24-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 24-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_le24(struct net_buf_simple *buf, u32_t val); + +/** + * @brief Push 24-bit value to the beginning of the buffer + * + * Adds 24-bit value in big endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 24-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_be24(struct net_buf_simple *buf, u32_t val); + +/** + * @brief Push 32-bit value to the beginning of the buffer + * + * Adds 32-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 32-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_le32(struct net_buf_simple *buf, u32_t val); + +/** + * @brief Push 32-bit value to the beginning of the buffer + * + * Adds 32-bit value in big endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 32-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_be32(struct net_buf_simple *buf, u32_t val); + +/** + * @brief Push 48-bit value to the beginning of the buffer + * + * Adds 48-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 48-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_le48(struct net_buf_simple *buf, u64_t val); + +/** + * @brief Push 48-bit value to the beginning of the buffer + * + * Adds 48-bit value in big endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 48-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_be48(struct net_buf_simple *buf, u64_t val); + +/** + * @brief Push 64-bit value to the beginning of the buffer + * + * Adds 64-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 64-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_le64(struct net_buf_simple *buf, u64_t val); + +/** + * @brief Push 64-bit value to the beginning of the buffer + * + * Adds 64-bit value in big endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 64-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_be64(struct net_buf_simple *buf, u64_t val); + /** * @brief Remove data from the beginning of the buffer. * @@ -372,6 +533,30 @@ u16_t net_buf_simple_pull_le16(struct net_buf_simple *buf); */ u16_t net_buf_simple_pull_be16(struct net_buf_simple *buf); +/** + * @brief Remove and convert 24 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 24-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 24-bit value converted from little endian to host endian. + */ +u32_t net_buf_simple_pull_le24(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 24 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 24-bit big endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 24-bit value converted from big endian to host endian. + */ +u32_t net_buf_simple_pull_be24(struct net_buf_simple *buf); + /** * @brief Remove and convert 32 bits from the beginning of the buffer. * @@ -396,6 +581,54 @@ u32_t net_buf_simple_pull_le32(struct net_buf_simple *buf); */ u32_t net_buf_simple_pull_be32(struct net_buf_simple *buf); +/** + * @brief Remove and convert 48 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 48-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 48-bit value converted from little endian to host endian. + */ +u64_t net_buf_simple_pull_le48(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 48 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 48-bit big endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 48-bit value converted from big endian to host endian. + */ +u64_t net_buf_simple_pull_be48(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 64 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 64-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 64-bit value converted from little endian to host endian. + */ +u64_t net_buf_simple_pull_le64(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 64 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 64-bit big endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 64-bit value converted from big endian to host endian. + */ +u64_t net_buf_simple_pull_be64(struct net_buf_simple *buf); + /** * @brief Get the tail pointer for a buffer. * @@ -882,6 +1115,32 @@ static inline void *net_buf_user_data(struct net_buf *buf) */ #define net_buf_add_be16(buf, val) net_buf_simple_add_be16(&(buf)->b, val) +/** + * @def net_buf_add_le24 + * @brief Add 24-bit value at the end of the buffer + * + * Adds 24-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 24-bit value to be added. + */ +#define net_buf_add_le24(buf, val) net_buf_simple_add_le24(&(buf)->b, val) + +/** + * @def net_buf_add_be24 + * @brief Add 24-bit value at the end of the buffer + * + * Adds 24-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 24-bit value to be added. + */ +#define net_buf_add_be24(buf, val) net_buf_simple_add_be24(&(buf)->b, val) + /** * @def net_buf_add_le32 * @brief Add 32-bit value at the end of the buffer @@ -908,6 +1167,58 @@ static inline void *net_buf_user_data(struct net_buf *buf) */ #define net_buf_add_be32(buf, val) net_buf_simple_add_be32(&(buf)->b, val) +/** + * @def net_buf_add_le48 + * @brief Add 48-bit value at the end of the buffer + * + * Adds 48-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 48-bit value to be added. + */ +#define net_buf_add_le48(buf, val) net_buf_simple_add_le48(&(buf)->b, val) + +/** + * @def net_buf_add_be48 + * @brief Add 48-bit value at the end of the buffer + * + * Adds 48-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 48-bit value to be added. + */ +#define net_buf_add_be48(buf, val) net_buf_simple_add_be48(&(buf)->b, val) + +/** + * @def net_buf_add_le64 + * @brief Add 64-bit value at the end of the buffer + * + * Adds 64-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 64-bit value to be added. + */ +#define net_buf_add_le64(buf, val) net_buf_simple_add_le64(&(buf)->b, val) + +/** + * @def net_buf_add_be64 + * @brief Add 64-bit value at the end of the buffer + * + * Adds 64-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 64-bit value to be added. + */ +#define net_buf_add_be64(buf, val) net_buf_simple_add_be64(&(buf)->b, val) + /** * @def net_buf_push * @brief Push data to the beginning of the buffer. @@ -957,6 +1268,102 @@ static inline void *net_buf_user_data(struct net_buf *buf) */ #define net_buf_push_u8(buf, val) net_buf_simple_push_u8(&(buf)->b, val) +/** + * @def net_buf_push_le24 + * @brief Push 24-bit value to the beginning of the buffer + * + * Adds 24-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 24-bit value to be pushed to the buffer. + */ +#define net_buf_push_le24(buf, val) net_buf_simple_push_le24(&(buf)->b, val) + +/** + * @def net_buf_push_be24 + * @brief Push 24-bit value to the beginning of the buffer + * + * Adds 24-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 24-bit value to be pushed to the buffer. + */ +#define net_buf_push_be24(buf, val) net_buf_simple_push_be24(&(buf)->b, val) + +/** + * @def net_buf_push_le32 + * @brief Push 32-bit value to the beginning of the buffer + * + * Adds 32-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 32-bit value to be pushed to the buffer. + */ +#define net_buf_push_le32(buf, val) net_buf_simple_push_le32(&(buf)->b, val) + +/** + * @def net_buf_push_be32 + * @brief Push 32-bit value to the beginning of the buffer + * + * Adds 32-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 32-bit value to be pushed to the buffer. + */ +#define net_buf_push_be32(buf, val) net_buf_simple_push_be32(&(buf)->b, val) + +/** + * @def net_buf_push_le48 + * @brief Push 48-bit value to the beginning of the buffer + * + * Adds 48-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 48-bit value to be pushed to the buffer. + */ +#define net_buf_push_le48(buf, val) net_buf_simple_push_le48(&(buf)->b, val) + +/** + * @def net_buf_push_be48 + * @brief Push 48-bit value to the beginning of the buffer + * + * Adds 48-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 48-bit value to be pushed to the buffer. + */ +#define net_buf_push_be48(buf, val) net_buf_simple_push_be48(&(buf)->b, val) + +/** + * @def net_buf_push_le64 + * @brief Push 64-bit value to the beginning of the buffer + * + * Adds 64-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 64-bit value to be pushed to the buffer. + */ +#define net_buf_push_le64(buf, val) net_buf_simple_push_le64(&(buf)->b, val) + +/** + * @def net_buf_push_be64 + * @brief Push 64-bit value to the beginning of the buffer + * + * Adds 64-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 64-bit value to be pushed to the buffer. + */ +#define net_buf_push_be64(buf, val) net_buf_simple_push_be64(&(buf)->b, val) + /** * @def net_buf_pull * @brief Remove data from the beginning of the buffer. @@ -1024,6 +1431,32 @@ static inline void *net_buf_user_data(struct net_buf *buf) */ #define net_buf_pull_be16(buf) net_buf_simple_pull_be16(&(buf)->b) +/** + * @def net_buf_pull_le24 + * @brief Remove and convert 24 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 24-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 24-bit value converted from little endian to host endian. + */ +#define net_buf_pull_le24(buf) net_buf_simple_pull_le24(&(buf)->b) + +/** + * @def net_buf_pull_be24 + * @brief Remove and convert 24 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 24-bit big endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 24-bit value converted from big endian to host endian. + */ +#define net_buf_pull_be24(buf) net_buf_simple_pull_be24(&(buf)->b) + /** * @def net_buf_pull_le32 * @brief Remove and convert 32 bits from the beginning of the buffer. @@ -1050,6 +1483,58 @@ static inline void *net_buf_user_data(struct net_buf *buf) */ #define net_buf_pull_be32(buf) net_buf_simple_pull_be32(&(buf)->b) +/** + * @def net_buf_pull_le48 + * @brief Remove and convert 48 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 48-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 48-bit value converted from little endian to host endian. + */ +#define net_buf_pull_le48(buf) net_buf_simple_pull_le48(&(buf)->b) + +/** + * @def net_buf_pull_be48 + * @brief Remove and convert 48 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 48-bit big endian data. + * + * @param buf A valid pointer on a buffer + * + * @return 48-bit value converted from big endian to host endian. + */ +#define net_buf_pull_be48(buf) net_buf_simple_pull_be48(&(buf)->b) + +/** + * @def net_buf_pull_le64 + * @brief Remove and convert 64 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 64-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 64-bit value converted from little endian to host endian. + */ +#define net_buf_pull_le64(buf) net_buf_simple_pull_le64(&(buf)->b) + +/** + * @def net_buf_pull_be64 + * @brief Remove and convert 64 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 64-bit big endian data. + * + * @param buf A valid pointer on a buffer + * + * @return 64-bit value converted from big endian to host endian. + */ +#define net_buf_pull_be64(buf) net_buf_simple_pull_be64(&(buf)->b) + /** * @def net_buf_tailroom * @brief Check buffer tailroom. diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_byteorder.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_byteorder.h new file mode 100644 index 000000000..f570bd6e0 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_byteorder.h @@ -0,0 +1,599 @@ +/* + * Copyright (c) 2015-2016, Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _BLE_MESH_BYTEORDER_H_ +#define _BLE_MESH_BYTEORDER_H_ + +#include "mesh_types.h" +#include "mesh_trace.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Internal helpers only used by the sys_* APIs further below */ +#ifndef __bswap_16 +#define __bswap_16(x) ((u16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) +#endif + +#ifndef __bswap_24 +#define __bswap_24(x) ((u32_t) ((((x) >> 16) & 0xff) | \ + (((x)) & 0xff00) | \ + (((x) & 0xff) << 16))) +#endif + +#ifndef __bswap_32 +#define __bswap_32(x) ((u32_t) ((((x) >> 24) & 0xff) | \ + (((x) >> 8) & 0xff00) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff) << 24))) +#endif + +#ifndef __bswap_48 +#define __bswap_48(x) ((u64_t) ((((x) >> 40) & 0xff) | \ + (((x) >> 24) & 0xff00) | \ + (((x) >> 8) & 0xff0000) | \ + (((x) & 0xff0000) << 8) | \ + (((x) & 0xff00) << 24) | \ + (((x) & 0xff) << 40))) +#endif + +#ifndef __bswap_64 +#define __bswap_64(x) ((u64_t) ((((x) >> 56) & 0xff) | \ + (((x) >> 40) & 0xff00) | \ + (((x) >> 24) & 0xff0000) | \ + (((x) >> 8) & 0xff000000) | \ + (((x) & 0xff000000) << 8) | \ + (((x) & 0xff0000) << 24) | \ + (((x) & 0xff00) << 40) | \ + (((x) & 0xff) << 56))) +#endif + +/** @def sys_le16_to_cpu + * @brief Convert 16-bit integer from little-endian to host endianness. + * + * @param val 16-bit integer in little-endian format. + * + * @return 16-bit integer in host endianness. + */ + +/** @def sys_cpu_to_le16 + * @brief Convert 16-bit integer from host endianness to little-endian. + * + * @param val 16-bit integer in host endianness. + * + * @return 16-bit integer in little-endian format. + */ + +/** @def sys_le24_to_cpu + * @brief Convert 24-bit integer from little-endian to host endianness. + * + * @param val 24-bit integer in little-endian format. + * + * @return 24-bit integer in host endianness. + */ + +/** @def sys_cpu_to_le24 + * @brief Convert 24-bit integer from host endianness to little-endian. + * + * @param val 24-bit integer in host endianness. + * + * @return 24-bit integer in little-endian format. + */ + +/** @def sys_le32_to_cpu + * @brief Convert 32-bit integer from little-endian to host endianness. + * + * @param val 32-bit integer in little-endian format. + * + * @return 32-bit integer in host endianness. + */ + +/** @def sys_cpu_to_le32 + * @brief Convert 32-bit integer from host endianness to little-endian. + * + * @param val 32-bit integer in host endianness. + * + * @return 32-bit integer in little-endian format. + */ + +/** @def sys_le48_to_cpu + * @brief Convert 48-bit integer from little-endian to host endianness. + * + * @param val 48-bit integer in little-endian format. + * + * @return 48-bit integer in host endianness. + */ + +/** @def sys_cpu_to_le48 + * @brief Convert 48-bit integer from host endianness to little-endian. + * + * @param val 48-bit integer in host endianness. + * + * @return 48-bit integer in little-endian format. + */ + +/** @def sys_be16_to_cpu + * @brief Convert 16-bit integer from big-endian to host endianness. + * + * @param val 16-bit integer in big-endian format. + * + * @return 16-bit integer in host endianness. + */ + +/** @def sys_cpu_to_be16 + * @brief Convert 16-bit integer from host endianness to big-endian. + * + * @param val 16-bit integer in host endianness. + * + * @return 16-bit integer in big-endian format. + */ + +/** @def sys_be24_to_cpu + * @brief Convert 24-bit integer from big-endian to host endianness. + * + * @param val 24-bit integer in big-endian format. + * + * @return 24-bit integer in host endianness. + */ + +/** @def sys_cpu_to_be24 + * @brief Convert 24-bit integer from host endianness to big-endian. + * + * @param val 24-bit integer in host endianness. + * + * @return 24-bit integer in big-endian format. + */ + +/** @def sys_be32_to_cpu + * @brief Convert 32-bit integer from big-endian to host endianness. + * + * @param val 32-bit integer in big-endian format. + * + * @return 32-bit integer in host endianness. + */ + +/** @def sys_cpu_to_be32 + * @brief Convert 32-bit integer from host endianness to big-endian. + * + * @param val 32-bit integer in host endianness. + * + * @return 32-bit integer in big-endian format. + */ + +/** @def sys_be48_to_cpu + * @brief Convert 48-bit integer from big-endian to host endianness. + * + * @param val 48-bit integer in big-endian format. + * + * @return 48-bit integer in host endianness. + */ + +/** @def sys_cpu_to_be48 + * @brief Convert 48-bit integer from host endianness to big-endian. + * + * @param val 48-bit integer in host endianness. + * + * @return 48-bit integer in big-endian format. + */ + +#ifndef sys_le16_to_cpu +#define sys_le16_to_cpu(val) (val) +#endif +#ifndef sys_cpu_to_le16 +#define sys_cpu_to_le16(val) (val) +#endif +#ifndef sys_le24_to_cpu +#define sys_le24_to_cpu(val) (val) +#endif +#ifndef sys_cpu_to_le24 +#define sys_cpu_to_le24(val) (val) +#endif +#ifndef sys_le32_to_cpu +#define sys_le32_to_cpu(val) (val) +#endif +#ifndef sys_cpu_to_le32 +#define sys_cpu_to_le32(val) (val) +#endif +#ifndef sys_le48_to_cpu +#define sys_le48_to_cpu(val) (val) +#endif +#ifndef sys_cpu_to_le48 +#define sys_cpu_to_le48(val) (val) +#endif +#ifndef sys_le64_to_cpu +#define sys_le64_to_cpu(val) (val) +#endif +#ifndef sys_cpu_to_le64 +#define sys_cpu_to_le64(val) (val) +#endif +#ifndef sys_be16_to_cpu +#define sys_be16_to_cpu(val) __bswap_16(val) +#endif +#ifndef sys_cpu_to_be16 +#define sys_cpu_to_be16(val) __bswap_16(val) +#endif +#ifndef sys_be24_to_cpu +#define sys_be24_to_cpu(val) __bswap_24(val) +#endif +#ifndef sys_cpu_to_be24 +#define sys_cpu_to_be24(val) __bswap_24(val) +#endif +#ifndef sys_be32_to_cpu +#define sys_be32_to_cpu(val) __bswap_32(val) +#endif +#ifndef sys_cpu_to_be32 +#define sys_cpu_to_be32(val) __bswap_32(val) +#endif +#ifndef sys_be48_to_cpu +#define sys_be48_to_cpu(val) __bswap_48(val) +#endif +#ifndef sys_cpu_to_be48 +#define sys_cpu_to_be48(val) __bswap_48(val) +#endif +#ifndef sys_be64_to_cpu +#define sys_be64_to_cpu(val) __bswap_64(val) +#endif +#ifndef sys_cpu_to_be64 +#define sys_cpu_to_be64(val) __bswap_64(val) +#endif + +/** + * @brief Put a 16-bit integer as big-endian to arbitrary location. + * + * Put a 16-bit integer, originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param val 16-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_be16(u16_t val, u8_t dst[2]) +{ + dst[0] = val >> 8; + dst[1] = val; +} + +/** + * @brief Put a 24-bit integer as big-endian to arbitrary location. + * + * Put a 24-bit integer, originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param val 24-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_be24(u32_t val, u8_t dst[3]) +{ + dst[0] = val >> 16; + sys_put_be16(val, &dst[1]); +} + +/** + * @brief Put a 32-bit integer as big-endian to arbitrary location. + * + * Put a 32-bit integer, originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param val 32-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_be32(u32_t val, u8_t dst[4]) +{ + sys_put_be16(val >> 16, dst); + sys_put_be16(val, &dst[2]); +} + +/** + * @brief Put a 48-bit integer as big-endian to arbitrary location. + * + * Put a 48-bit integer, originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param val 48-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_be48(u64_t val, u8_t dst[6]) +{ + sys_put_be16(val >> 32, dst); + sys_put_be32(val, &dst[2]); +} + +/** + * @brief Put a 64-bit integer as big-endian to arbitrary location. + * + * Put a 64-bit integer, originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param val 64-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_be64(u64_t val, u8_t dst[8]) +{ + sys_put_be32(val >> 32, dst); + sys_put_be32(val, &dst[4]); +} + +/** + * @brief Put a 16-bit integer as little-endian to arbitrary location. + * + * Put a 16-bit integer, originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param val 16-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le16(u16_t val, u8_t dst[2]) +{ + dst[0] = val; + dst[1] = val >> 8; +} + +/** + * @brief Put a 24-bit integer as little-endian to arbitrary location. + * + * Put a 24-bit integer, originally in host endianness, to a + * potentially unaligned memory location in littel-endian format. + * + * @param val 24-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le24(u32_t val, u8_t dst[3]) +{ + sys_put_le16(val, dst); + dst[2] = val >> 16; +} + +/** + * @brief Put a 32-bit integer as little-endian to arbitrary location. + * + * Put a 32-bit integer, originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param val 32-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le32(u32_t val, u8_t dst[4]) +{ + sys_put_le16(val, dst); + sys_put_le16(val >> 16, &dst[2]); +} + +/** + * @brief Put a 48-bit integer as little-endian to arbitrary location. + * + * Put a 48-bit integer, originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param val 48-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le48(u64_t val, u8_t dst[6]) +{ + sys_put_le32(val, dst); + sys_put_le16(val >> 32, &dst[4]); +} + +/** + * @brief Put a 64-bit integer as little-endian to arbitrary location. + * + * Put a 64-bit integer, originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param val 64-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le64(u64_t val, u8_t dst[8]) +{ + sys_put_le32(val, dst); + sys_put_le32(val >> 32, &dst[4]); +} + +/** + * @brief Get a 16-bit integer stored in big-endian format. + * + * Get a 16-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 16-bit integer to get. + * + * @return 16-bit integer in host endianness. + */ +static inline u16_t sys_get_be16(const u8_t src[2]) +{ + return ((u16_t)src[0] << 8) | src[1]; +} + +/** + * @brief Get a 24-bit integer stored in big-endian format. + * + * Get a 24-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 24-bit integer to get. + * + * @return 24-bit integer in host endianness. + */ +static inline u32_t sys_get_be24(const u8_t src[3]) +{ + return ((u32_t)src[0] << 16) | sys_get_be16(&src[1]); +} + +/** + * @brief Get a 32-bit integer stored in big-endian format. + * + * Get a 32-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 32-bit integer to get. + * + * @return 32-bit integer in host endianness. + */ +static inline u32_t sys_get_be32(const u8_t src[4]) +{ + return ((u32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]); +} + +/** + * @brief Get a 48-bit integer stored in big-endian format. + * + * Get a 48-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 48-bit integer to get. + * + * @return 48-bit integer in host endianness. + */ +static inline u64_t sys_get_be48(const u8_t src[6]) +{ + return ((u64_t)sys_get_be32(&src[0]) << 32) | sys_get_be16(&src[4]); +} + +/** + * @brief Get a 64-bit integer stored in big-endian format. + * + * Get a 64-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 64-bit integer to get. + * + * @return 64-bit integer in host endianness. + */ +static inline u64_t sys_get_be64(const u8_t src[8]) +{ + return ((u64_t)sys_get_be32(&src[0]) << 32) | sys_get_be32(&src[4]); +} + +/** + * @brief Get a 16-bit integer stored in little-endian format. + * + * Get a 16-bit integer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the little-endian 16-bit integer to get. + * + * @return 16-bit integer in host endianness. + */ +static inline u16_t sys_get_le16(const u8_t src[2]) +{ + return ((u16_t)src[1] << 8) | src[0]; +} + +/** + * @brief Get a 24-bit integer stored in big-endian format. + * + * Get a 24-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 24-bit integer to get. + * + * @return 24-bit integer in host endianness. + */ +static inline u32_t sys_get_le24(const u8_t src[3]) +{ + return ((u32_t)src[2] << 16) | sys_get_le16(&src[0]); +} + +/** + * @brief Get a 32-bit integer stored in little-endian format. + * + * Get a 32-bit integer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the little-endian 32-bit integer to get. + * + * @return 32-bit integer in host endianness. + */ +static inline u32_t sys_get_le32(const u8_t src[4]) +{ + return ((u32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]); +} + +/** + * @brief Get a 48-bit integer stored in little-endian format. + * + * Get a 48-bit integer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the little-endian 48-bit integer to get. + * + * @return 48-bit integer in host endianness. + */ +static inline u64_t sys_get_le48(const u8_t src[6]) +{ + return ((u64_t)sys_get_le32(&src[2]) << 32) | sys_get_le16(&src[0]); +} + +/** + * @brief Get a 64-bit integer stored in little-endian format. + * + * Get a 64-bit integer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the little-endian 64-bit integer to get. + * + * @return 64-bit integer in host endianness. + */ +static inline u64_t sys_get_le64(const u8_t src[8]) +{ + return ((u64_t)sys_get_le32(&src[4]) << 32) | sys_get_le32(&src[0]); +} + +/** + * @brief Swap one buffer content into another + * + * Copy the content of src buffer into dst buffer in reversed order, + * i.e.: src[n] will be put in dst[end-n] + * Where n is an index and 'end' the last index in both arrays. + * The 2 memory pointers must be pointing to different areas, and have + * a minimum size of given length. + * + * @param dst A valid pointer on a memory area where to copy the data in + * @param src A valid pointer on a memory area where to copy the data from + * @param length Size of both dst and src memory areas + */ +static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) +{ + u8_t *pdst = (u8_t *)dst; + const u8_t *psrc = (const u8_t *)src; + + __ASSERT(((psrc < pdst && (psrc + length) <= pdst) || + (psrc > pdst && (pdst + length) <= psrc)), + "Source and destination buffers must not overlap"); + + psrc += length - 1; + + for (; length > 0; length--) { + *pdst++ = *psrc--; + } +} + +/** + * @brief Swap buffer content + * + * In-place memory swap, where final content will be reversed. + * I.e.: buf[n] will be put in buf[end-n] + * Where n is an index and 'end' the last index of buf. + * + * @param buf A valid pointer on a memory area to swap + * @param length Size of buf memory area + */ +static inline void sys_mem_swap(void *buf, size_t length) +{ + size_t i; + + for (i = 0; i < (length / 2); i++) { + u8_t tmp = ((u8_t *)buf)[i]; + + ((u8_t *)buf)[i] = ((u8_t *)buf)[length - 1 - i]; + ((u8_t *)buf)[length - 1 - i] = tmp; + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* _BLE_MESH_BYTEORDER_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h index e4274b0a1..ad968dd0e 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_common.h @@ -22,13 +22,12 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" - #include "esp_heap_caps.h" +#include "mesh_byteorder.h" +#include "mesh_ffs.h" +#include "mesh_trace.h" +#include "mesh_mutex.h" #include "mesh_access.h" #ifdef __cplusplus @@ -76,21 +75,6 @@ void bt_mesh_free_buf(struct net_buf_simple *buf); */ u8_t bt_mesh_get_device_role(struct bt_mesh_model *model, bool srv_send); -typedef struct { - SemaphoreHandle_t mutex; -#if CONFIG_SPIRAM_USE_MALLOC - StaticQueue_t *buffer; -#endif -} bt_mesh_mutex_t; - -void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex); - -void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex); - -void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex); - -void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex); - #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_compiler.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_compiler.h new file mode 100644 index 000000000..cab93fe39 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_compiler.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010-2014,2017 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _BLE_MESH_COMPILER_H_ +#define _BLE_MESH_COMPILER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ___in_section(a, b, c) + +#define __in_section(a, b, c) ___in_section(a, b, c) + +#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif + +#ifndef __used +#define __used __attribute__((__used__)) +#endif + +#ifndef ARG_UNUSED +#define ARG_UNUSED(x) (void)(x) +#endif + +#ifndef popcount +#define popcount(x) __builtin_popcount(x) +#endif + +#ifndef ALWAYS_INLINE +#define ALWAYS_INLINE inline __attribute__((always_inline)) +#endif + + +/* + * This is meant to be used in conjunction with __in_section() and similar + * where scattered structure instances are concatened together by the linker + * and walked by the code at run time just like a contiguous array of such + * structures. + * + * Assemblers and linkers may insert alignment padding by default whose + * size is larger than the natural alignment for those structures when + * gathering various section segments together, messing up the array walk. + * To prevent this, we need to provide an explicit alignment not to rely + * on the default that might just work by luck. + * + * Alignment statements in linker scripts are not sufficient as + * the assembler may add padding by itself to each segment when switching + * between sections within the same file even if it merges many such segments + * into a single section in the end. + */ +#ifndef Z_DECL_ALIGN +#define Z_DECL_ALIGN(type) __aligned(__alignof(type)) type +#endif + +/* + * Convenience helper combining __in_section() and Z_DECL_ALIGN(). + * The section name is the struct type prepended with an underscore. + * The subsection is "static" and the subsubsection is the variable name. + */ +#ifndef Z_STRUCT_SECTION_ITERABLE +#define Z_STRUCT_SECTION_ITERABLE(struct_type, name) \ + Z_DECL_ALIGN(struct struct_type) name +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _BLE_MESH_COMPILER_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_ffs.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_ffs.h new file mode 100644 index 000000000..63c1b1b25 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_ffs.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015, Wind River Systems, Inc. + * Copyright (c) 2017, Oticon A/S + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _BLE_MESH_FFS_H_ +#define _BLE_MESH_FFS_H_ + +#include "mesh_types.h" +#include "mesh_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * + * @brief find most significant bit set in a 32-bit word + * + * This routine finds the first bit set starting from the most significant bit + * in the argument passed in and returns the index of that bit. Bits are + * numbered starting at 1 from the least significant bit. A return value of + * zero indicates that the value passed is zero. + * + * @return most significant bit set, 0 if @a op is 0 + */ + +static ALWAYS_INLINE unsigned int find_msb_set(u32_t op) +{ + if (op == 0) { + return 0; + } + + return 32 - __builtin_clz(op); +} + +/** + * + * @brief find least significant bit set in a 32-bit word + * + * This routine finds the first bit set starting from the least significant bit + * in the argument passed in and returns the index of that bit. Bits are + * numbered starting at 1 from the least significant bit. A return value of + * zero indicates that the value passed is zero. + * + * @return least significant bit set, 0 if @a op is 0 + */ + +static ALWAYS_INLINE unsigned int find_lsb_set(u32_t op) +{ + return __builtin_ffs(op); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _BLE_MESH_FFS_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h index fbe6d271e..9ffa28959 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_kernel.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, Wind River Systems, Inc. - * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * Additional Copyright (c) 2020 Espressif Systems (Shanghai) PTE LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,253 +8,34 @@ #ifndef _BLE_MESH_KERNEL_H_ #define _BLE_MESH_KERNEL_H_ +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" + #include "mesh_types.h" -#include "mesh_slist.h" -#include "mesh_atomic.h" #ifdef __cplusplus extern "C" { #endif -/* number of nsec per usec */ -#define NSEC_PER_USEC 1000 +#ifdef CONFIG_BT_BLUEDROID_ENABLED +#ifdef CONFIG_BT_BLUEDROID_PINNED_TO_CORE +#define BLE_MESH_ADV_TASK_CORE (CONFIG_BT_BLUEDROID_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_BLUEDROID_PINNED_TO_CORE : tskNO_AFFINITY) +#else +#define BLE_MESH_ADV_TASK_CORE (0) +#endif +#endif -/* number of microseconds per millisecond */ -#define USEC_PER_MSEC 1000 +#ifdef CONFIG_BT_NIMBLE_ENABLED +#ifdef CONFIG_BT_NIMBLE_PINNED_TO_CORE +#define BLE_MESH_ADV_TASK_CORE (CONFIG_BT_NIMBLE_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_NIMBLE_PINNED_TO_CORE : tskNO_AFFINITY) +#else +#define BLE_MESH_ADV_TASK_CORE (0) +#endif +#endif -/* number of milliseconds per second */ -#define MSEC_PER_SEC 1000 - -/* number of microseconds per second */ -#define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC)) - -/* number of nanoseconds per second */ -#define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC)) - -/* timeout is not in use */ -#define _INACTIVE (-1) - -struct k_work; - -/** - * @typedef k_work_handler_t - * @brief Work item handler function type. - * - * A work item's handler function is executed by a workqueue's thread - * when the work item is processed by the workqueue. - * - * @param work Address of the work item. - * - * @return N/A - */ -typedef void (*k_work_handler_t)(struct k_work *work); - -struct k_work { - void *_reserved; - k_work_handler_t handler; - int index; -}; - -#define _K_WORK_INITIALIZER(work_handler) \ -{ \ - ._reserved = NULL, \ - .handler = work_handler, \ -} - -/** - * @brief Generate null timeout delay. - * - * This macro generates a timeout delay that that instructs a kernel API - * not to wait if the requested operation cannot be performed immediately. - * - * @return Timeout delay value. - */ -#define K_NO_WAIT 0 - -/** - * @brief Generate timeout delay from milliseconds. - * - * This macro generates a timeout delay that that instructs a kernel API - * to wait up to @a ms milliseconds to perform the requested operation. - * - * @param ms Duration in milliseconds. - * - * @return Timeout delay value. - */ -#define K_MSEC(ms) (ms) - -/** - * @brief Generate timeout delay from seconds. - * - * This macro generates a timeout delay that that instructs a kernel API - * to wait up to @a s seconds to perform the requested operation. - * - * @param s Duration in seconds. - * - * @return Timeout delay value. - */ -#define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC) - -/** - * @brief Generate timeout delay from minutes. - * - * This macro generates a timeout delay that that instructs a kernel API - * to wait up to @a m minutes to perform the requested operation. - * - * @param m Duration in minutes. - * - * @return Timeout delay value. - */ -#define K_MINUTES(m) K_SECONDS((m) * 60) - -/** - * @brief Generate timeout delay from hours. - * - * This macro generates a timeout delay that that instructs a kernel API - * to wait up to @a h hours to perform the requested operation. - * - * @param h Duration in hours. - * - * @return Timeout delay value. - */ -#define K_HOURS(h) K_MINUTES((h) * 60) - -/** - * @brief Generate infinite timeout delay. - * - * This macro generates a timeout delay that that instructs a kernel API - * to wait as long as necessary to perform the requested operation. - * - * @return Timeout delay value. - */ -#define K_FOREVER (-1) - -/** - * @brief Get system uptime (32-bit version). - * - * This routine returns the lower 32-bits of the elapsed time since the system - * booted, in milliseconds. - * - * This routine can be more efficient than k_uptime_get(), as it reduces the - * need for interrupt locking and 64-bit math. However, the 32-bit result - * cannot hold a system uptime time larger than approximately 50 days, so the - * caller must handle possible rollovers. - * - * @return Current uptime. - */ -u32_t k_uptime_get_32(void); - -struct k_delayed_work { - struct k_work work; -}; - -/** - * @brief Submit a delayed work item to the system workqueue. - * - * This routine schedules work item @a work to be processed by the system - * workqueue after a delay of @a delay milliseconds. The routine initiates - * an asynchronous countdown for the work item and then returns to the caller. - * Only when the countdown completes is the work item actually submitted to - * the workqueue and becomes pending. - * - * Submitting a previously submitted delayed work item that is still - * counting down cancels the existing submission and restarts the countdown - * using the new delay. If the work item is currently pending on the - * workqueue's queue because the countdown has completed it is too late to - * resubmit the item, and resubmission fails without impacting the work item. - * If the work item has already been processed, or is currently being processed, - * its work is considered complete and the work item can be resubmitted. - * - * @warning - * Work items submitted to the system workqueue should avoid using handlers - * that block or yield since this may prevent the system workqueue from - * processing other work items in a timely manner. - * - * @note Can be called by ISRs. - * - * @param work Address of delayed work item. - * @param delay Delay before submitting the work item (in milliseconds). - * - * @retval 0 Work item countdown started. - * @retval -EINPROGRESS Work item is already pending. - * @retval -EINVAL Work item is being processed or has completed its work. - * @retval -EADDRINUSE Work item is pending on a different workqueue. - */ -int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay); - -int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period); - -/** - * @brief Get time remaining before a delayed work gets scheduled. - * - * This routine computes the (approximate) time remaining before a - * delayed work gets executed. If the delayed work is not waiting to be - * scheduled, it returns zero. - * - * @param work Delayed work item. - * - * @return Remaining time (in milliseconds). - */ -s32_t k_delayed_work_remaining_get(struct k_delayed_work *work); - -/** - * @brief Submit a work item to the system workqueue. - * - * This routine submits work item @a work to be processed by the system - * workqueue. If the work item is already pending in the workqueue's queue - * as a result of an earlier submission, this routine has no effect on the - * work item. If the work item has already been processed, or is currently - * being processed, its work is considered complete and the work item can be - * resubmitted. - * - * @warning - * Work items submitted to the system workqueue should avoid using handlers - * that block or yield since this may prevent the system workqueue from - * processing other work items in a timely manner. - * - * @note Can be called by ISRs. - * - * @param work Address of work item. - * - * @return N/A - */ -static inline void k_work_submit(struct k_work *work) -{ - if (work && work->handler) { - work->handler(work); - } -} - -/** - * @brief Initialize a work item. - * - * This routine initializes a workqueue work item, prior to its first use. - * - * @param work Address of work item. - * @param handler Function to invoke each time work item is processed. - * - * @return N/A - */ -static inline void k_work_init(struct k_work *work, k_work_handler_t handler) -{ - work->handler = handler; -} - -int k_delayed_work_cancel(struct k_delayed_work *work); - -int k_delayed_work_free(struct k_delayed_work *work); - -void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler); - -/** - * @brief Get system uptime. - * - * This routine returns the elapsed time since the system booted, - * in milliseconds. - * - * @return Current uptime. - */ -s64_t k_uptime_get(void); +#define BLE_MESH_ADV_TASK_STACK_SIZE 3072 /** * @brief Put the current thread to sleep. @@ -268,18 +49,6 @@ s64_t k_uptime_get(void); */ void k_sleep(s32_t duration); -void bt_mesh_list_lock(void); -void bt_mesh_list_unlock(void); - -void bt_mesh_buf_lock(void); -void bt_mesh_buf_unlock(void); - -void bt_mesh_atomic_lock(void); -void bt_mesh_atomic_unlock(void); - -void bt_mesh_k_init(void); -void bt_mesh_k_deinit(void); - #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_mutex.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_mutex.h new file mode 100644 index 000000000..488e010fa --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_mutex.h @@ -0,0 +1,58 @@ +// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _BLE_MESH_MUTEX_H_ +#define _BLE_MESH_MUTEX_H_ + +#include "mesh_kernel.h" +#include "mesh_slist.h" +#include "mesh_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + SemaphoreHandle_t mutex; +#if CONFIG_SPIRAM_USE_MALLOC + StaticQueue_t *buffer; +#endif +} bt_mesh_mutex_t; + +void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex); +void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex); +void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex); +void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex); + +void bt_mesh_alarm_lock(void); +void bt_mesh_alarm_unlock(void); + +void bt_mesh_list_lock(void); +void bt_mesh_list_unlock(void); + +void bt_mesh_buf_lock(void); +void bt_mesh_buf_unlock(void); + +void bt_mesh_atomic_lock(void); +void bt_mesh_atomic_unlock(void); + +void bt_mesh_mutex_init(void); +void bt_mesh_mutex_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _BLE_MESH_MUTEX_H_ */ + diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_timer.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_timer.h new file mode 100644 index 000000000..7d753a21a --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_timer.h @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2016, Wind River Systems, Inc. + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _BLE_MESH_TIMER_H_ +#define _BLE_MESH_TIMER_H_ + +#include "mesh_types.h" +#include "mesh_slist.h" +#include "mesh_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* number of nsec per usec */ +#define NSEC_PER_USEC 1000 + +/* number of microseconds per millisecond */ +#define USEC_PER_MSEC 1000 + +/* number of milliseconds per second */ +#define MSEC_PER_SEC 1000 + +/* number of microseconds per second */ +#define USEC_PER_SEC ((USEC_PER_MSEC) * (MSEC_PER_SEC)) + +/* number of nanoseconds per second */ +#define NSEC_PER_SEC ((NSEC_PER_USEC) * (USEC_PER_MSEC) * (MSEC_PER_SEC)) + +/* timeout is not in use */ +#define _INACTIVE (-1) + +struct k_work; + +/** + * @typedef k_work_handler_t + * @brief Work item handler function type. + * + * A work item's handler function is executed by a workqueue's thread + * when the work item is processed by the workqueue. + * + * @param work Address of the work item. + * + * @return N/A + */ +typedef void (*k_work_handler_t)(struct k_work *work); + +struct k_work { + void *_reserved; + k_work_handler_t handler; + int index; +}; + +#define _K_WORK_INITIALIZER(work_handler) \ +{ \ + ._reserved = NULL, \ + .handler = work_handler, \ +} + +/** + * @brief Generate null timeout delay. + * + * This macro generates a timeout delay that that instructs a kernel API + * not to wait if the requested operation cannot be performed immediately. + * + * @return Timeout delay value. + */ +#define K_NO_WAIT 0 + +/** + * @brief Generate timeout delay from milliseconds. + * + * This macro generates a timeout delay that that instructs a kernel API + * to wait up to @a ms milliseconds to perform the requested operation. + * + * @param ms Duration in milliseconds. + * + * @return Timeout delay value. + */ +#define K_MSEC(ms) (ms) + +/** + * @brief Generate timeout delay from seconds. + * + * This macro generates a timeout delay that that instructs a kernel API + * to wait up to @a s seconds to perform the requested operation. + * + * @param s Duration in seconds. + * + * @return Timeout delay value. + */ +#define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC) + +/** + * @brief Generate timeout delay from minutes. + * + * This macro generates a timeout delay that that instructs a kernel API + * to wait up to @a m minutes to perform the requested operation. + * + * @param m Duration in minutes. + * + * @return Timeout delay value. + */ +#define K_MINUTES(m) K_SECONDS((m) * 60) + +/** + * @brief Generate timeout delay from hours. + * + * This macro generates a timeout delay that that instructs a kernel API + * to wait up to @a h hours to perform the requested operation. + * + * @param h Duration in hours. + * + * @return Timeout delay value. + */ +#define K_HOURS(h) K_MINUTES((h) * 60) + +/** + * @brief Generate infinite timeout delay. + * + * This macro generates a timeout delay that that instructs a kernel API + * to wait as long as necessary to perform the requested operation. + * + * @return Timeout delay value. + */ +#define K_FOREVER (-1) + +/** + * @brief Get system uptime (32-bit version). + * + * This routine returns the lower 32-bits of the elapsed time since the system + * booted, in milliseconds. + * + * This routine can be more efficient than k_uptime_get(), as it reduces the + * need for interrupt locking and 64-bit math. However, the 32-bit result + * cannot hold a system uptime time larger than approximately 50 days, so the + * caller must handle possible rollovers. + * + * @return Current uptime. + */ +u32_t k_uptime_get_32(void); + +struct k_delayed_work { + struct k_work work; +}; + +/** + * @brief Submit a delayed work item to the system workqueue. + * + * This routine schedules work item @a work to be processed by the system + * workqueue after a delay of @a delay milliseconds. The routine initiates + * an asynchronous countdown for the work item and then returns to the caller. + * Only when the countdown completes is the work item actually submitted to + * the workqueue and becomes pending. + * + * Submitting a previously submitted delayed work item that is still + * counting down cancels the existing submission and restarts the countdown + * using the new delay. If the work item is currently pending on the + * workqueue's queue because the countdown has completed it is too late to + * resubmit the item, and resubmission fails without impacting the work item. + * If the work item has already been processed, or is currently being processed, + * its work is considered complete and the work item can be resubmitted. + * + * @warning + * Work items submitted to the system workqueue should avoid using handlers + * that block or yield since this may prevent the system workqueue from + * processing other work items in a timely manner. + * + * @note Can be called by ISRs. + * + * @param work Address of delayed work item. + * @param delay Delay before submitting the work item (in milliseconds). + * + * @retval 0 Work item countdown started. + * @retval -EINPROGRESS Work item is already pending. + * @retval -EINVAL Work item is being processed or has completed its work. + * @retval -EADDRINUSE Work item is pending on a different workqueue. + */ +int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay); + +int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period); + +/** + * @brief Get time remaining before a delayed work gets scheduled. + * + * This routine computes the (approximate) time remaining before a + * delayed work gets executed. If the delayed work is not waiting to be + * scheduled, it returns zero. + * + * @param work Delayed work item. + * + * @return Remaining time (in milliseconds). + */ +s32_t k_delayed_work_remaining_get(struct k_delayed_work *work); + +/** + * @brief Submit a work item to the system workqueue. + * + * This routine submits work item @a work to be processed by the system + * workqueue. If the work item is already pending in the workqueue's queue + * as a result of an earlier submission, this routine has no effect on the + * work item. If the work item has already been processed, or is currently + * being processed, its work is considered complete and the work item can be + * resubmitted. + * + * @warning + * Work items submitted to the system workqueue should avoid using handlers + * that block or yield since this may prevent the system workqueue from + * processing other work items in a timely manner. + * + * @note Can be called by ISRs. + * + * @param work Address of work item. + * + * @return N/A + */ +static inline void k_work_submit(struct k_work *work) +{ + if (work && work->handler) { + work->handler(work); + } +} + +/** + * @brief Initialize a work item. + * + * This routine initializes a workqueue work item, prior to its first use. + * + * @param work Address of work item. + * @param handler Function to invoke each time work item is processed. + * + * @return N/A + */ +static inline void k_work_init(struct k_work *work, k_work_handler_t handler) +{ + work->handler = handler; +} + +int k_delayed_work_cancel(struct k_delayed_work *work); + +int k_delayed_work_free(struct k_delayed_work *work); + +void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler); + +/** + * @brief Get system uptime. + * + * This routine returns the elapsed time since the system booted, + * in milliseconds. + * + * @return Current uptime. + */ +s64_t k_uptime_get(void); + +void bt_mesh_timer_init(void); +void bt_mesh_timer_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _BLE_MESH_TIMER_H_ */ + diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_trace.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_trace.h index d41da6a8c..924e60b8d 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_trace.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_trace.h @@ -10,6 +10,7 @@ #define _BLE_MESH_TRACE_H_ #include "esp_log.h" +#include "mesh_util.h" #ifdef __cplusplus extern "C" { @@ -56,10 +57,6 @@ extern "C" { #define BLE_MESH_LOG_LOCAL_LEVEL_MAPPING LOG_LOCAL_LEVEL #endif -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif /* MAX(a, b) */ - #define BLE_MESH_LOG_LEVEL_CHECK(LAYER, LEVEL) (MAX(LAYER##_LOG_LEVEL, BLE_MESH_LOG_LOCAL_LEVEL_MAPPING) >= LOG_LEVEL_##LEVEL) #define BLE_MESH_PRINT_E(tag, format, ...) {esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_types.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_types.h index 66df1ec75..5a189630c 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_types.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_types.h @@ -10,6 +10,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -39,6 +40,14 @@ typedef int bt_mesh_atomic_t; #define true 1 #endif +#ifndef PRIu64 +#define PRIu64 "llu" +#endif + +#ifndef PRIx64 +#define PRIx64 "llx" +#endif + #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h index 19c0a17ad..78b9ddf7b 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_util.h @@ -15,9 +15,7 @@ #define _BLE_MESH_UTIL_H_ #include -#include "soc/soc.h" #include "mesh_types.h" -#include "mesh_trace.h" #ifdef __cplusplus extern "C" { @@ -26,87 +24,99 @@ extern "C" { /* Helper to pass a int as a pointer or vice-versa. * Those are available for 32 bits architectures: */ +#ifndef POINTER_TO_UINT #define POINTER_TO_UINT(x) ((u32_t) (x)) +#endif +#ifndef UINT_TO_POINTER #define UINT_TO_POINTER(x) ((void *) (x)) +#endif +#ifndef POINTER_TO_INT #define POINTER_TO_INT(x) ((s32_t) (x)) +#endif +#ifndef INT_TO_POINTER #define INT_TO_POINTER(x) ((void *) (x)) +#endif /* Evaluates to 0 if cond is true-ish; compile error otherwise */ +#ifndef ZERO_OR_COMPILE_ERROR #define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1) +#endif /* Evaluates to 0 if array is an array; compile error if not array (e.g. * pointer) */ -#define IS_ARRAY(array) \ - ZERO_OR_COMPILE_ERROR( \ - !__builtin_types_compatible_p(__typeof__(array), \ - __typeof__(&(array)[0]))) +#ifndef IS_ARRAY +#define IS_ARRAY(array) \ + ZERO_OR_COMPILE_ERROR( \ + !__builtin_types_compatible_p(__typeof__(array), \ + __typeof__(&(array)[0]))) +#endif /* Evaluates to number of elements in an array; compile error if not * an array (e.g. pointer) */ -#define ARRAY_SIZE(array) \ - ((unsigned long) (IS_ARRAY(array) + \ - (sizeof(array) / sizeof((array)[0])))) +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) \ + ((unsigned long) (IS_ARRAY(array) + \ + (sizeof(array) / sizeof((array)[0])))) +#endif /* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if * "array" argument is not an array (e.g. "ptr" and "array" mixed up) */ +#ifndef PART_OF_ARRAY #define PART_OF_ARRAY(array, ptr) \ - ((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)])) + ((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)])) +#endif +#ifndef CONTAINER_OF #define CONTAINER_OF(ptr, type, field) \ - ((type *)(((char *)(ptr)) - offsetof(type, field))) + ((type *)(((char *)(ptr)) - offsetof(type, field))) +#endif /* round "x" up/down to next multiple of "align" (which must be a power of 2) */ -#define ROUND_UP(x, align) \ - (((unsigned long)(x) + ((unsigned long)align - 1)) & \ - ~((unsigned long)align - 1)) +#ifndef ROUND_UP +#define ROUND_UP(x, align) \ + (((unsigned long)(x) + ((unsigned long)align - 1)) & \ + ~((unsigned long)align - 1)) +#endif + +#ifndef ROUND_DOWN #define ROUND_DOWN(x, align) ((unsigned long)(x) & ~((unsigned long)align - 1)) +#endif +/* round up/down to the next word boundary */ +#ifndef WB_UP +#define WB_UP(x) ROUND_UP(x, sizeof(void *)) +#endif + +#ifndef WB_DN +#define WB_DN(x) ROUND_DOWN(x, sizeof(void *)) +#endif + +#ifndef ceiling_fraction #define ceiling_fraction(numerator, divider) \ - (((numerator) + ((divider) - 1)) / (divider)) - -/* Internal helpers only used by the sys_* APIs further below */ -#ifndef __bswap_16 -#define __bswap_16(x) ((u16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) + (((numerator) + ((divider) - 1)) / (divider)) #endif -#ifndef __bswap_32 -#define __bswap_32(x) ((u32_t) ((((x) >> 24) & 0xff) | \ - (((x) >> 8) & 0xff00) | \ - (((x) & 0xff00) << 8) | \ - (((x) & 0xff) << 24))) +#ifndef CHECKIF +#define CHECKIF(expr) if (expr) #endif -#ifndef __bswap_64 -#define __bswap_64(x) ((u64_t) ((((x) >> 56) & 0xff) | \ - (((x) >> 40) & 0xff00) | \ - (((x) >> 24) & 0xff0000) | \ - (((x) >> 8) & 0xff000000) | \ - (((x) & 0xff000000) << 8) | \ - (((x) & 0xff0000) << 24) | \ - (((x) & 0xff00) << 40) | \ - (((x) & 0xff) << 56))) -#endif - -#define sys_le16_to_cpu(val) (val) -#define sys_cpu_to_le16(val) (val) -#define sys_be16_to_cpu(val) __bswap_16(val) -#define sys_cpu_to_be16(val) __bswap_16(val) -#define sys_le32_to_cpu(val) (val) -#define sys_cpu_to_le32(val) (val) -#define sys_le64_to_cpu(val) (val) -#define sys_cpu_to_le64(val) (val) -#define sys_be32_to_cpu(val) __bswap_32(val) -#define sys_cpu_to_be32(val) __bswap_32(val) -#define sys_be64_to_cpu(val) __bswap_64(val) -#define sys_cpu_to_be64(val) __bswap_64(val) - +/** @brief Return larger value of two provided expressions. + * + * @note Arguments are evaluated twice. See Z_MAX for GCC only, single + * evaluation version. + */ #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif +/** @brief Return smaller value of two provided expressions. + * + * @note Arguments are evaluated twice. See Z_MIN for GCC only, single + * evaluation version. + */ #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif @@ -140,14 +150,14 @@ extern "C" { * value to be e.g. a literal "1" at expansion time in the next macro, * not "(1)", etc... Standard recursive expansion does not work. */ -#define IS_ENABLED(config_macro) _IS_ENABLED1(config_macro) +#define IS_ENABLED(config_macro) Z_IS_ENABLED1(config_macro) /* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro * is "1", or just "_XXXX" if it's undefined. - * ENABLED: _IS_ENABLED2(_XXXX1) - * DISABLED _IS_ENABLED2(_XXXX) + * ENABLED: Z_IS_ENABLED2(_XXXX1) + * DISABLED Z_IS_ENABLED2(_XXXX) */ -#define _IS_ENABLED1(config_macro) _IS_ENABLED2(_XXXX##config_macro) +#define Z_IS_ENABLED1(config_macro) Z_IS_ENABLED2(_XXXX##config_macro) /* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string * with a trailing comma), so it has the effect of making this a @@ -161,221 +171,20 @@ extern "C" { /* Then we append an extra argument to fool the gcc preprocessor into * accepting it as a varargs macro. * arg1 arg2 arg3 - * ENABLED: _IS_ENABLED3(_YYYY, 1, 0) - * DISABLED _IS_ENABLED3(_XXXX 1, 0) + * ENABLED: Z_IS_ENABLED3(_YYYY, 1, 0) + * DISABLED Z_IS_ENABLED3(_XXXX 1, 0) */ -#define _IS_ENABLED2(one_or_two_args) _IS_ENABLED3(one_or_two_args 1, 0) +#define Z_IS_ENABLED2(one_or_two_args) Z_IS_ENABLED3(one_or_two_args true, false) /* And our second argument is thus now cooked to be 1 in the case * where the value is defined to 1, and 0 if not: */ -#define _IS_ENABLED3(ignore_this, val, ...) val - -/* ESP Toolchain doesn't support section */ -#define ___in_section(a, b, c) -#define __in_section(a, b, c) ___in_section(a, b, c) - -#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__) - -#define popcount(x) __builtin_popcount(x) - -/** - * - * @brief find most significant bit set in a 32-bit word - * - * This routine finds the first bit set starting from the most significant bit - * in the argument passed in and returns the index of that bit. Bits are - * numbered starting at 1 from the least significant bit. A return value of - * zero indicates that the value passed is zero. - * - * @return most significant bit set, 0 if @a op is 0 - */ - -#if defined(__GNUC__) -static inline unsigned int find_msb_set(u32_t op) -{ - if (!op) { - return 0; - } - return 32 - __builtin_clz(op); -} -#endif - -/** - * - * @brief find least significant bit set in a 32-bit word - * - * This routine finds the first bit set starting from the least significant bit - * in the argument passed in and returns the index of that bit. Bits are - * numbered starting at 1 from the least significant bit. A return value of - * zero indicates that the value passed is zero. - * - * @return least significant bit set, 0 if @a op is 0 - */ - -#if defined(__GNUC__) -static inline unsigned int find_lsb_set(u32_t op) -{ - return __builtin_ffs(op); -} -#endif - -/** - * @brief Put a 16-bit integer as big-endian to arbitrary location. - * - * Put a 16-bit integer, originally in host endianness, to a - * potentially unaligned memory location in big-endian format. - * - * @param val 16-bit integer in host endianness. - * @param dst Destination memory address to store the result. - */ -static inline void sys_put_be16(u16_t val, u8_t dst[2]) -{ - dst[0] = val >> 8; - dst[1] = val; -} - -/** - * @brief Put a 32-bit integer as big-endian to arbitrary location. - * - * Put a 32-bit integer, originally in host endianness, to a - * potentially unaligned memory location in big-endian format. - * - * @param val 32-bit integer in host endianness. - * @param dst Destination memory address to store the result. - */ -static inline void sys_put_be32(u32_t val, u8_t dst[4]) -{ - sys_put_be16(val >> 16, dst); - sys_put_be16(val, &dst[2]); -} - -/** - * @brief Put a 16-bit integer as little-endian to arbitrary location. - * - * Put a 16-bit integer, originally in host endianness, to a - * potentially unaligned memory location in little-endian format. - * - * @param val 16-bit integer in host endianness. - * @param dst Destination memory address to store the result. - */ -static inline void sys_put_le16(u16_t val, u8_t dst[2]) -{ - dst[0] = val; - dst[1] = val >> 8; -} - -/** - * @brief Put a 32-bit integer as little-endian to arbitrary location. - * - * Put a 32-bit integer, originally in host endianness, to a - * potentially unaligned memory location in little-endian format. - * - * @param val 32-bit integer in host endianness. - * @param dst Destination memory address to store the result. - */ -static inline void sys_put_le32(u32_t val, u8_t dst[4]) -{ - sys_put_le16(val, dst); - sys_put_le16(val >> 16, &dst[2]); -} - -/** - * @brief Put a 64-bit integer as little-endian to arbitrary location. - * - * Put a 64-bit integer, originally in host endianness, to a - * potentially unaligned memory location in little-endian format. - * - * @param val 64-bit integer in host endianness. - * @param dst Destination memory address to store the result. - */ -static inline void sys_put_le64(u64_t val, u8_t dst[8]) -{ - sys_put_le32(val, dst); - sys_put_le32(val >> 32, &dst[4]); -} - -/** - * @brief Get a 16-bit integer stored in big-endian format. - * - * Get a 16-bit integer, stored in big-endian format in a potentially - * unaligned memory location, and convert it to the host endianness. - * - * @param src Location of the big-endian 16-bit integer to get. - * - * @return 16-bit integer in host endianness. - */ -static inline u16_t sys_get_be16(const u8_t src[2]) -{ - return ((u16_t)src[0] << 8) | src[1]; -} - -/** - * @brief Get a 32-bit integer stored in big-endian format. - * - * Get a 32-bit integer, stored in big-endian format in a potentially - * unaligned memory location, and convert it to the host endianness. - * - * @param src Location of the big-endian 32-bit integer to get. - * - * @return 32-bit integer in host endianness. - */ -static inline u32_t sys_get_be32(const u8_t src[4]) -{ - return ((u32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]); -} - -/** - * @brief Get a 16-bit integer stored in little-endian format. - * - * Get a 16-bit integer, stored in little-endian format in a potentially - * unaligned memory location, and convert it to the host endianness. - * - * @param src Location of the little-endian 16-bit integer to get. - * - * @return 16-bit integer in host endianness. - */ -static inline u16_t sys_get_le16(const u8_t src[2]) -{ - return ((u16_t)src[1] << 8) | src[0]; -} - -/** - * @brief Get a 32-bit integer stored in little-endian format. - * - * Get a 32-bit integer, stored in little-endian format in a potentially - * unaligned memory location, and convert it to the host endianness. - * - * @param src Location of the little-endian 32-bit integer to get. - * - * @return 32-bit integer in host endianness. - */ -static inline u32_t sys_get_le32(const u8_t src[4]) -{ - return ((u32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]); -} - -/** - * @brief Get a 64-bit integer stored in little-endian format. - * - * Get a 64-bit integer, stored in little-endian format in a potentially - * unaligned memory location, and convert it to the host endianness. - * - * @param src Location of the little-endian 64-bit integer to get. - * - * @return 64-bit integer in host endianness. - */ -static inline u64_t sys_get_le64(const u8_t src[8]) -{ - return ((u64_t)sys_get_le32(&src[4]) << 32) | sys_get_le32(&src[0]); -} +#define Z_IS_ENABLED3(ignore_this, val, ...) val const char *bt_hex(const void *buf, size_t len); void mem_rcopy(u8_t *dst, u8_t const *src, u16_t len); -void _set(void *to, uint8_t val, unsigned int len); - unsigned int _copy(uint8_t *to, unsigned int to_len, const uint8_t *from, unsigned int from_len); @@ -385,57 +194,6 @@ uint8_t _double_byte(uint8_t a); int _compare(const uint8_t *a, const uint8_t *b, size_t size); -/** - * @brief Swap one buffer content into another - * - * Copy the content of src buffer into dst buffer in reversed order, - * i.e.: src[n] will be put in dst[end-n] - * Where n is an index and 'end' the last index in both arrays. - * The 2 memory pointers must be pointing to different areas, and have - * a minimum size of given length. - * - * @param dst A valid pointer on a memory area where to copy the data in - * @param src A valid pointer on a memory area where to copy the data from - * @param length Size of both dst and src memory areas - */ -static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) -{ - u8_t *pdst = (u8_t *)dst; - const u8_t *psrc = (const u8_t *)src; - - __ASSERT(((psrc < pdst && (psrc + length) <= pdst) || - (psrc > pdst && (pdst + length) <= psrc)), - "Source and destination buffers must not overlap"); - - psrc += length - 1; - - for (; length > 0; length--) { - *pdst++ = *psrc--; - } -} - -/** - * @brief Swap buffer content - * - * In-place memory swap, where final content will be reversed. - * I.e.: buf[n] will be put in buf[end-n] - * Where n is an index and 'end' the last index of buf. - * - * @param buf A valid pointer on a memory area to swap - * @param length Size of buf memory area - */ -static inline void sys_mem_swap(void *buf, size_t length) -{ - size_t i; - - for (i = 0; i < (length / 2); i++) { - u8_t tmp = ((u8_t *)buf)[i]; - - ((u8_t *)buf)[i] = ((u8_t *)buf)[length - 1 - i]; - ((u8_t *)buf)[length - 1 - i] = tmp; - } -} - #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c b/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c index 5dce0b53b..595b385ed 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_atomic.c @@ -19,7 +19,7 @@ */ #include "mesh_atomic.h" -#include "mesh_kernel.h" +#include "mesh_mutex.h" #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c b/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c index 2fe8da1da..791948221 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c @@ -6,10 +6,7 @@ */ #include - -#include "mesh_buf.h" -#include "mesh_trace.h" -#include "mesh_kernel.h" +#include "mesh_common.h" int net_buf_id(struct net_buf *buf) { @@ -72,32 +69,70 @@ void net_buf_simple_add_le16(struct net_buf_simple *buf, u16_t val) { NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); - val = sys_cpu_to_le16(val); - memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); + sys_put_le16(val, net_buf_simple_add(buf, sizeof(val))); } void net_buf_simple_add_be16(struct net_buf_simple *buf, u16_t val) { NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); - val = sys_cpu_to_be16(val); - memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); + sys_put_be16(val, net_buf_simple_add(buf, sizeof(val))); +} + +void net_buf_simple_add_le24(struct net_buf_simple *buf, u32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + sys_put_le24(val, net_buf_simple_add(buf, 3)); +} + +void net_buf_simple_add_be24(struct net_buf_simple *buf, u32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + sys_put_be24(val, net_buf_simple_add(buf, 3)); } void net_buf_simple_add_le32(struct net_buf_simple *buf, u32_t val) { NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); - val = sys_cpu_to_le32(val); - memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); + sys_put_le32(val, net_buf_simple_add(buf, sizeof(val))); } void net_buf_simple_add_be32(struct net_buf_simple *buf, u32_t val) { NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); - val = sys_cpu_to_be32(val); - memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); + sys_put_be32(val, net_buf_simple_add(buf, sizeof(val))); +} + +void net_buf_simple_add_le48(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_le48(val, net_buf_simple_add(buf, 6)); +} + +void net_buf_simple_add_be48(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_be48(val, net_buf_simple_add(buf, 6)); +} + +void net_buf_simple_add_le64(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_le64(val, net_buf_simple_add(buf, sizeof(val))); +} + +void net_buf_simple_add_be64(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_be64(val, net_buf_simple_add(buf, sizeof(val))); } void *net_buf_simple_push(struct net_buf_simple *buf, size_t len) @@ -115,16 +150,14 @@ void net_buf_simple_push_le16(struct net_buf_simple *buf, u16_t val) { NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); - val = sys_cpu_to_le16(val); - memcpy(net_buf_simple_push(buf, sizeof(val)), &val, sizeof(val)); + sys_put_le16(val, net_buf_simple_push(buf, sizeof(val))); } void net_buf_simple_push_be16(struct net_buf_simple *buf, u16_t val) { NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); - val = sys_cpu_to_be16(val); - memcpy(net_buf_simple_push(buf, sizeof(val)), &val, sizeof(val)); + sys_put_be16(val, net_buf_simple_push(buf, sizeof(val))); } void net_buf_simple_push_u8(struct net_buf_simple *buf, u8_t val) @@ -134,6 +167,62 @@ void net_buf_simple_push_u8(struct net_buf_simple *buf, u8_t val) *data = val; } +void net_buf_simple_push_le24(struct net_buf_simple *buf, u32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + sys_put_le24(val, net_buf_simple_push(buf, 3)); +} + +void net_buf_simple_push_be24(struct net_buf_simple *buf, u32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + sys_put_be24(val, net_buf_simple_push(buf, 3)); +} + +void net_buf_simple_push_le32(struct net_buf_simple *buf, u32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + sys_put_le32(val, net_buf_simple_push(buf, sizeof(val))); +} + +void net_buf_simple_push_be32(struct net_buf_simple *buf, u32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + sys_put_be32(val, net_buf_simple_push(buf, sizeof(val))); +} + +void net_buf_simple_push_le48(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_le48(val, net_buf_simple_push(buf, 6)); +} + +void net_buf_simple_push_be48(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_be48(val, net_buf_simple_push(buf, 6)); +} + +void net_buf_simple_push_le64(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_le64(val, net_buf_simple_push(buf, sizeof(val))); +} + +void net_buf_simple_push_be64(struct net_buf_simple *buf, u64_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %" PRIu64, buf, val); + + sys_put_be64(val, net_buf_simple_push(buf, sizeof(val))); +} + void *net_buf_simple_pull(struct net_buf_simple *buf, size_t len) { NET_BUF_SIMPLE_DBG("buf %p len %u", buf, len); @@ -188,6 +277,30 @@ u16_t net_buf_simple_pull_be16(struct net_buf_simple *buf) return sys_be16_to_cpu(val); } +u32_t net_buf_simple_pull_le24(struct net_buf_simple *buf) +{ + struct uint24 { + u32_t u24:24; + } __packed val; + + val = UNALIGNED_GET((struct uint24 *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_le24_to_cpu(val.u24); +} + +u32_t net_buf_simple_pull_be24(struct net_buf_simple *buf) +{ + struct uint24 { + u32_t u24:24; + } __packed val; + + val = UNALIGNED_GET((struct uint24 *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_be24_to_cpu(val.u24); +} + u32_t net_buf_simple_pull_le32(struct net_buf_simple *buf) { u32_t val = 0U; @@ -208,6 +321,50 @@ u32_t net_buf_simple_pull_be32(struct net_buf_simple *buf) return sys_be32_to_cpu(val); } +u64_t net_buf_simple_pull_le48(struct net_buf_simple *buf) +{ + struct uint48 { + u64_t u48:48; + } __packed val; + + val = UNALIGNED_GET((struct uint48 *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_le48_to_cpu(val.u48); +} + +u64_t net_buf_simple_pull_be48(struct net_buf_simple *buf) +{ + struct uint48 { + u64_t u48:48; + } __packed val; + + val = UNALIGNED_GET((struct uint48 *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_be48_to_cpu(val.u48); +} + +u64_t net_buf_simple_pull_le64(struct net_buf_simple *buf) +{ + u64_t val; + + val = UNALIGNED_GET((u64_t *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_le64_to_cpu(val); +} + +u64_t net_buf_simple_pull_be64(struct net_buf_simple *buf) +{ + u64_t val; + + val = UNALIGNED_GET((u64_t *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_be64_to_cpu(val); +} + size_t net_buf_simple_headroom(struct net_buf_simple *buf) { return buf->data - buf->__buf; diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_common.c b/components/bt/esp_ble_mesh/mesh_common/mesh_common.c index 5aa4a1325..8ab86266e 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_common.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_common.c @@ -65,62 +65,3 @@ u8_t bt_mesh_get_device_role(struct bt_mesh_model *model, bool srv_send) return client->msg_role; } - -void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex) -{ - if (!mutex) { - BT_ERR("%s, Invalid mutex", __func__); - return; - } - -#if CONFIG_SPIRAM_USE_MALLOC - mutex->buffer = heap_caps_calloc(1, sizeof(StaticQueue_t), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); - __ASSERT(mutex->buffer, "%s, Failed to create queue buffer", __func__); - mutex->mutex = xSemaphoreCreateMutexStatic(mutex->buffer); - __ASSERT(mutex->mutex, "%s, Failed to create static mutex", __func__); -#else - mutex->mutex = xSemaphoreCreateMutex(); - __ASSERT(mutex->mutex, "%s, Failed to create mutex", __func__); -#endif -} - -void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex) -{ - if (!mutex) { - BT_ERR("%s, Invalid mutex", __func__); - return; - } - - if (mutex->mutex) { - vSemaphoreDelete(mutex->mutex); - mutex->mutex = NULL; -#if CONFIG_SPIRAM_USE_MALLOC - heap_caps_free(mutex->buffer); - mutex->buffer = NULL; -#endif - } -} - -void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex) -{ - if (!mutex) { - BT_ERR("%s, Invalid mutex", __func__); - return; - } - - if (mutex->mutex) { - xSemaphoreTake(mutex->mutex, portMAX_DELAY); - } -} - -void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex) -{ - if (!mutex) { - BT_ERR("%s, Invalid mutex", __func__); - return; - } - - if (mutex->mutex) { - xSemaphoreGive(mutex->mutex); - } -} diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c b/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c index 26c052ab4..b288f6500 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_kernel.c @@ -1,313 +1,14 @@ /* * Copyright (c) 2016 Intel Corporation * Copyright (c) 2016 Wind River Systems, Inc. - * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * Additional Copyright (c) 2020 Espressif Systems (Shanghai) PTE LTD * * SPDX-License-Identifier: Apache-2.0 */ -#include - -#include "osi/hash_map.h" -#include "osi/alarm.h" -#include "osi/hash_functions.h" - -#include "mesh_common.h" -#include "provisioner_prov.h" - -static bt_mesh_mutex_t bm_alarm_lock; -static bt_mesh_mutex_t bm_list_lock; -static bt_mesh_mutex_t bm_buf_lock; -static bt_mesh_mutex_t bm_atomic_lock; -static hash_map_t *bm_alarm_hash_map; -static const size_t BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME + \ - CONFIG_BLE_MESH_PBG_SAME_TIME; - -typedef struct alarm_t { - /* timer id point to here */ - esp_timer_handle_t alarm_hdl; - osi_alarm_callback_t cb; - void *cb_data; - int64_t deadline_us; -} osi_alarm_t; - -static void bt_mesh_alarm_mutex_new(void) -{ - if (!bm_alarm_lock.mutex) { - bt_mesh_mutex_create(&bm_alarm_lock); - } -} - -static void bt_mesh_alarm_mutex_free(void) -{ - bt_mesh_mutex_free(&bm_alarm_lock); -} - -static void bt_mesh_alarm_lock(void) -{ - bt_mesh_mutex_lock(&bm_alarm_lock); -} - -static void bt_mesh_alarm_unlock(void) -{ - bt_mesh_mutex_unlock(&bm_alarm_lock); -} - -static void bt_mesh_list_mutex_new(void) -{ - if (!bm_list_lock.mutex) { - bt_mesh_mutex_create(&bm_list_lock); - } -} - -static void bt_mesh_list_mutex_free(void) -{ - bt_mesh_mutex_free(&bm_list_lock); -} - -void bt_mesh_list_lock(void) -{ - bt_mesh_mutex_lock(&bm_list_lock); -} - -void bt_mesh_list_unlock(void) -{ - bt_mesh_mutex_unlock(&bm_list_lock); -} - -static void bt_mesh_buf_mutex_new(void) -{ - if (!bm_buf_lock.mutex) { - bt_mesh_mutex_create(&bm_buf_lock); - } -} - -static void bt_mesh_buf_mutex_free(void) -{ - bt_mesh_mutex_free(&bm_buf_lock); -} - -void bt_mesh_buf_lock(void) -{ - bt_mesh_mutex_lock(&bm_buf_lock); -} - -void bt_mesh_buf_unlock(void) -{ - bt_mesh_mutex_unlock(&bm_buf_lock); -} - -static void bt_mesh_atomic_mutex_new(void) -{ - if (!bm_atomic_lock.mutex) { - bt_mesh_mutex_create(&bm_atomic_lock); - } -} - -static void bt_mesh_atomic_mutex_free(void) -{ - bt_mesh_mutex_free(&bm_atomic_lock); -} - -void bt_mesh_atomic_lock(void) -{ - bt_mesh_mutex_lock(&bm_atomic_lock); -} - -void bt_mesh_atomic_unlock(void) -{ - bt_mesh_mutex_unlock(&bm_atomic_lock); -} - -s64_t k_uptime_get(void) -{ - /** k_uptime_get_32 is in in milliseconds, - * but esp_timer_get_time is in microseconds - */ - return (esp_timer_get_time() / 1000); -} - -u32_t k_uptime_get_32(void) -{ - /** k_uptime_get_32 is in in milliseconds, - * but esp_timer_get_time is in microseconds - */ - return (u32_t)(esp_timer_get_time() / 1000); -} +#include "mesh_kernel.h" void k_sleep(s32_t duration) { vTaskDelay(duration / portTICK_PERIOD_MS); - return; -} - -void bt_mesh_k_init(void) -{ - bt_mesh_alarm_mutex_new(); - bt_mesh_list_mutex_new(); - bt_mesh_buf_mutex_new(); - bt_mesh_atomic_mutex_new(); - bm_alarm_hash_map = hash_map_new(BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE, - hash_function_pointer, NULL, - (data_free_fn)osi_alarm_free, NULL); - __ASSERT(bm_alarm_hash_map, "%s, Failed to create hash map", __func__); -} - -void bt_mesh_k_deinit(void) -{ - bt_mesh_alarm_mutex_free(); - bt_mesh_list_mutex_free(); - bt_mesh_buf_mutex_free(); - bt_mesh_atomic_mutex_free(); - if (bm_alarm_hash_map) { - hash_map_free(bm_alarm_hash_map); - bm_alarm_hash_map = NULL; - } -} - -void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) -{ - osi_alarm_t *alarm = NULL; - - if (!work || !bm_alarm_hash_map) { - BT_ERR("%s, Invalid parameter", __func__); - return; - } - - k_work_init(&work->work, handler); - - bt_mesh_alarm_lock(); - if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) { - alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0); - if (alarm == NULL) { - BT_ERR("%s, Unable to create alarm", __func__); - bt_mesh_alarm_unlock(); - return; - } - if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) { - BT_ERR("%s Unable to add the timer to hash map.", __func__); - bt_mesh_alarm_unlock(); - return; - } - } - - alarm = hash_map_get(bm_alarm_hash_map, work); - if (alarm == NULL) { - BT_WARN("%s, Unable to find expected alarm in hash map", __func__); - bt_mesh_alarm_unlock(); - return; - } - - // Just init the work timer only, don't start it. - osi_alarm_cancel(alarm); - bt_mesh_alarm_unlock(); - return; -} - -int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay) -{ - if (!work || !bm_alarm_hash_map) { - BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; - } - - bt_mesh_alarm_lock(); - osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); - if (alarm == NULL) { - BT_WARN("%s, Unable to find expected alarm in hash map", __func__); - bt_mesh_alarm_unlock(); - return -EINVAL; - } - - // Cancel the alarm first, before start the alarm. - osi_alarm_cancel(alarm); - osi_alarm_set(alarm, delay); - bt_mesh_alarm_unlock(); - return 0; -} - -int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period) -{ - if (!work || !bm_alarm_hash_map) { - BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; - } - - bt_mesh_alarm_lock(); - osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); - if (alarm == NULL) { - BT_WARN("%s, Unable to find expected alarm in hash map", __func__); - bt_mesh_alarm_unlock(); - return -EINVAL; - } - - /* Cancel the alarm first before starting it. */ - osi_alarm_cancel(alarm); - osi_alarm_set_periodic(alarm, period); - bt_mesh_alarm_unlock(); - return 0; -} - -int k_delayed_work_cancel(struct k_delayed_work *work) -{ - if (!work || !bm_alarm_hash_map) { - BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; - } - - bt_mesh_alarm_lock(); - osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); - if (alarm == NULL) { - BT_WARN("%s, Unable to find expected alarm in hash map", __func__); - bt_mesh_alarm_unlock(); - return -EINVAL; - } - - osi_alarm_cancel(alarm); - alarm->deadline_us = 0; - bt_mesh_alarm_unlock(); - return 0; -} - -int k_delayed_work_free(struct k_delayed_work *work) -{ - if (!work || !bm_alarm_hash_map) { - BT_ERR("%s, Invalid parameter", __func__); - return -EINVAL; - } - - bt_mesh_alarm_lock(); - osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, work); - if (alarm == NULL) { - BT_WARN("%s Unable to find expected alarm in hash map", __func__); - bt_mesh_alarm_unlock(); - return -EINVAL; - } - - osi_alarm_cancel(alarm); - hash_map_erase(bm_alarm_hash_map, work); - bt_mesh_alarm_unlock(); - return 0; -} - -s32_t k_delayed_work_remaining_get(struct k_delayed_work *work) -{ - s32_t time = 0; - - if (!work || !bm_alarm_hash_map) { - BT_ERR("%s, Invalid parameter", __func__); - return 0; - } - - bt_mesh_alarm_lock(); - osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); - if (alarm == NULL) { - BT_WARN("%s Unable to find expected alarm in hash map", __func__); - bt_mesh_alarm_unlock(); - return 0; - } - - time = osi_alarm_get_remaining_ms(alarm); - bt_mesh_alarm_unlock(); - return time; } diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_mutex.c b/components/bt/esp_ble_mesh/mesh_common/mesh_mutex.c new file mode 100644 index 000000000..1bd6a2358 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_mutex.c @@ -0,0 +1,183 @@ +// Copyright 2017-2020 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "mesh_common.h" + +static bt_mesh_mutex_t alarm_lock; +static bt_mesh_mutex_t list_lock; +static bt_mesh_mutex_t buf_lock; +static bt_mesh_mutex_t atomic_lock; + +void bt_mesh_mutex_create(bt_mesh_mutex_t *mutex) +{ + if (!mutex) { + BT_ERR("%s, Invalid mutex", __func__); + return; + } + +#if CONFIG_SPIRAM_USE_MALLOC + mutex->buffer = heap_caps_calloc(1, sizeof(StaticQueue_t), MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM); + __ASSERT(mutex->buffer, "%s, Failed to create queue buffer", __func__); + mutex->mutex = xSemaphoreCreateMutexStatic(mutex->buffer); + __ASSERT(mutex->mutex, "%s, Failed to create static mutex", __func__); +#else + mutex->mutex = xSemaphoreCreateMutex(); + __ASSERT(mutex->mutex, "%s, Failed to create mutex", __func__); +#endif +} + +void bt_mesh_mutex_free(bt_mesh_mutex_t *mutex) +{ + if (!mutex) { + BT_ERR("%s, Invalid mutex", __func__); + return; + } + + if (mutex->mutex) { + vSemaphoreDelete(mutex->mutex); + mutex->mutex = NULL; +#if CONFIG_SPIRAM_USE_MALLOC + heap_caps_free(mutex->buffer); + mutex->buffer = NULL; +#endif + } +} + +void bt_mesh_mutex_lock(bt_mesh_mutex_t *mutex) +{ + if (!mutex) { + BT_ERR("%s, Invalid mutex", __func__); + return; + } + + if (mutex->mutex) { + xSemaphoreTake(mutex->mutex, portMAX_DELAY); + } +} + +void bt_mesh_mutex_unlock(bt_mesh_mutex_t *mutex) +{ + if (!mutex) { + BT_ERR("%s, Invalid mutex", __func__); + return; + } + + if (mutex->mutex) { + xSemaphoreGive(mutex->mutex); + } +} + +static void bt_mesh_alarm_mutex_new(void) +{ + if (!alarm_lock.mutex) { + bt_mesh_mutex_create(&alarm_lock); + } +} + +static void bt_mesh_alarm_mutex_free(void) +{ + bt_mesh_mutex_free(&alarm_lock); +} + +void bt_mesh_alarm_lock(void) +{ + bt_mesh_mutex_lock(&alarm_lock); +} + +void bt_mesh_alarm_unlock(void) +{ + bt_mesh_mutex_unlock(&alarm_lock); +} + +static void bt_mesh_list_mutex_new(void) +{ + if (!list_lock.mutex) { + bt_mesh_mutex_create(&list_lock); + } +} + +static void bt_mesh_list_mutex_free(void) +{ + bt_mesh_mutex_free(&list_lock); +} + +void bt_mesh_list_lock(void) +{ + bt_mesh_mutex_lock(&list_lock); +} + +void bt_mesh_list_unlock(void) +{ + bt_mesh_mutex_unlock(&list_lock); +} + +static void bt_mesh_buf_mutex_new(void) +{ + if (!buf_lock.mutex) { + bt_mesh_mutex_create(&buf_lock); + } +} + +static void bt_mesh_buf_mutex_free(void) +{ + bt_mesh_mutex_free(&buf_lock); +} + +void bt_mesh_buf_lock(void) +{ + bt_mesh_mutex_lock(&buf_lock); +} + +void bt_mesh_buf_unlock(void) +{ + bt_mesh_mutex_unlock(&buf_lock); +} + +static void bt_mesh_atomic_mutex_new(void) +{ + if (!atomic_lock.mutex) { + bt_mesh_mutex_create(&atomic_lock); + } +} + +static void bt_mesh_atomic_mutex_free(void) +{ + bt_mesh_mutex_free(&atomic_lock); +} + +void bt_mesh_atomic_lock(void) +{ + bt_mesh_mutex_lock(&atomic_lock); +} + +void bt_mesh_atomic_unlock(void) +{ + bt_mesh_mutex_unlock(&atomic_lock); +} + +void bt_mesh_mutex_init(void) +{ + bt_mesh_alarm_mutex_new(); + bt_mesh_list_mutex_new(); + bt_mesh_buf_mutex_new(); + bt_mesh_atomic_mutex_new(); +} + +void bt_mesh_mutex_deinit(void) +{ + bt_mesh_alarm_mutex_free(); + bt_mesh_list_mutex_free(); + bt_mesh_buf_mutex_free(); + bt_mesh_atomic_mutex_free(); +} diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_timer.c b/components/bt/esp_ble_mesh/mesh_common/mesh_timer.c new file mode 100644 index 000000000..76b7ac2a9 --- /dev/null +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_timer.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2016 Wind River Systems, Inc. + * Additional Copyright (c) 2018 Espressif Systems (Shanghai) PTE LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "osi/hash_map.h" +#include "osi/alarm.h" +#include "osi/hash_functions.h" + +#include "mesh_common.h" +#include "provisioner_prov.h" + +static hash_map_t *bm_alarm_hash_map; +static const size_t BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE = 20 + CONFIG_BLE_MESH_PBA_SAME_TIME + \ + CONFIG_BLE_MESH_PBG_SAME_TIME; + +typedef struct alarm_t { + /* timer id point to here */ + esp_timer_handle_t alarm_hdl; + osi_alarm_callback_t cb; + void *cb_data; + int64_t deadline_us; +} osi_alarm_t; + +s64_t k_uptime_get(void) +{ + /** k_uptime_get_32 is in in milliseconds, + * but esp_timer_get_time is in microseconds + */ + return (esp_timer_get_time() / 1000); +} + +u32_t k_uptime_get_32(void) +{ + /** k_uptime_get_32 is in in milliseconds, + * but esp_timer_get_time is in microseconds + */ + return (u32_t)(esp_timer_get_time() / 1000); +} + +void bt_mesh_timer_init(void) +{ + bm_alarm_hash_map = hash_map_new(BLE_MESH_GENERAL_ALARM_HASH_MAP_SIZE, + hash_function_pointer, NULL, + (data_free_fn)osi_alarm_free, NULL); + __ASSERT(bm_alarm_hash_map, "%s, Failed to create hash map", __func__); +} + +void bt_mesh_timer_deinit(void) +{ + if (bm_alarm_hash_map) { + hash_map_free(bm_alarm_hash_map); + bm_alarm_hash_map = NULL; + } +} + +void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) +{ + osi_alarm_t *alarm = NULL; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return; + } + + k_work_init(&work->work, handler); + + bt_mesh_alarm_lock(); + if (!hash_map_has_key(bm_alarm_hash_map, (void *)work)) { + alarm = osi_alarm_new("bt_mesh", (osi_alarm_callback_t)handler, (void *)&work->work, 0); + if (alarm == NULL) { + BT_ERR("%s, Unable to create alarm", __func__); + bt_mesh_alarm_unlock(); + return; + } + if (!hash_map_set(bm_alarm_hash_map, work, (void *)alarm)) { + BT_ERR("%s Unable to add the timer to hash map.", __func__); + bt_mesh_alarm_unlock(); + return; + } + } + + alarm = hash_map_get(bm_alarm_hash_map, work); + if (alarm == NULL) { + BT_WARN("%s, Unable to find expected alarm in hash map", __func__); + bt_mesh_alarm_unlock(); + return; + } + + // Just init the work timer only, don't start it. + osi_alarm_cancel(alarm); + bt_mesh_alarm_unlock(); + return; +} + +int k_delayed_work_submit(struct k_delayed_work *work, s32_t delay) +{ + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_alarm_lock(); + osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("%s, Unable to find expected alarm in hash map", __func__); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + // Cancel the alarm first, before start the alarm. + osi_alarm_cancel(alarm); + osi_alarm_set(alarm, delay); + bt_mesh_alarm_unlock(); + return 0; +} + +int k_delayed_work_submit_periodic(struct k_delayed_work *work, s32_t period) +{ + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_alarm_lock(); + osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("%s, Unable to find expected alarm in hash map", __func__); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + /* Cancel the alarm first before starting it. */ + osi_alarm_cancel(alarm); + osi_alarm_set_periodic(alarm, period); + bt_mesh_alarm_unlock(); + return 0; +} + +int k_delayed_work_cancel(struct k_delayed_work *work) +{ + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_alarm_lock(); + osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("%s, Unable to find expected alarm in hash map", __func__); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + osi_alarm_cancel(alarm); + alarm->deadline_us = 0; + bt_mesh_alarm_unlock(); + return 0; +} + +int k_delayed_work_free(struct k_delayed_work *work) +{ + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return -EINVAL; + } + + bt_mesh_alarm_lock(); + osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, work); + if (alarm == NULL) { + BT_WARN("%s Unable to find expected alarm in hash map", __func__); + bt_mesh_alarm_unlock(); + return -EINVAL; + } + + osi_alarm_cancel(alarm); + hash_map_erase(bm_alarm_hash_map, work); + bt_mesh_alarm_unlock(); + return 0; +} + +s32_t k_delayed_work_remaining_get(struct k_delayed_work *work) +{ + s32_t time = 0; + + if (!work || !bm_alarm_hash_map) { + BT_ERR("%s, Invalid parameter", __func__); + return 0; + } + + bt_mesh_alarm_lock(); + osi_alarm_t *alarm = hash_map_get(bm_alarm_hash_map, (void *)work); + if (alarm == NULL) { + BT_WARN("%s Unable to find expected alarm in hash map", __func__); + bt_mesh_alarm_unlock(); + return 0; + } + + time = osi_alarm_get_remaining_ms(alarm); + bt_mesh_alarm_unlock(); + return time; +} diff --git a/components/bt/esp_ble_mesh/mesh_core/access.c b/components/bt/esp_ble_mesh/mesh_core/access.c index dab417534..eb18d88a9 100644 --- a/components/bt/esp_ble_mesh/mesh_core/access.c +++ b/components/bt/esp_ble_mesh/mesh_core/access.c @@ -411,7 +411,7 @@ static int publish_retransmit(struct bt_mesh_model *mod) ctx.net_idx = key->net_idx; ctx.app_idx = key->app_idx; - sdu = bt_mesh_alloc_buf(pub->msg->len + 4); + sdu = bt_mesh_alloc_buf(pub->msg->len + BLE_MESH_MIC_SHORT); if (!sdu) { BT_ERR("%s, Failed to allocate memory", __func__); return -ENOMEM; @@ -427,6 +427,14 @@ static int publish_retransmit(struct bt_mesh_model *mod) return err; } +static void publish_retransmit_end(int err, struct bt_mesh_model_pub *pub) +{ + /* Cancel all retransmits for this publish attempt */ + pub->count = 0U; + /* Make sure the publish timer gets reset */ + publish_sent(err, pub->mod); +} + static void mod_publish(struct k_work *work) { struct bt_mesh_model_pub *pub = CONTAINER_OF(work, @@ -468,7 +476,10 @@ static void mod_publish(struct k_work *work) */ err = pub->update(pub->mod); if (err) { - BT_ERR("%s, Failed to update publication message", __func__); + /* Cancel this publish attempt. */ + BT_ERR("Update failed, skipping publish (err %d)", err); + pub->period_start = k_uptime_get_32(); + publish_retransmit_end(err, pub); return; } @@ -616,7 +627,7 @@ void bt_mesh_comp_provision(u16_t addr) dev_primary_addr = addr; - BT_INFO("addr 0x%04x elem_count %u", addr, dev_comp->elem_count); + BT_INFO("Primary address 0x%04x, element count %u", addr, dev_comp->elem_count); for (i = 0; i < dev_comp->elem_count; i++) { struct bt_mesh_elem *elem = &dev_comp->elem[i]; @@ -786,6 +797,10 @@ static int get_opcode(struct net_buf_simple *buf, u32_t *opcode) } *opcode = net_buf_simple_pull_u8(buf) << 16; + /* Using LE for the CID since the model layer is defined as + * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3 + * will declare the opcode in this way. + */ *opcode |= net_buf_simple_pull_le16(buf); return 0; } @@ -827,7 +842,7 @@ void bt_mesh_model_recv(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) return; } - BT_INFO("OpCode 0x%08x", opcode); + BT_DBG("OpCode 0x%08x", opcode); for (i = 0; i < dev_comp->elem_count; i++) { struct bt_mesh_elem *elem = &dev_comp->elem[i]; @@ -910,6 +925,10 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode) break; case 3: net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff)); + /* Using LE for the CID since the model layer is defined as + * little-endian in the mesh spec and using BT_MESH_MODEL_OP_3 + * will declare the opcode in this way. + */ net_buf_simple_add_le16(msg, opcode & 0xffff); break; default: @@ -948,8 +967,8 @@ static int model_send(struct bt_mesh_model *model, return -EINVAL; } - BT_INFO("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->ctx->net_idx, - tx->ctx->app_idx, tx->ctx->addr); + BT_INFO("app_idx 0x%04x src 0x%04x dst 0x%04x", + tx->ctx->app_idx, tx->src, tx->ctx->addr); BT_INFO("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); if (!ready_to_send(role, tx->ctx->addr)) { @@ -957,12 +976,12 @@ static int model_send(struct bt_mesh_model *model, return -EINVAL; } - if (net_buf_simple_tailroom(msg) < 4) { + if (net_buf_simple_tailroom(msg) < BLE_MESH_MIC_SHORT) { BT_ERR("%s, Not enough tailroom for TransMIC", __func__); return -EINVAL; } - if (msg->len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN) - 4) { + if (msg->len > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN) - BLE_MESH_MIC_SHORT) { BT_ERR("%s, Too big message", __func__); return -EMSGSIZE; } @@ -1040,7 +1059,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) return -EADDRNOTAVAIL; } - if (pub->msg->len + 4 > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN)) { + if (pub->msg->len + BLE_MESH_MIC_SHORT > MIN(BLE_MESH_TX_SDU_MAX, BLE_MESH_SDU_MAX_LEN)) { BT_ERR("%s, Message does not fit maximum SDU size", __func__); return -EMSGSIZE; } @@ -1051,6 +1070,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) } ctx.addr = pub->addr; + ctx.send_rel = pub->send_rel; ctx.send_ttl = pub->ttl; ctx.net_idx = key->net_idx; ctx.app_idx = key->app_idx; @@ -1069,7 +1089,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) BT_INFO("Publish Retransmit Count %u Interval %ums", pub->count, BLE_MESH_PUB_TRANSMIT_INT(pub->retransmit)); - sdu = bt_mesh_alloc_buf(pub->msg->len + 4); + sdu = bt_mesh_alloc_buf(pub->msg->len + BLE_MESH_MIC_SHORT); if (!sdu) { BT_ERR("%s, Failed to allocate memory", __func__); return -ENOMEM; @@ -1079,10 +1099,7 @@ int bt_mesh_model_publish(struct bt_mesh_model *model) err = model_send(model, &tx, true, sdu, &pub_sent_cb, model); if (err) { - /* Don't try retransmissions for this publish attempt */ - pub->count = 0U; - /* Make sure the publish timer gets reset */ - publish_sent(err, model); + publish_retransmit_end(err, pub); } bt_mesh_free_buf(sdu); diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.c b/components/bt/esp_ble_mesh/mesh_core/adv.c index 1986f1fba..22365c2be 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.c +++ b/components/bt/esp_ble_mesh/mesh_core/adv.c @@ -11,14 +11,9 @@ #include #include -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" -#include "freertos/task.h" - -#include "osi/thread.h" - #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_ADV) +#include "mesh_kernel.h" #include "mesh.h" #include "mesh_hci.h" #include "mesh_common.h" diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.h b/components/bt/esp_ble_mesh/mesh_core/adv.h index dc8649d13..e0ade0da3 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.h +++ b/components/bt/esp_ble_mesh/mesh_core/adv.h @@ -48,14 +48,9 @@ struct bt_mesh_adv { const struct bt_mesh_send_cb *cb; void *cb_data; - u8_t type: 3, - busy: 1; + u8_t type:3, + busy:1; u8_t xmit; - - /* For transport layer segment sending */ - struct { - u8_t attempts; - } seg; }; typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id); diff --git a/components/bt/esp_ble_mesh/mesh_core/beacon.c b/components/bt/esp_ble_mesh/mesh_core/beacon.c index 0dd02a1ad..2f53aa49f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/beacon.c +++ b/components/bt/esp_ble_mesh/mesh_core/beacon.c @@ -102,10 +102,10 @@ void bt_mesh_beacon_create(struct bt_mesh_subnet *sub, net_buf_simple_add_mem(buf, sub->auth, 8); - BT_INFO("net_idx 0x%04x flags 0x%02x NetID %s", sub->net_idx, - flags, bt_hex(keys->net_id, 8)); - BT_INFO("IV Index 0x%08x Auth %s", bt_mesh.iv_index, - bt_hex(sub->auth, 8)); + BT_INFO("net_idx 0x%03x iv_index 0x%08x flags 0x%02x", + sub->net_idx, bt_mesh.iv_index, flags); + BT_DBG("NetID %s Auth %s", bt_hex(keys->net_id, 8), + bt_hex(sub->auth, 8)); } /* If the interval has passed or is within 5 seconds from now send a beacon */ @@ -357,8 +357,8 @@ static void secure_beacon_recv(struct net_buf_simple *buf) goto update_stats; } - BT_INFO("net_idx 0x%04x iv_index 0x%08x, current iv_index 0x%08x", - sub->net_idx, iv_index, bt_mesh.iv_index); + BT_INFO("net_idx 0x%03x iv_index 0x%08x current iv_index 0x%08x", + sub->net_idx, iv_index, bt_mesh.iv_index); if (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_INITIATOR) && (bt_mesh_atomic_test_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS) == diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c index 9ca4c2e32..3138079fd 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c @@ -13,13 +13,13 @@ #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL) +#include "btc_ble_mesh_config_model.h" + #include "mesh.h" #include "foundation.h" #include "mesh_common.h" #include "cfg_cli.h" -#include "btc_ble_mesh_config_model.h" - #define CID_NVAL 0xffff /* 2 byte dummy opcode for getting compile time buffer sizes. */ @@ -341,14 +341,13 @@ static void net_key_status(struct bt_mesh_model *model, struct net_buf_simple *buf) { struct bt_mesh_cfg_netkey_status status = {0}; - u16_t app_idx = 0U; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, bt_hex(buf->data, buf->len)); status.status = net_buf_simple_pull_u8(buf); - key_idx_unpack(buf, &status.net_idx, &app_idx); + status.net_idx = net_buf_simple_pull_le16(buf) & 0xfff; cfg_client_cancel(model, ctx, &status, sizeof(struct bt_mesh_cfg_netkey_status)); } diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c index 56a906deb..c8ebf854a 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c @@ -13,6 +13,8 @@ #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL) +#include "btc_ble_mesh_config_model.h" + #include "mesh.h" #include "adv.h" #include "lpn.h" @@ -28,8 +30,6 @@ #include "mesh_main.h" #include "mesh_common.h" -#include "btc_ble_mesh_config_model.h" - #define DEFAULT_TTL 7 /* Maximum message length is 384 in BLE Mesh. Here for composition data, @@ -49,7 +49,7 @@ static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, int i; if (net_buf_simple_tailroom(buf) < - 4 + (elem->model_count * 2U) + (elem->vnd_model_count * 2U)) { + 4 + (elem->model_count * 2U) + (elem->vnd_model_count * 4U)) { BT_ERR("%s, Too large device composition", __func__); return -E2BIG; } @@ -822,30 +822,6 @@ static void gatt_proxy_set(struct bt_mesh_model *model, bt_mesh_store_cfg(); } - if (cfg->gatt_proxy == BLE_MESH_GATT_PROXY_DISABLED) { - int i; - - /* Section 4.2.11.1: "When the GATT Proxy state is set to - * 0x00, the Node Identity state for all subnets shall be set - * to 0x00 and shall not be changed." - */ - for (i = 0; i < ARRAY_SIZE(bt_mesh.sub); i++) { - struct bt_mesh_subnet *sub = &bt_mesh.sub[i]; - - if (sub->net_idx != BLE_MESH_KEY_UNUSED) { - bt_mesh_proxy_identity_stop(sub); - } - } - - /* Section 4.2.11: "Upon transition from GATT Proxy state 0x01 - * to GATT Proxy state 0x00 the GATT Bearer Server shall - * disconnect all GATT Bearer Clients. - */ - bt_mesh_proxy_gatt_disconnect(); - } - - bt_mesh_adv_update(); - if (cfg->hb_pub.feat & BLE_MESH_FEAT_PROXY) { bt_mesh_heartbeat_send(); } @@ -2493,12 +2469,8 @@ static void node_identity_set(struct bt_mesh_model *model, } else { net_buf_simple_add_u8(&msg, STATUS_SUCCESS); net_buf_simple_add_le16(&msg, idx); - /* Section 4.2.11.1: "When the GATT Proxy state is set to - * 0x00, the Node Identity state for all subnets shall be set - * to 0x00 and shall not be changed." - */ - if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && - bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) { + + if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) { if (node_id) { bt_mesh_proxy_identity_start(sub); } else { @@ -2857,9 +2829,7 @@ static void lpn_timeout_get(struct bt_mesh_model *model, timeout = k_delayed_work_remaining_get(&frnd->timer) / 100; send_rsp: - net_buf_simple_add_u8(&msg, timeout); - net_buf_simple_add_u8(&msg, timeout >> 8); - net_buf_simple_add_u8(&msg, timeout >> 16); + net_buf_simple_add_le24(&msg, timeout); if (bt_mesh_model_send(model, ctx, &msg, NULL, NULL)) { BT_ERR("%s, Unable to send Config LPN PollTimeout Status", __func__); diff --git a/components/bt/esp_ble_mesh/mesh_core/crypto.c b/components/bt/esp_ble_mesh/mesh_core/crypto.c index 48d3a6098..d1d94e167 100644 --- a/components/bt/esp_ble_mesh/mesh_core/crypto.c +++ b/components/bt/esp_ble_mesh/mesh_core/crypto.c @@ -13,6 +13,7 @@ #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_CRYPTO) +#include "mesh_common.h" #include "crypto.h" #include "mesh_aes_encrypt.h" #include "mesh_bearer_adapt.h" diff --git a/components/bt/esp_ble_mesh/mesh_core/foundation.h b/components/bt/esp_ble_mesh/mesh_core/foundation.h index 21744efdd..76634079e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/foundation.h +++ b/components/bt/esp_ble_mesh/mesh_core/foundation.h @@ -8,6 +8,7 @@ #ifndef _FOUNDATION_H_ #define _FOUNDATION_H_ +#include "mesh_byteorder.h" #include "net.h" #ifdef __cplusplus diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 02649b21f..615ef6f8e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -285,7 +285,7 @@ int bt_mesh_friend_clear(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) cfm.lpn_counter = msg->lpn_counter; bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR_CFM, &cfm, - sizeof(cfm), NULL, NULL, NULL); + sizeof(cfm), NULL, NULL); friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_RECV_FRND_CLEAR); @@ -504,9 +504,8 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, } seq = bt_mesh_next_seq(); - buf->data[2] = seq >> 16; - buf->data[3] = seq >> 8; - buf->data[4] = seq; + sys_put_be24(seq, &buf->data[2]); + iv_index = BLE_MESH_NET_IVI_TX; FRIEND_ADV(buf)->app_idx = BLE_MESH_KEY_UNUSED; } else { @@ -814,7 +813,7 @@ static void send_friend_clear(struct bt_mesh_friend *frnd) } bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req, - sizeof(req), NULL, &clear_sent_cb, frnd); + sizeof(req), &clear_sent_cb, frnd); } static void clear_timeout(struct k_work *work) @@ -972,9 +971,7 @@ int bt_mesh_friend_req(struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) return -EINVAL; } - poll_to = (((u32_t)msg->poll_to[0] << 16) | - ((u32_t)msg->poll_to[1] << 8) | - ((u32_t)msg->poll_to[2])); + poll_to = sys_get_be24(msg->poll_to); if (poll_to <= 0x000009 || poll_to >= 0x34bc00) { BT_WARN("%s, Prohibited PollTimeout (0x%06x)", __func__, poll_to); @@ -1286,7 +1283,7 @@ int bt_mesh_friend_deinit(void) return 0; } -static bool is_segack(struct net_buf *buf, u64_t *seqauth, u16_t src) +static bool is_segack(struct net_buf *buf, const u64_t *seqauth, u16_t src) { struct net_buf_simple_state state = {0}; bool found = false; @@ -1322,8 +1319,8 @@ end: return found; } -static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, - u16_t src) +static void friend_purge_old_ack(struct bt_mesh_friend *frnd, + const u64_t *seq_auth, u16_t src) { sys_snode_t *cur = NULL, *prev = NULL; @@ -1350,7 +1347,7 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, struct bt_mesh_net_rx *rx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, u8_t seg_count, + const u64_t *seq_auth, u8_t seg_count, struct net_buf_simple *sbuf) { struct friend_pdu_info info = {0}; @@ -1381,9 +1378,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, info.ctl = rx->ctl; - info.seq[0] = (rx->seq >> 16); - info.seq[1] = (rx->seq >> 8); - info.seq[2] = rx->seq; + sys_put_be24(rx->seq, info.seq); info.iv_index = BLE_MESH_NET_IVI_RX(rx); @@ -1402,7 +1397,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, struct bt_mesh_net_tx *tx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, u8_t seg_count, + const u64_t *seq_auth, u8_t seg_count, struct net_buf_simple *sbuf) { struct friend_pdu_info info = {0}; @@ -1420,9 +1415,7 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, info.ttl = tx->ctx->send_ttl; info.ctl = (tx->ctx->app_idx == BLE_MESH_KEY_UNUSED); - info.seq[0] = (bt_mesh.seq >> 16); - info.seq[1] = (bt_mesh.seq >> 8); - info.seq[2] = bt_mesh.seq; + sys_put_be24(bt_mesh.seq, info.seq); info.iv_index = BLE_MESH_NET_IVI_TX; @@ -1491,7 +1484,7 @@ bool bt_mesh_friend_match(u16_t net_idx, u16_t addr) } static bool friend_queue_has_space(struct bt_mesh_friend *frnd, u16_t addr, - u64_t *seq_auth, u8_t seg_count) + const u64_t *seq_auth, u8_t seg_count) { u32_t total = 0U; int i; @@ -1522,7 +1515,7 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, u16_t addr, } bool bt_mesh_friend_queue_has_space(u16_t net_idx, u16_t src, u16_t dst, - u64_t *seq_auth, u8_t seg_count) + const u64_t *seq_auth, u8_t seg_count) { bool someone_has_space = false, friend_match = false; int i; @@ -1557,7 +1550,7 @@ bool bt_mesh_friend_queue_has_space(u16_t net_idx, u16_t src, u16_t dst, } static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, u16_t addr, - u64_t *seq_auth, u8_t seg_count) + const u64_t *seq_auth, u8_t seg_count) { bool pending_segments = false; u8_t avail_space = 0U; @@ -1594,7 +1587,7 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, u16_t addr, void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, u8_t seg_count, + const u64_t *seq_auth, u8_t seg_count, struct net_buf_simple *sbuf) { int i; @@ -1629,7 +1622,7 @@ void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, u8_t seg_count, + const u64_t *seq_auth, u8_t seg_count, struct net_buf_simple *sbuf) { bool matched = false; @@ -1665,7 +1658,7 @@ bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, } void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, - u16_t dst, u64_t *seq_auth) + u16_t dst, const u64_t *seq_auth) { int i; diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.h b/components/bt/esp_ble_mesh/mesh_core/friend.h index f595ce717..1f47c1bd5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.h +++ b/components/bt/esp_ble_mesh/mesh_core/friend.h @@ -27,19 +27,19 @@ struct bt_mesh_friend *bt_mesh_friend_find(u16_t net_idx, u16_t lpn_addr, bool valid, bool established); bool bt_mesh_friend_queue_has_space(u16_t net_idx, u16_t src, u16_t dst, - u64_t *seq_auth, u8_t seg_count); + const u64_t *seq_auth, u8_t seg_count); void bt_mesh_friend_enqueue_rx(struct bt_mesh_net_rx *rx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, u8_t seg_count, + const u64_t *seq_auth, u8_t seg_count, struct net_buf_simple *sbuf); bool bt_mesh_friend_enqueue_tx(struct bt_mesh_net_tx *tx, enum bt_mesh_friend_pdu_type type, - u64_t *seq_auth, u8_t seg_count, + const u64_t *seq_auth, u8_t seg_count, struct net_buf_simple *sbuf); void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, - u16_t dst, u64_t *seq_auth); + u16_t dst, const u64_t *seq_auth); void bt_mesh_friend_sec_update(u16_t net_idx); diff --git a/components/bt/esp_ble_mesh/mesh_core/health_cli.c b/components/bt/esp_ble_mesh/mesh_core/health_cli.c index 75a025bfd..bceb45047 100644 --- a/components/bt/esp_ble_mesh/mesh_core/health_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/health_cli.c @@ -12,12 +12,12 @@ #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL) +#include "btc_ble_mesh_health_model.h" + #include "foundation.h" #include "mesh_common.h" #include "health_cli.h" -#include "btc_ble_mesh_health_model.h" - s32_t health_msg_timeout; static bt_mesh_health_client_t *health_cli; diff --git a/components/bt/esp_ble_mesh/mesh_core/health_srv.c b/components/bt/esp_ble_mesh/mesh_core/health_srv.c index fc1d0366c..ccf18b368 100644 --- a/components/bt/esp_ble_mesh/mesh_core/health_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/health_srv.c @@ -12,13 +12,13 @@ #define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLE_MESH_DEBUG_MODEL) +#include "btc_ble_mesh_health_model.h" + #include "access.h" #include "foundation.h" #include "mesh_common.h" #include "health_srv.h" -#include "btc_ble_mesh_health_model.h" - #define HEALTH_TEST_STANDARD 0x00 #define HEALTH_NO_FAULT 0x00 diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h index 11a63b1d3..141cc6903 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h @@ -11,10 +11,9 @@ #ifndef _BLE_MESH_ACCESS_H_ #define _BLE_MESH_ACCESS_H_ -#include "mesh_types.h" -#include "mesh_util.h" +#include "sdkconfig.h" #include "mesh_buf.h" -#include "mesh_kernel.h" +#include "mesh_timer.h" /** * @brief Bluetooth Mesh Access Layer @@ -192,9 +191,9 @@ struct bt_mesh_model_op { #define BLE_MESH_MODEL_NONE ((struct bt_mesh_model []){}) /** Length of a short Mesh MIC. */ -#define BLE_MESH_MIC_SHORT 4 +#define BLE_MESH_MIC_SHORT 4 /** Length of a long Mesh MIC. */ -#define BLE_MESH_MIC_LONG 8 +#define BLE_MESH_MIC_LONG 8 /** @def BLE_MESH_MODEL_OP_LEN * @@ -339,7 +338,8 @@ struct bt_mesh_model_pub { u16_t addr; /**< Publish Address. */ u16_t key:12, /**< Publish AppKey Index. */ - cred:1; /**< Friendship Credentials Flag. */ + cred:1, /**< Friendship Credentials Flag. */ + send_rel:1; /**< Force reliable sending (segment acks) */ u8_t ttl; /**< Publish Time to Live. */ u8_t retransmit; /**< Retransmit Count & Interval Steps. */ @@ -367,6 +367,9 @@ struct bt_mesh_model_pub { * @ref bt_mesh_model_pub.msg with a valid publication * message. * + * If the callback returns non-zero, the publication is skipped + * and will resume on the next periodic publishing interval. + * * @param mod The Model the Publication Context belogs to. * * @return Zero on success or (negative) error code otherwise. diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h index 13e344edb..e9fbeb54e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_bearer_adapt.h @@ -21,25 +21,13 @@ extern "C" { /* BLE Mesh Max Connection Count */ #ifdef CONFIG_BT_BLUEDROID_ENABLED -#define BLE_MESH_MAX_CONN \ - MIN(CONFIG_BT_ACL_CONNECTIONS, CONFIG_BTDM_CTRL_BLE_MAX_CONN) - -#define BLE_MESH_ADV_TASK_CORE TASK_PINNED_TO_CORE +#define BLE_MESH_MAX_CONN MIN(CONFIG_BT_ACL_CONNECTIONS, CONFIG_BTDM_CTRL_BLE_MAX_CONN) #endif #ifdef CONFIG_BT_NIMBLE_ENABLED #define BLE_MESH_MAX_CONN CONFIG_BT_NIMBLE_MAX_CONNECTIONS - -#ifdef CONFIG_BT_NIMBLE_PINNED_TO_CORE -#define BLE_MESH_ADV_TASK_CORE (CONFIG_BT_NIMBLE_PINNED_TO_CORE < portNUM_PROCESSORS ? CONFIG_BT_NIMBLE_PINNED_TO_CORE : tskNO_AFFINITY) -#else -#define BLE_MESH_ADV_TASK_CORE (0) #endif -#endif - -#define BLE_MESH_ADV_TASK_STACK_SIZE 3072 - #define BLE_MESH_GAP_ADV_MAX_LEN 31 #define BLE_MESH_GATT_DEF_MTU_SIZE 23 diff --git a/components/bt/esp_ble_mesh/mesh_core/lpn.c b/components/bt/esp_ble_mesh/mesh_core/lpn.c index 69d428ad4..a07b9deec 100644 --- a/components/bt/esp_ble_mesh/mesh_core/lpn.c +++ b/components/bt/esp_ble_mesh/mesh_core/lpn.c @@ -201,7 +201,7 @@ static int send_friend_clear(void) BT_DBG("%s", __func__); return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req, - sizeof(req), NULL, &clear_sent_cb, NULL); + sizeof(req), &clear_sent_cb, NULL); } static void clear_friendship(bool force, bool disable) @@ -328,7 +328,7 @@ static int send_friend_req(struct bt_mesh_lpn *lpn) BT_DBG("%s", __func__); return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_REQ, &req, - sizeof(req), NULL, &friend_req_sent_cb, NULL); + sizeof(req), &friend_req_sent_cb, NULL); } static void req_sent(u16_t duration, int err, void *user_data) @@ -403,7 +403,7 @@ static int send_friend_poll(void) } err = bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_POLL, &fsn, 1, - NULL, &req_sent_cb, NULL); + &req_sent_cb, NULL); if (err == 0) { lpn->pending_poll = 0U; lpn->sent_req = TRANS_CTL_OP_FRIEND_POLL; @@ -718,7 +718,7 @@ static bool sub_update(u8_t op) req.xact = lpn->xact_next++; - if (bt_mesh_ctl_send(&tx, op, &req, 1 + g * 2, NULL, + if (bt_mesh_ctl_send(&tx, op, &req, 1 + g * 2, &req_sent_cb, NULL) < 0) { group_zero(lpn->pending); return false; diff --git a/components/bt/esp_ble_mesh/mesh_core/main.c b/components/bt/esp_ble_mesh/mesh_core/main.c index f293a68d3..f728ebf34 100644 --- a/components/bt/esp_ble_mesh/mesh_core/main.c +++ b/components/bt/esp_ble_mesh/mesh_core/main.c @@ -319,7 +319,9 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, return -EALREADY; } - bt_mesh_k_init(); + bt_mesh_mutex_init(); + + bt_mesh_timer_init(); bt_mesh_hci_init(); @@ -334,6 +336,19 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, bt_mesh_gatt_init(); } + if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) { + if ((IS_ENABLED(CONFIG_BLE_MESH_NODE) && + IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) || + IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) { + bt_mesh_proxy_init(); + } + if ((IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && + IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) || + IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) { + bt_mesh_proxy_prov_client_init(); + } + } + if (IS_ENABLED(CONFIG_BLE_MESH_PROV)) { if (IS_ENABLED(CONFIG_BLE_MESH_NODE)) { err = bt_mesh_prov_init(prov); @@ -363,19 +378,6 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, bt_mesh_adv_init(); - if (IS_ENABLED(CONFIG_BLE_MESH_PROXY)) { - if ((IS_ENABLED(CONFIG_BLE_MESH_NODE) && - IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) || - IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER)) { - bt_mesh_proxy_init(); - } - if ((IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && - IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) || - IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_CLIENT)) { - bt_mesh_proxy_prov_client_init(); - } - } - if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER)) { bt_mesh_provisioner_init(); } @@ -485,7 +487,9 @@ int bt_mesh_deinit(struct bt_mesh_deinit_param *param) bt_mesh_settings_deinit(); } - bt_mesh_k_deinit(); + bt_mesh_timer_deinit(); + + bt_mesh_mutex_deinit(); mesh_init = false; return 0; @@ -657,6 +661,7 @@ u8_t bt_mesh_set_fast_prov_action(u8_t action) if (IS_ENABLED(CONFIG_BLE_MESH_PB_GATT)) { bt_mesh_provisioner_pb_gatt_enable(); } + bt_mesh_provisioner_set_primary_elem_addr(bt_mesh_primary_addr()); 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/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index eeccc6664..bf63695e6 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -43,8 +43,7 @@ #define NID(pdu) ((pdu)[0] & 0x7f) #define CTL(pdu) ((pdu)[1] >> 7) #define TTL(pdu) ((pdu)[1] & 0x7f) -#define SEQ(pdu) (((u32_t)(pdu)[2] << 16) | \ - ((u32_t)(pdu)[3] << 8) | (u32_t)(pdu)[4]); +#define SEQ(pdu) (sys_get_be24(&(pdu)[2])) #define SRC(pdu) (sys_get_be16(&(pdu)[5])) #define DST(pdu) (sys_get_be16(&(pdu)[7])) @@ -61,7 +60,10 @@ static struct friend_cred friend_cred[FRIEND_CRED_COUNT]; #endif -static u64_t msg_cache[CONFIG_BLE_MESH_MSG_CACHE_SIZE]; +static struct { + u32_t src:15, /* MSB of source address is always 0 */ + seq:17; +} msg_cache[CONFIG_BLE_MESH_MSG_CACHE_SIZE]; static u16_t msg_cache_next; /* Singleton network context (the implementation only supports one) */ @@ -106,49 +108,38 @@ static bool check_dup(struct net_buf_simple *data) return false; } -static u64_t msg_hash(struct bt_mesh_net_rx *rx, struct net_buf_simple *pdu) -{ - u32_t hash1 = 0U, hash2 = 0U; - - /* Three least significant bytes of IVI + first byte of SEQ */ - hash1 = (BLE_MESH_NET_IVI_RX(rx) << 8) | pdu->data[2]; - - /* Two last bytes of SEQ + SRC */ - memcpy(&hash2, &pdu->data[3], 4); - - return (u64_t)hash1 << 32 | (u64_t)hash2; -} - static bool msg_cache_match(struct bt_mesh_net_rx *rx, struct net_buf_simple *pdu) { - u64_t hash = msg_hash(rx, pdu); int i; for (i = 0; i < ARRAY_SIZE(msg_cache); i++) { - if (msg_cache[i] == hash) { + if (msg_cache[i].src == SRC(pdu->data) && + msg_cache[i].seq == (SEQ(pdu->data) & BIT_MASK(17))) { return true; } } - /* Add to the cache */ - rx->msg_cache_idx = msg_cache_next++; - msg_cache[rx->msg_cache_idx] = hash; - msg_cache_next %= ARRAY_SIZE(msg_cache); - return false; } +static void msg_cache_add(struct bt_mesh_net_rx *rx) +{ + rx->msg_cache_idx = msg_cache_next++; + msg_cache[rx->msg_cache_idx].src = rx->ctx.addr; + msg_cache[rx->msg_cache_idx].seq = rx->seq; + msg_cache_next %= ARRAY_SIZE(msg_cache); +} + #if CONFIG_BLE_MESH_PROVISIONER void bt_mesh_msg_cache_clear(u16_t unicast_addr, u8_t elem_num) { - u16_t src = 0U; int i; for (i = 0; i < ARRAY_SIZE(msg_cache); i++) { - src = (((u8_t)(msg_cache[i] >> 16)) << 8) | (u8_t)(msg_cache[i] >> 24); - if (src >= unicast_addr && src < unicast_addr + elem_num) { - memset(&msg_cache[i], 0x0, sizeof(msg_cache[i])); + if (msg_cache[i].src >= unicast_addr && + msg_cache[i].src < unicast_addr + elem_num) { + memset(&msg_cache[i], 0, sizeof(msg_cache[i])); } } } @@ -510,6 +501,10 @@ void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub) BT_DBG("idx 0x%04x", sub->net_idx); memcpy(&sub->keys[0], &sub->keys[1], sizeof(sub->keys[0])); + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + BT_DBG("Store updated NetKey persistently"); + bt_mesh_store_subnet(sub); + } for (i = 0; i < ARRAY_SIZE(bt_mesh.app_keys); i++) { struct bt_mesh_app_key *key = &bt_mesh.app_keys[i]; @@ -520,6 +515,10 @@ void bt_mesh_net_revoke_keys(struct bt_mesh_subnet *sub) memcpy(&key->keys[0], &key->keys[1], sizeof(key->keys[0])); key->updated = false; + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + BT_DBG("Store updated AppKey persistently"); + bt_mesh_store_app_key(key); + } } } @@ -791,9 +790,7 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, /* Update with a new sequence number */ seq = bt_mesh_next_seq(); - buf->data[2] = seq >> 16; - buf->data[3] = seq >> 8; - buf->data[4] = seq; + sys_put_be24(seq, &buf->data[2]); /* Get destination, in case it's a proxy client */ dst = DST(buf->data); @@ -811,7 +808,8 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, } if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && - bt_mesh_proxy_relay(&buf->b, dst)) { + bt_mesh_proxy_relay(&buf->b, dst) && + BLE_MESH_ADDR_IS_UNICAST(dst)) { send_cb_finalize(cb, cb_data); return 0; } @@ -835,16 +833,14 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, bool proxy) { const bool ctl = (tx->ctx->app_idx == BLE_MESH_KEY_UNUSED); - u32_t seq_val = 0U; - u8_t nid = 0U; const u8_t *enc = NULL, *priv = NULL; - u8_t *seq = NULL; + u8_t nid = 0U; int err = 0; - if (ctl && net_buf_simple_tailroom(buf) < 8) { + if (ctl && net_buf_simple_tailroom(buf) < BLE_MESH_MIC_LONG) { BT_ERR("%s, Insufficient MIC space for CTL PDU", __func__); return -EINVAL; - } else if (net_buf_simple_tailroom(buf) < 4) { + } else if (net_buf_simple_tailroom(buf) < BLE_MESH_MIC_SHORT) { BT_ERR("%s, Insufficient MIC space for PDU", __func__); return -EINVAL; } @@ -855,11 +851,7 @@ int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, net_buf_simple_push_be16(buf, tx->ctx->addr); net_buf_simple_push_be16(buf, tx->src); - seq = net_buf_simple_push(buf, 3); - seq_val = bt_mesh_next_seq(); - seq[0] = seq_val >> 16; - seq[1] = seq_val >> 8; - seq[2] = seq_val; + net_buf_simple_push_be24(buf, bt_mesh_next_seq()); if (ctl) { net_buf_simple_push_u8(buf, tx->ctx->send_ttl | 0x80); @@ -1048,17 +1040,17 @@ static int net_decrypt(struct bt_mesh_subnet *sub, const u8_t *enc, return -ENOENT; } - if (rx->net_if == BLE_MESH_NET_IF_ADV && msg_cache_match(rx, buf)) { - BT_WARN("Duplicate found in Network Message Cache"); - return -EALREADY; - } - rx->ctx.addr = SRC(buf->data); if (!BLE_MESH_ADDR_IS_UNICAST(rx->ctx.addr)) { - BT_WARN("Ignoring non-unicast src addr 0x%04x", rx->ctx.addr); + BT_INFO("Ignoring non-unicast src addr 0x%04x", rx->ctx.addr); return -EINVAL; } + if (rx->net_if == BLE_MESH_NET_IF_ADV && msg_cache_match(rx, buf)) { + BT_DBG("Duplicate found in Network Message Cache"); + return -EALREADY; + } + BT_DBG("src 0x%04x", rx->ctx.addr); if (IS_ENABLED(CONFIG_BLE_MESH_PROXY) && @@ -1381,6 +1373,8 @@ int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, rx->ctx.recv_ttl); BT_DBG("PDU: %s", bt_hex(buf->data, buf->len)); + msg_cache_add(rx); + return 0; } @@ -1448,13 +1442,19 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, /* Save the state so the buffer can later be relayed */ net_buf_simple_save(&buf, &state); + rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) || + bt_mesh_elem_find(rx.ctx.recv_dst)); + if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && net_if == BLE_MESH_NET_IF_PROXY) { bt_mesh_proxy_addr_add(data, rx.ctx.addr); - } - rx.local_match = (bt_mesh_fixed_group_match(rx.ctx.recv_dst) || - bt_mesh_elem_find(rx.ctx.recv_dst)); + if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_DISABLED && + !rx.local_match) { + BT_INFO("Proxy is disabled; ignoring message"); + return; + } + } /* The transport layer has indicated that it has rejected the message, * but would like to see it again if it is received in the future. @@ -1465,7 +1465,7 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, */ if (bt_mesh_trans_recv(&buf, &rx) == -EAGAIN) { BT_WARN("Removing rejected message from Network Message Cache"); - msg_cache[rx.msg_cache_idx] = 0ULL; + msg_cache[rx.msg_cache_idx].src = BLE_MESH_ADDR_UNASSIGNED; /* Rewind the next index now that we're not using this entry */ msg_cache_next = rx.msg_cache_idx; } diff --git a/components/bt/esp_ble_mesh/mesh_core/prov.c b/components/bt/esp_ble_mesh/mesh_core/prov.c index bc36a6efb..8f624cd0a 100644 --- a/components/bt/esp_ble_mesh/mesh_core/prov.c +++ b/components/bt/esp_ble_mesh/mesh_core/prov.c @@ -1750,6 +1750,8 @@ int bt_mesh_prov_init(const struct bt_mesh_prov *prov_info) return -EINVAL; } + __ASSERT(prov_info->uuid, "%s, Device UUID is not initialized", __func__); + /* Changed by Espressif. Use micro-ecc to generate public key now. */ key = bt_mesh_pub_key_get(); if (!key) { diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c index 16450854d..feaf93a95 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c @@ -157,8 +157,8 @@ int bt_mesh_provisioner_net_create(void) } done: - BT_INFO("net_idx 0x%03x, netkey %s, nid 0x%02x", - sub->net_idx, bt_hex(sub->keys[0].net, 16), sub->keys[0].nid); + BT_INFO("NetKey Index 0x%03x, NID 0x%02x", sub->net_idx, sub->keys[0].nid); + BT_INFO("NetKey %s", bt_hex(sub->keys[0].net, 16)); return 0; } @@ -303,7 +303,7 @@ static int provisioner_store_node(struct bt_mesh_node *node, bool store, u16_t * } } - BT_ERR("%s, Node queue is full", __func__); + BT_ERR("Node is full!"); bt_mesh_provisioner_unlock(); return -ENOMEM; } @@ -355,7 +355,7 @@ static int provisioner_remove_node(u16_t index, bool erase) struct bt_mesh_node *node = NULL; int i; - BT_DBG("%s, reset node %d", __func__, index); + BT_DBG("Remove node %d", index); bt_mesh_provisioner_lock(); @@ -441,7 +441,7 @@ int bt_mesh_provisioner_remove_node(const u8_t uuid[16]) node = provisioner_find_node_with_uuid(uuid, &index); if (!node) { - BT_WARN("Node %s not exist", bt_hex(uuid, 16)); + BT_WARN("%s, Node not exists, uuid %s", __func__, bt_hex(uuid, 16)); return -ENODEV; } @@ -485,7 +485,7 @@ int bt_mesh_provisioner_restore_node_name(u16_t addr, const char *name) node = provisioner_find_node_with_addr(addr, NULL); if (node == NULL) { - BT_ERR("%s, Node 0x%04x not exist", __func__, addr); + BT_ERR("%s, Node not exists, addr 0x%04x", __func__, addr); return -ENODEV; } @@ -506,7 +506,7 @@ int bt_mesh_provisioner_restore_node_comp_data(u16_t addr, const u8_t *data, u16 node = provisioner_find_node_with_addr(addr, NULL); if (node == NULL) { - BT_ERR("%s, Node 0x%04x not exist", __func__, addr); + BT_ERR("%s, Node not exists, addr 0x%04x", __func__, addr); return -ENODEV; } @@ -539,7 +539,7 @@ int bt_mesh_provisioner_delete_node_with_uuid(const u8_t uuid[16]) node = provisioner_find_node_with_uuid(uuid, &index); if (!node) { - BT_WARN("Node %s not exist", bt_hex(uuid, 16)); + BT_WARN("%s, Node not exists, uuid %s", __func__, bt_hex(uuid, 16)); return -ENODEV; } @@ -554,7 +554,7 @@ int bt_mesh_provisioner_delete_node_with_node_addr(u16_t unicast_addr) node = provisioner_find_node_with_addr(unicast_addr, &index); if (!node) { - BT_WARN("Node 0x%04x not exist", unicast_addr); + BT_WARN("%s, Node not exists, addr 0x%04x", __func__, unicast_addr); return -ENODEV; } @@ -587,7 +587,7 @@ static int provisioner_check_node_index(u16_t index) } if (mesh_nodes[index] == NULL) { - BT_ERR("%s, Node %d is not found", __func__, index); + BT_ERR("%s, Node not exists, index %d", __func__, index); return -ENODEV; } @@ -607,11 +607,10 @@ int bt_mesh_provisioner_set_node_name(u16_t index, const char *name) } if (provisioner_check_node_index(index)) { - BT_ERR("%s, Failed to check node index", __func__); return -EINVAL; } - BT_DBG("name len is %d, name is %s", strlen(name), name); + BT_DBG("len %d, name %s", strlen(name), name); length = (strlen(name) <= BLE_MESH_NODE_NAME_SIZE) ? strlen(name) : BLE_MESH_NODE_NAME_SIZE; for (i = 0; i < ARRAY_SIZE(mesh_nodes); i++) { @@ -621,7 +620,7 @@ int bt_mesh_provisioner_set_node_name(u16_t index, const char *name) continue; } if (!strncmp(mesh_nodes[i]->name, name, length)) { - BT_WARN("Node name %s already exists", name); + BT_WARN("Node name %s exists", name); return -EEXIST; } } @@ -642,7 +641,6 @@ const char *bt_mesh_provisioner_get_node_name(u16_t index) BT_DBG("%s", __func__); if (provisioner_check_node_index(index)) { - BT_ERR("%s, Failed to check node index", __func__); return NULL; } @@ -674,7 +672,7 @@ u16_t bt_mesh_provisioner_get_node_index(const char *name) } } - BT_ERR("%s, Node name %s not exist", __func__, name); + BT_ERR("Node name %s not exists", name); return BLE_MESH_INVALID_NODE_INDEX; } @@ -691,7 +689,7 @@ int bt_mesh_provisioner_store_node_comp_data(u16_t addr, const u8_t *data, u16_t node = provisioner_find_node_with_addr(addr, &index); if (node == NULL) { - BT_ERR("%s, Node 0x%04x not exist", __func__, addr); + BT_ERR("%s, Node not exists, addr 0x%04x", __func__, addr); return -ENODEV; } @@ -701,7 +699,7 @@ int bt_mesh_provisioner_store_node_comp_data(u16_t addr, const u8_t *data, u16_t return -ENOMEM; } - BT_DBG("%s, index %d", __func__, index); + BT_DBG("node index %d", index); memcpy(node->comp_data, data, length); node->comp_length = length; @@ -955,7 +953,7 @@ int bt_mesh_provisioner_local_app_key_add(const u8_t app_key[16], u16_t net_idx, int add = -1; if (bt_mesh.p_app_idx_next >= 0x1000) { - BT_ERR("%s, No AppKey Index available", __func__); + BT_ERR("No AppKey Index available"); return -EIO; } @@ -966,31 +964,31 @@ int bt_mesh_provisioner_local_app_key_add(const u8_t app_key[16], u16_t net_idx, /* Check if the same application key already exists */ if (provisioner_check_app_key(app_key, app_idx)) { - BT_WARN("AppKey already exists, AppKey Index updated"); + BT_WARN("AppKey exists, AppKey Index updated"); return 0; } /* Check if the net_idx exists */ if (provisioner_check_net_idx(net_idx, false)) { - BT_ERR("%s, NetKey Index does not exist", __func__); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return -ENODEV; } /* Check if the same app_idx already exists */ if (provisioner_check_app_idx(*app_idx, true)) { - BT_ERR("%s, AppKey Index already exists", __func__); + BT_ERR("%s, AppKey Index 0x%03x exists", __func__, *app_idx); return -EEXIST; } add = provisioner_check_app_key_full(); if (add < 0) { - BT_ERR("%s, AppKey queue is full", __func__); + BT_ERR("AppKey is full!"); return -ENOMEM; } if (!app_key) { if (bt_mesh_rand(p_key, 16)) { - BT_ERR("%s, Failed to generate AppKey", __func__); + BT_ERR("Failed to generate AppKey"); return -EIO; } } else { @@ -1020,7 +1018,7 @@ int bt_mesh_provisioner_local_app_key_add(const u8_t app_key[16], u16_t net_idx, if (provisioner_check_app_idx(key->app_idx, true)) { key->app_idx = (++bt_mesh.p_app_idx_next); if (key->app_idx >= 0x1000) { - BT_ERR("%s, No AppKey Index available", __func__); + BT_ERR("No AppKey Index available"); bt_mesh_free(key); return -EIO; } @@ -1056,13 +1054,13 @@ int bt_mesh_provisioner_local_app_key_update(const u8_t app_key[16], u16_t net_i /* Check if the net_idx exists */ if (provisioner_check_net_idx(net_idx, false)) { - BT_ERR("%s, NetKey Index 0x%03x not exist", __func__, net_idx); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return -ENODEV; } key = bt_mesh_provisioner_app_key_find(app_idx); if (key == NULL) { - BT_ERR("%s, AppKey 0x%03x not exist", __func__, app_idx); + BT_ERR("%s, AppKey Index 0x%03x not exists", __func__, app_idx); return -ENODEV; } @@ -1093,12 +1091,12 @@ const u8_t *bt_mesh_provisioner_local_app_key_get(u16_t net_idx, u16_t app_idx) BT_DBG("%s", __func__); if (provisioner_check_net_idx(net_idx, false)) { - BT_ERR("%s, NetKey Index does not exist", __func__); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return NULL; } if (provisioner_check_app_idx(app_idx, false)) { - BT_ERR("%s, AppKey Index does not exist", __func__); + BT_ERR("%s, AppKey Index 0x%03x not exists", __func__, app_idx); return NULL; } @@ -1149,7 +1147,7 @@ static void model_unbind(struct bt_mesh_model *model, u16_t app_idx) { int i; - BT_DBG("model %p key_idx 0x%03x", model, app_idx); + BT_DBG("model %p app_idx 0x%03x", model, app_idx); for (i = 0; i < ARRAY_SIZE(model->keys); i++) { if (model->keys[i] != app_idx) { @@ -1182,12 +1180,12 @@ int bt_mesh_provisioner_local_app_key_delete(u16_t net_idx, u16_t app_idx) BT_DBG("%s", __func__); if (provisioner_check_net_idx(net_idx, false)) { - BT_ERR("%s, NetKey Index does not exist", __func__); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return -ENODEV; } if (provisioner_check_app_idx(app_idx, false)) { - BT_ERR("%s, AppKey Index does not exist", __func__); + BT_ERR("%s, AppKey Index 0x%03x not exists", __func__, app_idx); return -ENODEV; } @@ -1219,7 +1217,7 @@ int bt_mesh_provisioner_local_net_key_add(const u8_t net_key[16], u16_t *net_idx int add = -1; if (bt_mesh.p_net_idx_next >= 0x1000) { - BT_ERR("%s, No NetKey Index available", __func__); + BT_ERR("No NetKey Index available"); return -EIO; } @@ -1230,25 +1228,25 @@ int bt_mesh_provisioner_local_net_key_add(const u8_t net_key[16], u16_t *net_idx /* Check if the same network key already exists */ if (provisioner_check_net_key(net_key, net_idx)) { - BT_WARN("NetKey already exists, NetKey Index updated"); + BT_WARN("NetKey exists, NetKey Index updated"); return 0; } /* Check if the same net_idx already exists */ if (provisioner_check_net_idx(*net_idx, true)) { - BT_ERR("%s, NetKey Index already exists", __func__); + BT_ERR("%s, NetKey Index 0x%03x exists", __func__, *net_idx); return -EEXIST; } add = provisioner_check_net_key_full(); if (add < 0) { - BT_ERR("%s, NetKey queue is full", __func__); + BT_ERR("NetKey is full!"); return -ENOMEM; } if (!net_key) { if (bt_mesh_rand(p_key, 16)) { - BT_ERR("%s, Failed to generate NetKey", __func__); + BT_ERR("Failed to generate NetKey"); return -EIO; } } else { @@ -1275,7 +1273,7 @@ int bt_mesh_provisioner_local_net_key_add(const u8_t net_key[16], u16_t *net_idx if (provisioner_check_net_idx(sub->net_idx, true)) { sub->net_idx = (++bt_mesh.p_net_idx_next); if (sub->net_idx >= 0x1000) { - BT_ERR("%s, No NetKey Index available", __func__); + BT_ERR("No NetKey Index available"); bt_mesh_free(sub); return -EIO; } @@ -1313,7 +1311,7 @@ int bt_mesh_provisioner_local_net_key_update(const u8_t net_key[16], u16_t net_i sub = bt_mesh_provisioner_subnet_get(net_idx); if (sub == NULL) { - BT_ERR("%s, NetKey 0x%03x not exist", __func__, net_idx); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return -ENODEV; } @@ -1351,7 +1349,7 @@ const u8_t *bt_mesh_provisioner_local_net_key_get(u16_t net_idx) BT_DBG("%s", __func__); if (provisioner_check_net_idx(net_idx, false)) { - BT_ERR("%s, NetKey Index does not exist", __func__); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return NULL; } @@ -1376,7 +1374,7 @@ int bt_mesh_provisioner_local_net_key_delete(u16_t net_idx) BT_DBG("%s", __func__); if (provisioner_check_net_idx(net_idx, false)) { - BT_ERR("%s, NetKey Index does not exist", __func__); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return -ENODEV; } @@ -1414,7 +1412,7 @@ int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id, elem = bt_mesh_elem_find(elem_addr); if (!elem) { - BT_ERR("%s, No element is found", __func__); + BT_ERR("%s, No element found, addr 0x%04x", __func__, elem_addr); return -ENODEV; } @@ -1429,13 +1427,13 @@ int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id, } if (provisioner_check_app_idx(app_idx, false)) { - BT_ERR("%s, AppKey Index does not exist", __func__); + BT_ERR("%s, AppKey Index 0x%03x not exists", __func__, app_idx); return -ENODEV; } for (i = 0; i < ARRAY_SIZE(model->keys); i++) { if (model->keys[i] == app_idx) { - BT_WARN("AppKey 0x%03x is already bound to model", app_idx); + BT_INFO("AppKey 0x%03x already bound to model", app_idx); return 0; } } @@ -1451,7 +1449,7 @@ int bt_mesh_provisioner_bind_local_model_app_idx(u16_t elem_addr, u16_t mod_id, } } - BT_ERR("%s, Model AppKey queue is full", __func__); + BT_ERR("Model bound is full!"); return -ENOMEM; } @@ -1663,7 +1661,7 @@ const u8_t *bt_mesh_get_fast_prov_net_key(u16_t net_idx) sub = bt_mesh_fast_prov_subnet_get(net_idx); if (!sub) { - BT_ERR("%s, Failed to get subnet", __func__); + BT_ERR("%s, NetKey Index 0x%03x not exists", __func__, net_idx); return NULL; } @@ -1676,7 +1674,7 @@ const u8_t *bt_mesh_get_fast_prov_app_key(u16_t net_idx, u16_t app_idx) key = bt_mesh_fast_prov_app_key_find(app_idx); if (!key) { - BT_ERR("%s, Failed to get AppKey", __func__); + BT_ERR("%s, AppKey Index 0x%03x not exists", __func__, app_idx); return NULL; } diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h index 05071fe82..d44a2a89e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_prov.h @@ -22,22 +22,13 @@ extern "C" { #endif -#if !CONFIG_BLE_MESH_PROVISIONER - +#ifndef CONFIG_BLE_MESH_PBA_SAME_TIME #define CONFIG_BLE_MESH_PBA_SAME_TIME 0 +#endif + +#ifndef CONFIG_BLE_MESH_PBG_SAME_TIME #define CONFIG_BLE_MESH_PBG_SAME_TIME 0 - -#else - -#if !defined(CONFIG_BLE_MESH_PB_ADV) -#define CONFIG_BLE_MESH_PBA_SAME_TIME 0 -#endif /* !CONFIG_BLE_MESH_PB_ADV */ - -#if !defined(CONFIG_BLE_MESH_PB_GATT) -#define CONFIG_BLE_MESH_PBG_SAME_TIME 0 -#endif /* !CONFIG_BLE_MESH_PB_GATT */ - -#endif /* !CONFIG_BLE_MESH_PROVISIONER */ +#endif #define RM_AFTER_PROV BIT(0) #define START_PROV_NOW BIT(1) diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c index 72e443a90..4305a3ebb 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c @@ -1174,7 +1174,7 @@ static bool advertise_subnet(struct bt_mesh_subnet *sub) } return (sub->node_id == BLE_MESH_NODE_IDENTITY_RUNNING || - bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED); + bt_mesh_gatt_proxy_get() != BLE_MESH_GATT_PROXY_NOT_SUPPORTED); } static struct bt_mesh_subnet *next_sub(void) @@ -1252,11 +1252,7 @@ static s32_t gatt_proxy_advertise(struct bt_mesh_subnet *sub) } if (sub->node_id == BLE_MESH_NODE_IDENTITY_STOPPED) { - if (bt_mesh_gatt_proxy_get() == BLE_MESH_GATT_PROXY_ENABLED) { - net_id_adv(sub); - } else { - return gatt_proxy_advertise(next_sub()); - } + net_id_adv(sub); } subnet_count = sub_count(); @@ -1420,11 +1416,6 @@ int bt_mesh_proxy_init(void) bt_mesh_gatts_conn_cb_register(&conn_callbacks); -#if defined(CONFIG_BLE_MESH_PB_GATT) - const struct bt_mesh_prov *prov = bt_mesh_prov_get(); - __ASSERT(prov && prov->uuid, "%s, Device UUID is not initialized", __func__); -#endif - return bt_mesh_gatts_set_local_device_name(device_name); } diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index 81ae7ca77..a7f564024 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/components/bt/esp_ble_mesh/mesh_core/settings.c @@ -178,6 +178,7 @@ static int role_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)bt_mesh.flags, sizeof(bt_mesh.flags), &exist); if (err) { + BT_ERR("Failed to load mesh device role"); return err; } @@ -185,8 +186,6 @@ static int role_set(const char *name) return 0; } - BT_INFO("Restored mesh device role %lu", bt_mesh_atomic_get(bt_mesh.flags) & DEVICE_ROLE_BITS); - return 0; } @@ -200,7 +199,7 @@ static int net_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&net, sizeof(net), &exist); if (err) { - BT_WARN("%s, Clear NET", __func__); + BT_ERR("Failed to load node net info"); memset(bt_mesh.dev_key, 0, sizeof(bt_mesh.dev_key)); bt_mesh_comp_unprovision(); return 0; @@ -213,7 +212,7 @@ static int net_set(const char *name) memcpy(bt_mesh.dev_key, net.dev_key, sizeof(bt_mesh.dev_key)); bt_mesh_comp_provision(net.primary_addr); - BT_INFO("Restored primary address 0x%04x", net.primary_addr); + BT_INFO("Restored Primary Address 0x%04x", net.primary_addr); BT_INFO("Restored DevKey %s", bt_hex(bt_mesh.dev_key, 16)); return 0; @@ -229,7 +228,7 @@ static int iv_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&iv, sizeof(iv), &exist); if (err) { - BT_WARN("%s, Clear IV", __func__); + BT_ERR("Failed to load iv_index"); bt_mesh.iv_index = 0U; bt_mesh_atomic_clear_bit(bt_mesh.flags, BLE_MESH_IVU_IN_PROGRESS); return 0; @@ -259,7 +258,7 @@ static int seq_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&seq, sizeof(seq), &exist); if (err) { - BT_WARN("%s, Clear SEQ", __func__); + BT_ERR("Failed to load sequence number"); bt_mesh.seq = 0U; return 0; } @@ -268,8 +267,7 @@ static int seq_set(const char *name) return 0; } - bt_mesh.seq = ((u32_t)seq.val[0] | ((u32_t)seq.val[1] << 8) | - ((u32_t)seq.val[2] << 16)); + bt_mesh.seq = sys_get_le24(seq.val); #if CONFIG_BLE_MESH_SEQ_STORE_RATE > 0 /* Make sure we have a large enough sequence number. We @@ -339,7 +337,7 @@ static int rpl_set(const char *name) err = bt_mesh_load_core_settings(get, (u8_t *)&rpl, sizeof(rpl), &exist); if (err) { - BT_ERR("%s, Failed to load RPL %s, reset RPL", __func__, get); + BT_ERR("Failed to load RPL entry 0x%04x", src); bt_mesh_rpl_reset(); goto free; } @@ -358,7 +356,7 @@ static int rpl_set(const char *name) } } - BT_INFO("Restored RPL 0x%04x: Seq 0x%06x, old_iv %u", src, rpl.seq, rpl.old_iv); + BT_INFO("Restored RPL entry 0x%04x: seq 0x%06x, old_iv %u", src, rpl.seq, rpl.old_iv); entry->src = src; entry->seq = rpl.seq; entry->old_iv = rpl.old_iv; @@ -409,7 +407,7 @@ static int net_key_set(const char *name) err = bt_mesh_load_core_settings(get, (u8_t *)&key, sizeof(key), &exist); if (err) { - BT_ERR("%s, Failed to load NetKey %s", __func__, get); + BT_ERR("%s, Failed to load NetKey 0x%03x", __func__, net_idx); goto free; } @@ -427,12 +425,14 @@ static int net_key_set(const char *name) } } - BT_INFO("Restored NetKey Index 0x%03x", net_idx); sub->net_idx = net_idx; sub->kr_flag = key.kr_flag; sub->kr_phase = key.kr_phase; memcpy(sub->keys[0].net, &key.val[0], 16); memcpy(sub->keys[1].net, &key.val[1], 16); + + BT_INFO("Restored NetKey Index 0x%03x", sub->net_idx); + BT_INFO("Restored NetKey %s", bt_hex(sub->keys[0].net, 16)); } free: @@ -467,7 +467,7 @@ static int app_key_set(const char *name) err = bt_mesh_load_core_settings(get, (u8_t *)&key, sizeof(key), &exist); if (err) { - BT_ERR("%s, Failed to load AppKey %s", __func__, get); + BT_ERR("%s, Failed to load AppKey 0x%03x", __func__, app_idx); goto free; } @@ -492,7 +492,6 @@ static int app_key_set(const char *name) } } - BT_INFO("Restored AppKey Index 0x%03x", app_idx); app->net_idx = key.net_idx; app->app_idx = app_idx; app->updated = key.updated; @@ -500,6 +499,10 @@ static int app_key_set(const char *name) memcpy(app->keys[1].val, key.val[1], 16); bt_mesh_app_id(app->keys[0].val, &app->keys[0].id); bt_mesh_app_id(app->keys[1].val, &app->keys[1].id); + + BT_INFO("Restored AppKey Index 0x%03x, NetKey Index 0x%03x", + app->app_idx, app->net_idx); + BT_INFO("Restored AppKey %s", bt_hex(app->keys[0].val, 16)); } free: @@ -523,7 +526,7 @@ static int hb_pub_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&hb_val, sizeof(hb_val), &exist); if (err) { - BT_WARN("%s, Cleared heartbeat publication", __func__); + BT_ERR("Failed to load heartbeat publication"); hb_pub->dst = BLE_MESH_ADDR_UNASSIGNED; hb_pub->count = 0U; hb_pub->ttl = 0U; @@ -547,7 +550,7 @@ static int hb_pub_set(const char *name) hb_pub->count = 0U; } - BT_INFO("Restored heartbeat publication, dst 0x%04x", hb_pub->dst); + BT_INFO("Restored Heartbeat Publication, dst 0x%04x", hb_pub->dst); return 0; } @@ -569,7 +572,7 @@ static int cfg_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&val, sizeof(val), &exist); if (err) { - BT_WARN("%s, Cleared configuration", __func__); + BT_ERR("Failed to load configuration state"); stored_cfg.valid = false; return 0; } @@ -580,7 +583,7 @@ static int cfg_set(const char *name) memcpy(&stored_cfg.cfg, &val, sizeof(val)); stored_cfg.valid = true; - BT_INFO("Restored configuration state"); + BT_INFO("Restored Configuration State"); return 0; } @@ -599,7 +602,7 @@ static int model_set_bind(bool vnd, struct bt_mesh_model *model, u16_t model_key sprintf(name, "mesh/%s/%04x/b", vnd ? "v" : "s", model_key); err = bt_mesh_load_core_settings(name, (u8_t *)model->keys, sizeof(model->keys), &exist); if (err) { - BT_ERR("%s, Failed to get model bind keys", __func__); + BT_ERR("Failed to load model bound keys"); return -EIO; } @@ -621,7 +624,7 @@ static int model_set_sub(bool vnd, struct bt_mesh_model *model, u16_t model_key) sprintf(name, "mesh/%s/%04x/s", vnd ? "v" : "s", model_key); err = bt_mesh_load_core_settings(name, (u8_t *)model->groups, sizeof(model->groups), &exist); if (err) { - BT_ERR("%s, Failed to get model subscriptions", __func__); + BT_ERR("Failed to load model subscriptions"); return -EIO; } @@ -636,14 +639,15 @@ static int model_set_pub(bool vnd, struct bt_mesh_model *model, u16_t model_key) int err = 0; if (!model->pub) { - BT_WARN("%s, Model has no publication context", __func__); + BT_INFO("Not support publication, model_id 0x%04x, cid 0x%04x", + vnd ? model->vnd.id : model->id, vnd ? model->vnd.company : 0xFFFF); return 0; } sprintf(name, "mesh/%s/%04x/p", vnd ? "v" : "s", model_key); err = bt_mesh_load_core_settings(name, (u8_t *)&pub, sizeof(pub), &exist); if (err) { - BT_WARN("%s, Cleared model publication", __func__); + BT_ERR("Failed to load model publication"); model->pub->addr = BLE_MESH_ADDR_UNASSIGNED; model->pub->key = 0U; model->pub->cred = 0U; @@ -666,7 +670,7 @@ static int model_set_pub(bool vnd, struct bt_mesh_model *model, u16_t model_key) model->pub->retransmit = pub.retransmit; model->pub->count = 0U; - BT_INFO("Restored model publication, pub_addr 0x%04x, app_idx 0x%03x", + BT_INFO("Restored Model Publication, address 0x%04x, app_idx 0x%03x", pub.addr, pub.key); return 0; @@ -697,27 +701,24 @@ static int model_set(bool vnd, const char *name) model = bt_mesh_model_get(vnd, elem_idx, model_idx); if (!model) { - BT_ERR("%s, Failed to get %s model, elem_idx %u model_idx %u", - __func__, vnd ? "vnd" : "sig", elem_idx, model_idx); + BT_ERR("%s model not found, elem_idx %u, model_idx %u", + vnd ? "vnd" : "sig", elem_idx, model_idx); err = -ENOENT; goto free; } err = model_set_bind(vnd, model, model_key); if (err) { - BT_ERR("%s, model_set_bind fail", __func__); goto free; } err = model_set_sub(vnd, model, model_key); if (err) { - BT_ERR("%s, model_set_sub fail", __func__); goto free; } err = model_set_pub(vnd, model, model_key); if (err) { - BT_ERR("%s, model_set_pub fail", __func__); goto free; } } @@ -764,7 +765,7 @@ static int va_set(const char *name) err = bt_mesh_load_core_settings(get, (u8_t *)&va, sizeof(va), &exist); if (err) { - BT_ERR("%s, Failed to load virtual address %s", __func__, get); + BT_ERR("Failed to load virtual address 0x%04x", index); goto free; } @@ -788,7 +789,7 @@ static int va_set(const char *name) lab->addr = va.addr; lab->ref = va.ref; - BT_INFO("Restored virtual address 0x%04x ref 0x%04x", index, lab->ref); + BT_INFO("Restored Virtual Address 0x%04x, ref 0x%04x", index, lab->ref); } free: @@ -808,7 +809,7 @@ static int p_prov_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&val, sizeof(val), &exist); if (err) { - BT_ERR("%s, Failed to load Provisioner prov info", __func__); + BT_ERR("Failed to load next address allocation"); return 0; } @@ -818,7 +819,7 @@ static int p_prov_set(const char *name) bt_mesh_provisoner_restore_prov_info(val.primary_addr, val.alloc_addr); - BT_INFO("Restored primary_addr 0x%04x, alloc_addr 0x%04x", + BT_INFO("Restored Primary Address 0x%04x, next address allocation 0x%04x", val.primary_addr, val.alloc_addr); return 0; @@ -834,7 +835,7 @@ static int p_net_idx_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&net_idx, sizeof(net_idx), &exist); if (err) { - BT_ERR("%s, Failed to load Provisioner keys", __func__); + BT_ERR("Failed to load next net_idx allocation"); return 0; } @@ -844,7 +845,7 @@ static int p_net_idx_set(const char *name) bt_mesh.p_net_idx_next = net_idx; - BT_INFO("Restored p_net_idx_next 0x%04x", bt_mesh.p_net_idx_next); + BT_INFO("Restored next NetKey Index allocation 0x%03x", bt_mesh.p_net_idx_next); return 0; } @@ -859,6 +860,7 @@ static int p_app_idx_set(const char *name) err = bt_mesh_load_core_settings(name, (u8_t *)&app_idx, sizeof(app_idx), &exist); if (err) { + BT_ERR("Failed to load next app_idx allocation"); return 0; } @@ -868,7 +870,7 @@ static int p_app_idx_set(const char *name) bt_mesh.p_app_idx_next = app_idx; - BT_INFO("Restored p_app_idx_next 0x%04x", bt_mesh.p_app_idx_next); + BT_INFO("Restored next AppKey Index allocation 0x%03x", bt_mesh.p_app_idx_next); return 0; } @@ -937,7 +939,7 @@ static int p_net_key_set(const char *name) err = bt_mesh_load_core_settings(get, (u8_t *)&key, sizeof(key), &exist); if (err) { - BT_ERR("%s, Failed to load Provisioner NetKey %s", __func__, get); + BT_ERR("%s, Failed to load NetKey 0x%03x", __func__, net_idx); goto free; } @@ -961,7 +963,7 @@ static int p_net_key_set(const char *name) memcpy(sub->keys[0].net, &key.val[0], 16); memcpy(sub->keys[1].net, &key.val[1], 16); - BT_INFO("Restored NetIdx 0x%03x", sub->net_idx); + BT_INFO("Restored NetKey Index 0x%03x", sub->net_idx); BT_INFO("Restored NetKey %s", bt_hex(sub->keys[0].net, 16)); } @@ -997,7 +999,7 @@ static int p_app_key_set(const char *name) err = bt_mesh_load_core_settings(get, (u8_t *)&key, sizeof(key), &exist); if (err) { - BT_ERR("%s, Failed to load Provisioner AppKey %s", __func__, get); + BT_ERR("%s, Failed to load AppKey 0x%03x", __func__, app_idx); goto free; } @@ -1030,7 +1032,8 @@ static int p_app_key_set(const char *name) bt_mesh_app_id(app->keys[0].val, &app->keys[0].id); bt_mesh_app_id(app->keys[1].val, &app->keys[1].id); - BT_INFO("Restored AppIdx %03x, NetIdx 0x%03x", app->app_idx, app->net_idx); + BT_INFO("Restored AppKey Index 0x%03x, NetKey Index 0x%03x", + app->app_idx, app->net_idx); BT_INFO("Restored AppKey %s", bt_hex(app->keys[0].val, 16)); } @@ -1049,7 +1052,7 @@ static int node_info_set(u16_t addr, bool *exist) sprintf(get, "mesh/pn/%04x/i", addr); err = bt_mesh_load_core_settings(get, (u8_t *)&info, sizeof(info), exist); if (err) { - BT_ERR("%s, Failed to load node %s", __func__, get); + BT_ERR("Failed to load node 0x%04x info", addr); return -EIO; } @@ -1070,11 +1073,11 @@ static int node_info_set(u16_t addr, bool *exist) err = bt_mesh_provisioner_restore_node_info(&node); if (err) { - BT_ERR("%s, Failed to restore node 0x%04x", __func__, addr); + BT_ERR("Failed to restore node 0x%04x info", addr); return -EIO; } - BT_INFO("Restored node 0x%04x, uuid %s", addr, bt_hex(node.dev_uuid, 16)); + BT_INFO("Restored Node 0x%04x, UUID %s", addr, bt_hex(node.dev_uuid, 16)); return 0; } @@ -1089,7 +1092,7 @@ static int node_name_set(u16_t addr) sprintf(get, "mesh/pn/%04x/n", addr); err = bt_mesh_load_core_settings(get, (u8_t *)name, BLE_MESH_NODE_NAME_SIZE, &exist); if (err) { - BT_ERR("%s, Failed to load node name %s", __func__, get); + BT_ERR("Failed to load node 0x%04x name", addr); return -EIO; } @@ -1099,11 +1102,11 @@ static int node_name_set(u16_t addr) err = bt_mesh_provisioner_restore_node_name(addr, name); if (err) { - BT_ERR("%s, Failed to restore node name 0x%04x", __func__, addr); + BT_ERR("Failed to restore node 0x%04x name", addr); return -EIO; } - BT_INFO("Restored node 0x%04x, name %s", addr, name); + BT_INFO("Restored Node 0x%04x, Name %s", addr, name); return 0; } @@ -1122,11 +1125,11 @@ static int node_comp_data_set(u16_t addr) err = bt_mesh_provisioner_restore_node_comp_data(addr, buf->data, buf->len); if (err) { - BT_ERR("%s, Failed to restore node comp data 0x%04x", __func__, addr); + BT_ERR("Failed to restore node 0x%04x comp data", addr); + } else { + BT_INFO("Restored Node 0x%04x, Composition Data %s", addr, bt_hex(buf->data, buf->len)); } - BT_INFO("Restored node 0x%04x, comp data %s", addr, bt_hex(buf->data, buf->len)); - bt_mesh_free_buf(buf); return err; } @@ -1136,7 +1139,6 @@ static int p_node_set(const char *name) struct net_buf_simple *buf = NULL; bool exist = false; size_t length = 0U; - int err = 0; int i; buf = bt_mesh_get_core_settings_item(name); @@ -1153,9 +1155,7 @@ static int p_node_set(const char *name) continue; } - err = node_info_set(addr, &exist); - if (err) { - BT_ERR("%s, Failed to load node 0x%04x info", __func__, addr); + if (node_info_set(addr, &exist)) { continue; } @@ -1163,21 +1163,17 @@ static int p_node_set(const char *name) continue; } - err = node_name_set(addr); - if (err) { - BT_ERR("%s, Failed to load node 0x%04x name", __func__, addr); + if (node_name_set(addr)) { continue; } - err = node_comp_data_set(addr); - if (err) { - BT_ERR("%s, Failed to load node 0x%04x comp data", __func__, addr); + if (node_comp_data_set(addr)) { continue; } } bt_mesh_free_buf(buf); - return err; + return 0; } #endif /* CONFIG_BLE_MESH_PROVISIONER */ @@ -1247,7 +1243,7 @@ int settings_core_load(void) !strcmp(settings[i].name, "mesh/p_appkey") || !strcmp(settings[i].name, "mesh/p_node")) && (!IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) || bt_mesh_is_node())) { - BT_DBG("Not restoring %s for node", settings[i].name); + BT_DBG("Not restoring %s for Node", settings[i].name); continue; } @@ -1255,12 +1251,18 @@ int settings_core_load(void) if (!strcmp(settings[i].name, "mesh/role")) { u8_t role = bt_mesh_atomic_get(bt_mesh.flags) & DEVICE_ROLE_BITS; - if (role == 0U) { - BT_INFO("Device just starts up, nothing restored"); + switch (role) { + case 0U: + BT_INFO("Mesh device just starts up, no restore"); return 0; - } - if (role != BIT(BLE_MESH_NODE) && role != BIT(BLE_MESH_PROVISIONER)) { - BT_ERR("Invalid restored device role %d", role); + case BIT(BLE_MESH_NODE): + BT_INFO("Restored mesh device role: Node"); + break; + case BIT(BLE_MESH_PROVISIONER): + BT_INFO("Restored mesh device role: Provisioner"); + break; + default: + BT_ERR("Restored mesh device role: Unknown"); return 0; } } @@ -1475,7 +1477,7 @@ static void store_pending_net(void) { struct net_val net = {0}; - BT_DBG("addr 0x%04x DevKey %s", bt_mesh_primary_addr(), + BT_DBG("Primary address 0x%04x DevKey %s", bt_mesh_primary_addr(), bt_hex(bt_mesh.dev_key, 16)); net.primary_addr = bt_mesh_primary_addr(); @@ -1526,9 +1528,7 @@ static void store_pending_seq(void) { struct seq_val seq = {0}; - seq.val[0] = bt_mesh.seq; - seq.val[1] = bt_mesh.seq >> 8; - seq.val[2] = bt_mesh.seq >> 16; + sys_put_le24(bt_mesh.seq, seq.val); bt_mesh_save_core_settings("mesh/seq", (const u8_t *)&seq, sizeof(seq)); } @@ -1562,13 +1562,13 @@ static void store_rpl(struct bt_mesh_rpl *entry) sprintf(name, "mesh/rpl/%04x", entry->src); err = bt_mesh_save_core_settings(name, (const u8_t *)&rpl, sizeof(rpl)); if (err) { - BT_ERR("%s, Failed to save RPL %s", __func__, name); + BT_ERR("Failed to store RPL entry 0x%04x", entry->src); return; } err = bt_mesh_add_core_settings_item("mesh/rpl", entry->src); if (err) { - BT_ERR("%s, Failed to add 0x%04x to mesh/rpl", __func__, entry->src); + BT_ERR("Failed to add 0x%04x to mesh/rpl", entry->src); } return; @@ -1588,7 +1588,6 @@ static void clear_rpl(void) buf = bt_mesh_get_core_settings_item("mesh/rpl"); if (!buf) { - BT_WARN("%s, Erase RPL", __func__); bt_mesh_save_core_settings("mesh/rpl", NULL, 0); return; } @@ -1629,7 +1628,7 @@ static void store_pending_hb_pub(void) struct hb_pub_val val = {0}; if (!hb_pub) { - BT_WARN("%s, NULL hb_pub", __func__); + BT_WARN("NULL heartbeat publication"); return; } @@ -1649,7 +1648,7 @@ static void store_pending_cfg(void) struct cfg_val val = {0}; if (!cfg) { - BT_WARN("%s, NULL cfg", __func__); + BT_WARN("NULL configuration state"); return; } @@ -1682,7 +1681,7 @@ static void clear_app_key(u16_t app_idx) err = bt_mesh_remove_core_settings_item("mesh/appkey", app_idx); if (err) { - BT_ERR("%s, Failed to remove 0x%04x from mesh/appkey", __func__, app_idx); + BT_ERR("%s, Failed to remove 0x%03x from mesh/appkey", __func__, app_idx); } return; @@ -1700,7 +1699,7 @@ static void clear_net_key(u16_t net_idx) err = bt_mesh_remove_core_settings_item("mesh/netkey", net_idx); if (err) { - BT_ERR("%s, Failed to remove 0x%04x from mesh/netkey", __func__, net_idx); + BT_ERR("%s, Failed to remove 0x%03x from mesh/netkey", __func__, net_idx); } return; @@ -1723,13 +1722,13 @@ static void store_net_key(struct bt_mesh_subnet *sub) sprintf(name, "mesh/nk/%04x", sub->net_idx); err = bt_mesh_save_core_settings(name, (const u8_t *)&key, sizeof(key)); if (err) { - BT_ERR("%s, Failed to save NetKey %s", __func__, name); + BT_ERR("%s, Failed to store NetKey 0x%03x", __func__, sub->net_idx); return; } err = bt_mesh_add_core_settings_item("mesh/netkey", sub->net_idx); if (err) { - BT_ERR("%s, Failed to add 0x%04x to mesh/netkey", __func__, sub->net_idx); + BT_ERR("Failed to add 0x%03x to mesh/netkey", sub->net_idx); } return; @@ -1749,13 +1748,13 @@ static void store_app_key(struct bt_mesh_app_key *app) sprintf(name, "mesh/ak/%04x", app->app_idx); err = bt_mesh_save_core_settings(name, (const u8_t *)&key, sizeof(key)); if (err) { - BT_ERR("%s, Failed to save AppKey %s", __func__, name); + BT_ERR("%s, Failed to store AppKey 0x%03x", __func__, app->app_idx); return; } err = bt_mesh_add_core_settings_item("mesh/appkey", app->app_idx); if (err) { - BT_ERR("%s, Failed to add 0x%04x to mesh/appkey", __func__, app->app_idx); + BT_ERR("Failed to add 0x%03x to mesh/appkey", app->app_idx); } return; @@ -1820,14 +1819,14 @@ static void store_pending_mod_bind(struct bt_mesh_model *model, bool vnd) err = bt_mesh_save_core_settings(name, (const u8_t *)model->keys, sizeof(model->keys)); if (err) { - BT_ERR("%s, Failed to save %s", __func__, name); + BT_ERR("Failed to store %s", name); return; } err = bt_mesh_add_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key); if (err) { - BT_ERR("%s, Failed to add 0x%04x to %s", __func__, model_key, - vnd ? "mesh/vnd" : "mesh/sig"); + BT_ERR("Failed to add bound key to %s, model_key 0x%04x", + vnd ? "mesh/vnd" : "mesh/sig", model_key); } return; @@ -1851,14 +1850,14 @@ static void store_pending_mod_sub(struct bt_mesh_model *model, bool vnd) err = bt_mesh_save_core_settings(name, (const u8_t *)model->groups, sizeof(model->groups)); if (err) { - BT_ERR("%s, Failed to save %s", __func__, name); + BT_ERR("Failed to store %s", name); return; } err = bt_mesh_add_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key); if (err) { - BT_ERR("%s, Failed to add 0x%04x to %s", __func__, model_key, - vnd ? "mesh/vnd" : "mesh/sig"); + BT_ERR("Failed to add subscription to %s, model_key 0x%04x", + vnd ? "mesh/vnd" : "mesh/sig", model_key); } return; @@ -1872,7 +1871,7 @@ static void store_pending_mod_pub(struct bt_mesh_model *model, bool vnd) int err = 0; if (!model->pub) { - BT_WARN("%s, No model publication to store", __func__); + BT_WARN("Model has no publication support"); return; } @@ -1896,14 +1895,14 @@ static void store_pending_mod_pub(struct bt_mesh_model *model, bool vnd) err = bt_mesh_save_core_settings(name, (const u8_t *)&pub, sizeof(pub)); if (err) { - BT_ERR("%s, Failed to save %s", __func__, name); + BT_ERR("Failed to store %s", name); return; } err = bt_mesh_add_core_settings_item(vnd ? "mesh/vnd" : "mesh/sig", model_key); if (err) { - BT_ERR("%s, Failed to add 0x%04x to %s", __func__, model_key, - vnd ? "mesh/vnd" : "mesh/sig"); + BT_ERR("Failed to add publication to %s, model_key 0x%04x", + vnd ? "mesh/vnd" : "mesh/sig", model_key); } return; @@ -1959,7 +1958,7 @@ static void store_pending_va(void) err = bt_mesh_save_core_settings(name, (const u8_t *)&va, sizeof(va)); } if (err) { - BT_ERR("%s, Failed to %s virtual address %s", __func__, + BT_ERR("Failed to %s virtual address %s", IS_VA_DEL(lab) ? "delete" : "store", name); return; } @@ -1970,7 +1969,7 @@ static void store_pending_va(void) err = bt_mesh_add_core_settings_item("mesh/vaddr", i); } if (err) { - BT_ERR("%s, Failed to %s 0x%04x in mesh/vaddr", __func__, + BT_ERR("Failed to %s 0x%04x in mesh/vaddr", IS_VA_DEL(lab) ? "delete" : "store", i); return; } @@ -2256,7 +2255,7 @@ void bt_mesh_store_prov_info(u16_t primary_addr, u16_t alloc_addr) { struct prov_info val = {0}; - BT_DBG("primary_addr 0x%04x, alloc_addr 0x%04x", primary_addr, alloc_addr); + BT_DBG("Primary address 0x%04x, next address allocation 0x%04x", primary_addr, alloc_addr); val.primary_addr = primary_addr; val.alloc_addr = alloc_addr; @@ -2279,7 +2278,7 @@ static void clear_p_net_key(u16_t net_idx) err = bt_mesh_remove_core_settings_item("mesh/p_netkey", net_idx); if (err) { - BT_ERR("%s, Failed to remove 0x%04x from mesh/p_netkey", __func__, net_idx); + BT_ERR("Failed to remove 0x%03x from mesh/p_netkey", net_idx); } } @@ -2293,7 +2292,7 @@ static void clear_p_app_key(u16_t app_idx) err = bt_mesh_remove_core_settings_item("mesh/p_appkey", app_idx); if (err) { - BT_ERR("%s, Failed to remove 0x%03x from mesh/p_appkey", __func__, app_idx); + BT_ERR("Failed to remove 0x%03x from mesh/p_appkey", app_idx); } } @@ -2311,13 +2310,13 @@ static void store_p_net_key(struct bt_mesh_subnet *sub) sprintf(name, "mesh/pnk/%04x", sub->net_idx); err = bt_mesh_save_core_settings(name, (const u8_t *)&key, sizeof(key)); if (err) { - BT_ERR("%s, Failed to save NetKey %s", __func__, name); + BT_ERR("%s, Failed to store NetKey 0x%03x", __func__, sub->net_idx); return; } err = bt_mesh_add_core_settings_item("mesh/p_netkey", sub->net_idx); if (err) { - BT_ERR("%s, Failed to add 0x%04x to mesh/p_netkey", __func__, sub->net_idx); + BT_ERR("Failed to add 0x%03x to mesh/p_netkey", sub->net_idx); } } @@ -2335,13 +2334,13 @@ static void store_p_app_key(struct bt_mesh_app_key *app) sprintf(name, "mesh/pak/%04x", app->app_idx); err = bt_mesh_save_core_settings(name, (const u8_t *)&key, sizeof(key)); if (err) { - BT_ERR("%s, Failed to save AppKey %s", __func__, name); + BT_ERR("%s, Failed to store AppKey 0x%03x", __func__, app->app_idx); return; } err = bt_mesh_add_core_settings_item("mesh/p_appkey", app->app_idx); if (err) { - BT_ERR("%s, Failed to add 0x%04x to mesh/p_appkey", __func__, app->app_idx); + BT_ERR("Failed to add 0x%03x to mesh/p_appkey", app->app_idx); } } @@ -2436,7 +2435,7 @@ void bt_mesh_clear_rpl_single(u16_t src) err = bt_mesh_remove_core_settings_item("mesh/rpl", src); if (err) { - BT_ERR("%s, Failed to remove 0x%04x from mesh/rpl", __func__, src); + BT_ERR("Failed to remove 0x%04x from mesh/rpl", src); } } @@ -2465,13 +2464,13 @@ void bt_mesh_store_node_info(struct bt_mesh_node *node) sprintf(name, "mesh/pn/%04x/i", node->unicast_addr); err = bt_mesh_save_core_settings(name, (const u8_t *)&val, sizeof(val)); if (err) { - BT_ERR("%s, Failed to save node %s", __func__, name); + BT_ERR("Failed to store node 0x%04x info", node->unicast_addr); return; } err = bt_mesh_add_core_settings_item("mesh/p_node", node->unicast_addr); if (err) { - BT_ERR("%s, Failed to add node 0x%04x", __func__, node->unicast_addr); + BT_ERR("Failed to add node 0x%04x info", node->unicast_addr); } } @@ -2494,7 +2493,7 @@ static void clear_node(u16_t addr) err = bt_mesh_remove_core_settings_item("mesh/p_node", addr); if (err) { - BT_ERR("%s, Failed to remove node 0x%04x", __func__, addr); + BT_ERR("Failed to remove node 0x%04x", addr); } } @@ -2526,7 +2525,7 @@ void bt_mesh_store_node_name(struct bt_mesh_node *node) sprintf(name, "mesh/pn/%04x/n", node->unicast_addr); err = bt_mesh_save_core_settings(name, (const u8_t *)node_name, BLE_MESH_NODE_NAME_SIZE); if (err) { - BT_ERR("%s, Failed to save node name %s", __func__, name); + BT_ERR("Failed to store node 0x%04x name", node->unicast_addr); } } @@ -2543,7 +2542,7 @@ void bt_mesh_store_node_comp_data(struct bt_mesh_node *node) sprintf(name, "mesh/pn/%04x/c", node->unicast_addr); err = bt_mesh_save_core_settings(name, (const u8_t *)node->comp_data, node->comp_length); if (err) { - BT_ERR("%s, Failed to save node comp data %s", __func__, name); + BT_ERR("Failed to store node 0x%04x comp data", node->unicast_addr); } } #endif /* CONFIG_BLE_MESH_PROVISIONER */ diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index bb8a1cc54..56112c040 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -40,7 +40,7 @@ _Static_assert(CONFIG_BLE_MESH_ADV_BUF_COUNT >= (CONFIG_BLE_MESH_TX_SEG_MAX + 3) #define AID(data) ((data)[0] & AID_MASK) #define ASZMIC(data) (((data)[1] >> 7) & 1) -#define APP_MIC_LEN(aszmic) ((aszmic) ? 8 : 4) +#define APP_MIC_LEN(aszmic) ((aszmic) ? BLE_MESH_MIC_LONG : BLE_MESH_MIC_SHORT) #define UNSEG_HDR(akf, aid) ((akf << 6) | (aid & AID_MASK)) #define SEG_HDR(akf, aid) (UNSEG_HDR(akf, aid) | 0x80) @@ -56,7 +56,17 @@ _Static_assert(CONFIG_BLE_MESH_ADV_BUF_COUNT >= (CONFIG_BLE_MESH_TX_SEG_MAX + 3) * We use 400 since 300 is a common send duration for standard HCI, and we * need to have a timeout that's bigger than that. */ -#define SEG_RETRANSMIT_TIMEOUT(tx) (K_MSEC(400) + 50 * (tx)->ttl) +#define SEG_RETRANSMIT_TIMEOUT_UNICAST(tx) (K_MSEC(400) + 50 * (tx)->ttl) +/* When sending to a group, the messages are not acknowledged, and there's no + * reason to delay the repetitions significantly. Delaying by more than 0 ms + * to avoid flooding the network. + */ +#define SEG_RETRANSMIT_TIMEOUT_GROUP K_MSEC(50) + +#define SEG_RETRANSMIT_TIMEOUT(tx) \ + (BLE_MESH_ADDR_IS_UNICAST((tx)->dst) ? \ + SEG_RETRANSMIT_TIMEOUT_UNICAST(tx) : \ + SEG_RETRANSMIT_TIMEOUT_GROUP) /* How long to wait for available buffers before giving up */ #define BUF_TIMEOUT K_NO_WAIT @@ -66,10 +76,12 @@ static struct seg_tx { struct net_buf *seg[CONFIG_BLE_MESH_TX_SEG_MAX]; u64_t seq_auth; u16_t dst; - u8_t seg_n: 5, /* Last segment index */ - new_key: 1; /* New/old key */ + u8_t seg_n:5, /* Last segment index */ + new_key:1; /* New/old key */ u8_t nack_count; /* Number of unacked segs */ u8_t ttl; + u8_t seg_pending:5, /* Number of segments pending */ + attempts:3; const struct bt_mesh_send_cb *cb; void *cb_data; struct k_delayed_work retransmit; /* Retransmit timer */ @@ -102,6 +114,7 @@ static u8_t seg_rx_buf_data[(CONFIG_BLE_MESH_RX_SEG_MSG_COUNT * static u16_t hb_sub_dst = BLE_MESH_ADDR_UNASSIGNED; static bt_mesh_mutex_t tx_seg_lock; +static bt_mesh_mutex_t rx_seg_lock; static void bt_mesh_tx_seg_mutex_new(void) { @@ -125,6 +138,28 @@ static void bt_mesh_tx_seg_unlock(void) bt_mesh_mutex_unlock(&tx_seg_lock); } +static void bt_mesh_rx_seg_mutex_new(void) +{ + if (!rx_seg_lock.mutex) { + bt_mesh_mutex_create(&rx_seg_lock); + } +} + +static void bt_mesh_rx_seg_mutex_free(void) +{ + bt_mesh_mutex_free(&rx_seg_lock); +} + +static void bt_mesh_rx_seg_lock(void) +{ + bt_mesh_mutex_lock(&rx_seg_lock); +} + +static void bt_mesh_rx_seg_unlock(void) +{ + bt_mesh_mutex_unlock(&rx_seg_lock); +} + u8_t bt_mesh_get_seg_retrans_num(void) { return SEG_RETRANSMIT_ATTEMPTS; @@ -132,10 +167,16 @@ u8_t bt_mesh_get_seg_retrans_num(void) s32_t bt_mesh_get_seg_retrans_timeout(u8_t ttl) { + /* This function will be used when a client model sending an + * acknowledged message. And if the dst of a message is not + * a unicast address, the function will not be invoked. + * So we can directly use the SEG_RETRANSMIT_TIMEOUT_UNICAST + * macro here. + */ struct seg_tx tx = { .ttl = ttl, }; - return SEG_RETRANSMIT_TIMEOUT(&tx); + return SEG_RETRANSMIT_TIMEOUT_UNICAST(&tx); } void bt_mesh_set_hb_sub_dst(u16_t addr) @@ -210,10 +251,22 @@ bool bt_mesh_tx_in_progress(void) return false; } +static void seg_tx_done(struct seg_tx *tx, u8_t seg_idx) +{ + bt_mesh_adv_buf_ref_debug(__func__, tx->seg[seg_idx], 3U, BLE_MESH_BUF_REF_SMALL); + + BLE_MESH_ADV(tx->seg[seg_idx])->busy = 0U; + net_buf_unref(tx->seg[seg_idx]); + tx->seg[seg_idx] = NULL; + tx->nack_count--; +} + static void seg_tx_reset(struct seg_tx *tx) { int i; + bt_mesh_tx_seg_lock(); + k_delayed_work_cancel(&tx->retransmit); tx->cb = NULL; @@ -222,21 +275,12 @@ static void seg_tx_reset(struct seg_tx *tx) tx->sub = NULL; tx->dst = BLE_MESH_ADDR_UNASSIGNED; - if (!tx->nack_count) { - return; - } - - bt_mesh_tx_seg_lock(); - - for (i = 0; i <= tx->seg_n; i++) { + for (i = 0; i <= tx->seg_n && tx->nack_count; i++) { if (!tx->seg[i]) { continue; } - bt_mesh_adv_buf_ref_debug(__func__, tx->seg[i], 3U, BLE_MESH_BUF_REF_SMALL); - BLE_MESH_ADV(tx->seg[i])->busy = 0U; - net_buf_unref(tx->seg[i]); - tx->seg[i] = NULL; + seg_tx_done(tx, i); } tx->nack_count = 0U; @@ -256,11 +300,29 @@ static void seg_tx_reset(struct seg_tx *tx) static inline void seg_tx_complete(struct seg_tx *tx, int err) { - if (tx->cb && tx->cb->end) { - tx->cb->end(err, tx->cb_data); - } + const struct bt_mesh_send_cb *cb = tx->cb; + void *cb_data = tx->cb_data; seg_tx_reset(tx); + + if (cb && cb->end) { + cb->end(err, cb_data); + } +} + +static void schedule_retransmit(struct seg_tx *tx) +{ + if (--tx->seg_pending) { + return; + } + + if (!BLE_MESH_ADDR_IS_UNICAST(tx->dst) && !tx->attempts) { + BT_INFO("Complete tx sdu to group"); + seg_tx_complete(tx, 0); + return; + } + + k_delayed_work_submit(&tx->retransmit, SEG_RETRANSMIT_TIMEOUT(tx)); } static void seg_first_send_start(u16_t duration, int err, void *user_data) @@ -281,8 +343,7 @@ static void seg_send_start(u16_t duration, int err, void *user_data) * case since otherwise we risk the transmission of becoming stale. */ if (err) { - k_delayed_work_submit(&tx->retransmit, - SEG_RETRANSMIT_TIMEOUT(tx)); + schedule_retransmit(tx); } } @@ -290,8 +351,7 @@ static void seg_sent(int err, void *user_data) { struct seg_tx *tx = user_data; - k_delayed_work_submit(&tx->retransmit, - SEG_RETRANSMIT_TIMEOUT(tx)); + schedule_retransmit(tx); } static const struct bt_mesh_send_cb first_sent_cb = { @@ -310,6 +370,15 @@ static void seg_tx_send_unacked(struct seg_tx *tx) bt_mesh_tx_seg_lock(); + if (!(tx->attempts--)) { + BT_WARN("Ran out of retransmit attempts"); + bt_mesh_tx_seg_unlock(); + seg_tx_complete(tx, -ETIMEDOUT); + return; + } + + BT_INFO("Attempts: %u", tx->attempts); + for (i = 0; i <= tx->seg_n; i++) { struct net_buf *seg = tx->seg[i]; @@ -322,12 +391,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) continue; } - if (!(BLE_MESH_ADV(seg)->seg.attempts--)) { - BT_WARN("Ran out of retransmit attempts"); - bt_mesh_tx_seg_unlock(); - seg_tx_complete(tx, -ETIMEDOUT); - return; - } + tx->seg_pending++; BT_DBG("resending %u/%u", i, tx->seg_n); @@ -393,11 +457,13 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, seg_o = 0U; tx->dst = net_tx->ctx->addr; - tx->seg_n = (sdu->len - 1) / 12U; + tx->seg_n = (sdu->len - 1) / BLE_MESH_APP_SEG_SDU_MAX; 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; tx->new_key = net_tx->sub->kr_flag; + tx->attempts = SEG_RETRANSMIT_ATTEMPTS; + tx->seg_pending = 0; tx->cb = cb; tx->cb_data = cb_data; @@ -435,8 +501,6 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, return -ENOBUFS; } - BLE_MESH_ADV(seg)->seg.attempts = SEG_RETRANSMIT_ATTEMPTS; - net_buf_reserve(seg, BLE_MESH_NET_HDR_LEN); net_buf_add_u8(seg, seg_hdr); @@ -445,7 +509,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, (seg_o >> 3))); net_buf_add_u8(seg, ((seg_o & 0x07) << 5) | tx->seg_n); - len = MIN(sdu->len, 12); + len = MIN(sdu->len, BLE_MESH_APP_SEG_SDU_MAX); net_buf_add_mem(seg, sdu->data, len); net_buf_simple_pull(sdu, len); @@ -474,6 +538,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, tx->seg[seg_o] = net_buf_ref(seg); BT_DBG("Sending %u/%u", seg_o, tx->seg_n); + tx->seg_pending++; err = bt_mesh_net_send(net_tx, seg, seg_o ? &seg_sent_cb : &first_sent_cb, @@ -527,12 +592,12 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, u8_t aid = 0U; int err = 0; - if (net_buf_simple_tailroom(msg) < 4) { + if (net_buf_simple_tailroom(msg) < BLE_MESH_MIC_SHORT) { BT_ERR("%s, Insufficient tailroom for Transport MIC", __func__); return -EINVAL; } - if (msg->len > 11) { + if (msg->len > BLE_MESH_SDU_UNSEG_MAX) { tx->ctx->send_rel = 1U; } @@ -554,7 +619,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, tx->aid = aid; - if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) { + if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < BLE_MESH_MIC_LONG) { tx->aszmic = 0U; } else { tx->aszmic = 1U; @@ -696,7 +761,7 @@ static int sdu_recv(struct bt_mesh_net_rx *rx, u32_t seq, u8_t hdr, /* Use bt_mesh_alloc_buf() instead of NET_BUF_SIMPLE_DEFINE to avoid * causing btu task stackoverflow. */ - sdu = bt_mesh_alloc_buf(CONFIG_BLE_MESH_RX_SDU_MAX - 4); + sdu = bt_mesh_alloc_buf(CONFIG_BLE_MESH_RX_SDU_MAX - BLE_MESH_MIC_SHORT); if (!sdu) { BT_ERR("%s, Failed to allocate memory", __func__); return -ENOMEM; @@ -851,6 +916,11 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr, return -EINVAL; } + if (!BLE_MESH_ADDR_IS_UNICAST(tx->dst)) { + BT_WARN("%s, Received ack for segments to group", __func__); + return -EINVAL; + } + *seq_auth = tx->seq_auth; if (!ack) { @@ -869,9 +939,9 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr, while ((bit = find_lsb_set(ack))) { if (tx->seg[bit - 1]) { BT_DBG("seg %u/%u acked", bit - 1, tx->seg_n); - net_buf_unref(tx->seg[bit - 1]); - tx->seg[bit - 1] = NULL; - tx->nack_count--; + bt_mesh_tx_seg_lock(); + seg_tx_done(tx, bit - 1); + bt_mesh_tx_seg_unlock(); } ack &= ~BIT(bit - 1); @@ -1039,16 +1109,12 @@ static inline s32_t ack_timeout(struct seg_rx *rx) return MAX(to, K_MSEC(400)); } -int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, - size_t data_len, u64_t *seq_auth, - const struct bt_mesh_send_cb *cb, void *cb_data) +static int ctl_send_unseg(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, + size_t data_len, const struct bt_mesh_send_cb *cb, + void *cb_data) { struct net_buf *buf = NULL; - BT_DBG("src 0x%04x dst 0x%04x ttl 0x%02x ctl 0x%02x", tx->src, - tx->ctx->addr, tx->ctx->send_ttl, ctl_op); - BT_DBG("len %u: %s", data_len, bt_hex(data, data_len)); - buf = bt_mesh_adv_create(BLE_MESH_ADV_DATA, tx->xmit, BUF_TIMEOUT); if (!buf) { BT_ERR("%s, Out of transport buffers", __func__); @@ -1063,7 +1129,7 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { if (bt_mesh_friend_enqueue_tx(tx, BLE_MESH_FRIEND_PDU_SINGLE, - seq_auth, 1, &buf->b) && + NULL, 1, &buf->b) && BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { /* PDUs for a specific Friend should only go * out through the Friend Queue. @@ -1076,6 +1142,108 @@ int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, return bt_mesh_net_send(tx, buf, cb, cb_data); } +static int ctl_send_seg(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, + size_t data_len, const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + struct seg_tx *tx_seg = NULL; + u16_t unsent = data_len; + u16_t seq_zero = 0; + u8_t seg_o = 0; + int i; + + for (tx_seg = NULL, i = 0; i < ARRAY_SIZE(seg_tx); i++) { + if (!seg_tx[i].nack_count) { + tx_seg = &seg_tx[i]; + break; + } + } + + if (!tx_seg) { + BT_ERR("%s, No multi-segment message contexts available", __func__); + return -EBUSY; + } + + tx_seg->dst = tx->ctx->addr; + tx_seg->seg_n = (data_len - 1) / BLE_MESH_CTL_SEG_SDU_MAX; + tx_seg->nack_count = tx_seg->seg_n + 1; + tx_seg->seq_auth = SEQ_AUTH(BLE_MESH_NET_IVI_TX, bt_mesh.seq); + tx_seg->sub = tx->sub; + tx_seg->new_key = tx->sub->kr_flag; + tx_seg->attempts = SEG_RETRANSMIT_ATTEMPTS; + tx_seg->seg_pending = 0; + tx_seg->cb = cb; + tx_seg->cb_data = cb_data; + + if (tx->ctx->send_ttl == BLE_MESH_TTL_DEFAULT) { + tx_seg->ttl = bt_mesh_default_ttl_get(); + } else { + tx_seg->ttl = tx->ctx->send_ttl; + } + + seq_zero = tx_seg->seq_auth & TRANS_SEQ_ZERO_MASK; + + BT_DBG("SeqZero 0x%04x", seq_zero); + + for (seg_o = 0; seg_o <= tx_seg->seg_n; seg_o++) { + struct net_buf *seg = NULL; + u16_t len = 0; + int err = 0; + + seg = bt_mesh_adv_create(BLE_MESH_ADV_DATA, tx->xmit, + BUF_TIMEOUT); + if (!seg) { + BT_ERR("%s, Out of segment buffers", __func__); + seg_tx_reset(tx_seg); + return -ENOBUFS; + } + + net_buf_reserve(seg, BLE_MESH_NET_HDR_LEN); + + net_buf_add_u8(seg, TRANS_CTL_HDR(ctl_op, 1)); + net_buf_add_u8(seg, (tx->aszmic << 7) | seq_zero >> 6); + net_buf_add_u8(seg, (((seq_zero & 0x3f) << 2) | (seg_o >> 3))); + net_buf_add_u8(seg, ((seg_o & 0x07) << 5) | tx_seg->seg_n); + + len = MIN(unsent, BLE_MESH_CTL_SEG_SDU_MAX); + net_buf_add_mem(seg, (u8_t *)data + (data_len - unsent), len); + unsent -= len; + + tx_seg->seg[seg_o] = net_buf_ref(seg); + + BT_DBG("Sending %u/%u", seg_o, tx_seg->seg_n); + tx_seg->seg_pending++; + + err = bt_mesh_net_send(tx, seg, + seg_o ? &seg_sent_cb : &first_sent_cb, + tx_seg); + if (err) { + BT_ERR("%s, Sending segment failed", __func__); + seg_tx_reset(tx_seg); + return err; + } + } + + return 0; +} + +int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, + size_t data_len, const struct bt_mesh_send_cb *cb, + void *cb_data) +{ + BT_DBG("src 0x%04x dst 0x%04x ttl 0x%02x ctl 0x%02x", tx->src, + tx->ctx->addr, tx->ctx->send_ttl, ctl_op); + BT_DBG("len %zu: %s", data_len, bt_hex(data, data_len)); + + if (data_len <= BLE_MESH_SDU_UNSEG_MAX) { + return ctl_send_unseg(tx, ctl_op, data, data_len, + cb, cb_data); + } else { + return ctl_send_seg(tx, ctl_op, data, data_len, + cb, cb_data); + } +} + static int send_ack(struct bt_mesh_subnet *sub, u16_t src, u16_t dst, u8_t ttl, u64_t *seq_auth, u32_t block, u8_t obo) { @@ -1105,7 +1273,7 @@ static int send_ack(struct bt_mesh_subnet *sub, u16_t src, u16_t dst, * or virtual address. */ if (!BLE_MESH_ADDR_IS_UNICAST(src)) { - BT_WARN("Not sending ack for non-unicast address"); + BT_INFO("Not sending ack for non-unicast address"); return 0; } @@ -1113,13 +1281,15 @@ static int send_ack(struct bt_mesh_subnet *sub, u16_t src, u16_t dst, sys_put_be32(block, &buf[2]); return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_ACK, buf, sizeof(buf), - NULL, NULL, NULL); + NULL, NULL); } static void seg_rx_reset(struct seg_rx *rx, bool full_reset) { BT_DBG("rx %p", rx); + bt_mesh_rx_seg_lock(); + k_delayed_work_cancel(&rx->ack); if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->obo && @@ -1141,6 +1311,8 @@ static void seg_rx_reset(struct seg_rx *rx, bool full_reset) rx->src = BLE_MESH_ADDR_UNASSIGNED; rx->dst = BLE_MESH_ADDR_UNASSIGNED; } + + bt_mesh_rx_seg_unlock(); } static u32_t incomplete_timeout(struct seg_rx *rx) @@ -1169,24 +1341,37 @@ static void seg_ack(struct k_work *work) BT_DBG("rx %p", rx); + bt_mesh_rx_seg_lock(); + if (k_uptime_get_32() - rx->last > incomplete_timeout(rx)) { BT_WARN("Incomplete timer expired"); + bt_mesh_rx_seg_unlock(); seg_rx_reset(rx, false); return; } + /* Add this check in case the timeout handler is just executed + * after the seg_rx_reset() which may reset rx->sub to NULL. + */ + if (rx->sub == NULL) { + bt_mesh_rx_seg_unlock(); + return; + } + send_ack(rx->sub, rx->dst, rx->src, rx->ttl, &rx->seq_auth, rx->block, rx->obo); k_delayed_work_submit(&rx->ack, ack_timeout(rx)); + + bt_mesh_rx_seg_unlock(); } static inline u8_t seg_len(bool ctl) { if (ctl) { - return 8; + return BLE_MESH_CTL_SEG_SDU_MAX; } else { - return 12; + return BLE_MESH_APP_SEG_SDU_MAX; } } @@ -1370,7 +1555,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, } if (rx->block == BLOCK_COMPLETE(rx->seg_n)) { - BT_WARN("Got segment for already complete SDU"); + BT_INFO("Got segment for already complete SDU"); send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); @@ -1677,6 +1862,7 @@ void bt_mesh_trans_init(void) } bt_mesh_tx_seg_mutex_new(); + bt_mesh_rx_seg_mutex_new(); } void bt_mesh_trans_deinit(bool erase) @@ -1704,6 +1890,7 @@ void bt_mesh_trans_deinit(bool erase) } bt_mesh_tx_seg_mutex_free(); + bt_mesh_rx_seg_mutex_free(); } void bt_mesh_rpl_clear(void) @@ -1761,7 +1948,7 @@ void bt_mesh_heartbeat_send(void) BT_INFO("InitTTL %u feat 0x%04x", cfg->hb_pub.ttl, feat); bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), - NULL, NULL, NULL); + NULL, NULL); } int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx, diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.h b/components/bt/esp_ble_mesh/mesh_core/transport.h index 870876727..ac80273b0 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.h +++ b/components/bt/esp_ble_mesh/mesh_core/transport.h @@ -18,6 +18,9 @@ extern "C" { #define TRANS_SEQ_AUTH_NVAL 0xffffffffffffffff +#define BLE_MESH_SDU_UNSEG_MAX 11 +#define BLE_MESH_CTL_SEG_SDU_MAX 8 +#define BLE_MESH_APP_SEG_SDU_MAX 12 #define BLE_MESH_TX_SDU_MAX (CONFIG_BLE_MESH_TX_SEG_MAX * 12) #define TRANS_SEQ_ZERO_MASK ((u16_t)BIT_MASK(13)) @@ -100,8 +103,8 @@ void bt_mesh_rx_reset_single(u16_t src); void bt_mesh_tx_reset_single(u16_t dst); int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, u8_t ctl_op, void *data, - size_t data_len, u64_t *seq_auth, - const struct bt_mesh_send_cb *cb, void *cb_data); + size_t data_len, const struct bt_mesh_send_cb *cb, + void *cb_data); int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, const struct bt_mesh_send_cb *cb, void *cb_data); diff --git a/components/bt/esp_ble_mesh/mesh_models/client/client_common.c b/components/bt/esp_ble_mesh/mesh_models/client/client_common.c index 5718d5202..fe5653b7b 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/client_common.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/client_common.c @@ -22,9 +22,7 @@ #include "client_common.h" #include "mesh_common.h" -#define UNSEG_ACCESS_MSG_MAX_LEN 11 /* 11 octets (Opcode + Payload), 4 octets TransMIC */ -#define SEG_ACCESS_MSG_SEG_LEN 12 /* 12 * 32 = 384 octets (Opcode + Payload + TransMIC) */ -#define HCI_TIME_FOR_START_ADV K_MSEC(5) /* Three adv related hci commands may take 4 ~ 5ms */ +#define HCI_TIME_FOR_START_ADV K_MSEC(5) /* Three adv related hci commands may take 4 ~ 5ms */ static bt_mesh_client_node_t *bt_mesh_client_pick_node(sys_slist_t *list, u16_t tx_dst) { @@ -183,11 +181,12 @@ static s32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx, bool need_seg = false; u8_t mic_size = 0; - if (msg->len > UNSEG_ACCESS_MSG_MAX_LEN || ctx->send_rel) { + if (msg->len > BLE_MESH_SDU_UNSEG_MAX || ctx->send_rel) { need_seg = true; /* Needs segmentation */ } - mic_size = (need_seg && net_buf_simple_tailroom(msg) >= 8U) ? 8U : 4U; + mic_size = (need_seg && net_buf_simple_tailroom(msg) >= BLE_MESH_MIC_LONG) ? + BLE_MESH_MIC_LONG : BLE_MESH_MIC_SHORT; if (need_seg) { /* Based on the message length, calculate how many segments are needed. @@ -203,17 +202,14 @@ static s32_t bt_mesh_client_calc_timeout(struct bt_mesh_msg_ctx *ctx, * messages, but if there are other messages between any two retrans- * missions of the same segmented messages, then the whole time will * be longer. + * + * Since the transport behavior has been changed, i.e. start retransmit + * timer after the last segment is sent, so we can simplify the timeout + * calculation here. And the retransmit timer will be started event if + * the attempts reaches ZERO when the dst is a unicast address. */ - if (duration + HCI_TIME_FOR_START_ADV < seg_retrans_to) { - s32_t seg_duration = seg_count * (duration + HCI_TIME_FOR_START_ADV); - time = (seg_duration + seg_retrans_to) * (seg_retrans_num - 1) + seg_duration; - } else { - /* If the duration is bigger than the segment retransmit timeout - * value. In this situation, the segment retransmit timeout value - * may need to be optimized based on the "Network Transmit" value. - */ - time = seg_count * (duration + HCI_TIME_FOR_START_ADV) * seg_retrans_num; - } + s32_t seg_duration = seg_count * (duration + HCI_TIME_FOR_START_ADV); + time = (seg_duration + seg_retrans_to) * seg_retrans_num; BT_INFO("Original timeout %dms, calculated timeout %dms", timeout, time); diff --git a/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c b/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c index 3ccb43a79..0aff82eb6 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/generic_client.c @@ -15,11 +15,11 @@ #include #include +#include "btc_ble_mesh_generic_model.h" + #include "model_opcode.h" #include "generic_client.h" -#include "btc_ble_mesh_generic_model.h" - /** The following are the macro definitions of generic client * model messages length, and a message is composed of three * parts: Opcode + msg_value + MIC diff --git a/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c b/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c index ff693cf88..5ab225ab5 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/lighting_client.c @@ -15,11 +15,11 @@ #include #include +#include "btc_ble_mesh_lighting_model.h" + #include "model_opcode.h" #include "lighting_client.h" -#include "btc_ble_mesh_lighting_model.h" - /** The following are the macro definitions of lighting client * model messages length, and a message is composed of three * parts: Opcode + msg_value + MIC diff --git a/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c b/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c index 9df2e25ae..18e1e389e 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/sensor_client.c @@ -15,11 +15,11 @@ #include #include +#include "btc_ble_mesh_sensor_model.h" + #include "model_opcode.h" #include "sensor_client.h" -#include "btc_ble_mesh_sensor_model.h" - /** The following are the macro definitions of sensor client * model messages length, and a message is composed of three * parts: Opcode + msg_value + MIC diff --git a/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c b/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c index 15961d1eb..11162ae4f 100644 --- a/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c +++ b/components/bt/esp_ble_mesh/mesh_models/client/time_scene_client.c @@ -15,11 +15,11 @@ #include #include +#include "btc_ble_mesh_time_scene_model.h" + #include "model_opcode.h" #include "time_scene_client.h" -#include "btc_ble_mesh_time_scene_model.h" - /** The following are the macro definitions of time and client * scene model messages length, and a message is composed of * three parts: Opcode + msg_value + MIC diff --git a/components/bt/esp_ble_mesh/mesh_models/server/device_property.c b/components/bt/esp_ble_mesh/mesh_models/server/device_property.c index 9e8afffcd..5ef9d3968 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/device_property.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/device_property.c @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "mesh_common.h" #include "server_common.h" #include "device_property.h" diff --git a/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c b/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c index 79f7c08eb..f390191eb 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/generic_server.c @@ -8,14 +8,14 @@ #include +#include "btc_ble_mesh_generic_model.h" + #include "access.h" #include "transport.h" #include "model_opcode.h" #include "state_transition.h" #include "device_property.h" -#include "btc_ble_mesh_generic_model.h" - static bt_mesh_mutex_t generic_server_lock; static void bt_mesh_generic_server_mutex_new(void) diff --git a/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c b/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c index a63de218c..e3d6e51e9 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/lighting_server.c @@ -8,14 +8,14 @@ #include +#include "btc_ble_mesh_lighting_model.h" + #include "access.h" #include "transport.h" #include "model_opcode.h" #include "state_transition.h" #include "device_property.h" -#include "btc_ble_mesh_lighting_model.h" - static bt_mesh_mutex_t light_server_lock; static void bt_mesh_light_server_mutex_new(void) diff --git a/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c b/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c index 54aac2874..5cbcb1bdc 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/sensor_server.c @@ -14,14 +14,14 @@ #include +#include "btc_ble_mesh_sensor_model.h" + #include "access.h" #include "transport.h" #include "model_opcode.h" #include "state_transition.h" #include "device_property.h" -#include "btc_ble_mesh_sensor_model.h" - static void update_sensor_periodic_pub(struct bt_mesh_model *model, u16_t prop_id); /* message handlers (Start) */ diff --git a/components/bt/esp_ble_mesh/mesh_models/server/state_binding.c b/components/bt/esp_ble_mesh/mesh_models/server/state_binding.c index 45dbadffd..9aef2081c 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/state_binding.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/state_binding.c @@ -8,6 +8,7 @@ #include +#include "mesh_common.h" #include "model_opcode.h" #include "state_binding.h" #include "state_transition.h" diff --git a/components/bt/esp_ble_mesh/mesh_models/server/state_transition.c b/components/bt/esp_ble_mesh/mesh_models/server/state_transition.c index 38c9f94fe..56871faa8 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/state_transition.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/state_transition.c @@ -6,14 +6,14 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "model_opcode.h" -#include "state_transition.h" - #include "btc_ble_mesh_generic_model.h" #include "btc_ble_mesh_lighting_model.h" #include "btc_ble_mesh_time_scene_model.h" #include "btc_ble_mesh_sensor_model.h" +#include "model_opcode.h" +#include "state_transition.h" + /* Function to calculate Remaining Time (Start) */ void bt_mesh_server_calc_remain_time(struct bt_mesh_state_transition *transition) diff --git a/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c b/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c index 78caa680f..890dcc019 100644 --- a/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c +++ b/components/bt/esp_ble_mesh/mesh_models/server/time_scene_server.c @@ -14,13 +14,13 @@ #include +#include "btc_ble_mesh_time_scene_model.h" + #include "access.h" #include "transport.h" #include "model_opcode.h" #include "state_transition.h" -#include "btc_ble_mesh_time_scene_model.h" - static bt_mesh_mutex_t time_scene_server_lock; static void bt_mesh_time_scene_server_mutex_new(void)