Merge branch 'bugfix/sync_zephyr_bt_mesh_bugfix_v4.1' into 'release/v4.1'

Bugfix/sync zephyr bt mesh bugfix (v4.1)

See merge request espressif/esp-idf!8688
This commit is contained in:
Island 2020-05-13 18:15:37 +08:00
commit 56c1646e2a
69 changed files with 2846 additions and 1472 deletions

View file

@ -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"

View file

@ -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"

View file

@ -14,8 +14,6 @@
#include <stdint.h>
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "btc_ble_mesh_prov.h"

View file

@ -14,8 +14,6 @@
#include <stdint.h>
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "btc_ble_mesh_prov.h"

View file

@ -15,8 +15,6 @@
#include <stdint.h>
#include <string.h>
#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)) {

View file

@ -15,8 +15,6 @@
#include <stdint.h>
#include <string.h>
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "btc_ble_mesh_prov.h"

View file

@ -15,8 +15,6 @@
#include <stdint.h>
#include <string.h>
#include "btc/btc_manage.h"
#include "esp_err.h"
#include "btc_ble_mesh_prov.h"

View file

@ -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. */

View file

@ -15,11 +15,9 @@
#include <string.h>
#include <errno.h>
#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

View file

@ -15,10 +15,8 @@
#include <string.h>
#include <errno.h>
#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 */

View file

@ -15,13 +15,11 @@
#include <string.h>
#include <errno.h>
#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;

View file

@ -15,10 +15,8 @@
#include <string.h>
#include <errno.h>
#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 */

View file

@ -15,10 +15,16 @@
#include <string.h>
#include <errno.h>
#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;

View file

@ -15,10 +15,8 @@
#include <string.h>
#include <errno.h>
#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 */

View file

@ -15,10 +15,8 @@
#include <string.h>
#include <errno.h>
#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 */

View file

@ -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"

View file

@ -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.

View file

@ -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_ */

View file

@ -22,13 +22,12 @@
#include <stddef.h>
#include <stdlib.h>
#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

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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__); }

View file

@ -10,6 +10,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
#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

View file

@ -15,9 +15,7 @@
#define _BLE_MESH_UTIL_H_
#include <stddef.h>
#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

View file

@ -19,7 +19,7 @@
*/
#include "mesh_atomic.h"
#include "mesh_kernel.h"
#include "mesh_mutex.h"
#ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN

View file

@ -6,10 +6,7 @@
*/
#include <string.h>
#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;

View file

@ -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);
}
}

View file

@ -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 <errno.h>
#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;
}

View file

@ -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();
}

View file

@ -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 <errno.h>
#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;
}

View file

@ -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);

View file

@ -11,14 +11,9 @@
#include <string.h>
#include <errno.h>
#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"

View file

@ -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);

View file

@ -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) ==

View file

@ -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));
}

View file

@ -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__);

View file

@ -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"

View file

@ -8,6 +8,7 @@
#ifndef _FOUNDATION_H_
#define _FOUNDATION_H_
#include "mesh_byteorder.h"
#include "net.h"
#ifdef __cplusplus

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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));

View file

@ -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;
}

View file

@ -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) {

View file

@ -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;
}

View file

@ -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)

View file

@ -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);
}

View file

@ -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 */

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -15,11 +15,11 @@
#include <string.h>
#include <errno.h>
#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

View file

@ -15,11 +15,11 @@
#include <string.h>
#include <errno.h>
#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

View file

@ -15,11 +15,11 @@
#include <string.h>
#include <errno.h>
#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

View file

@ -15,11 +15,11 @@
#include <string.h>
#include <errno.h>
#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

View file

@ -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"

View file

@ -8,14 +8,14 @@
#include <errno.h>
#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)

View file

@ -8,14 +8,14 @@
#include <errno.h>
#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)

View file

@ -14,14 +14,14 @@
#include <errno.h>
#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) */

View file

@ -8,6 +8,7 @@
#include <errno.h>
#include "mesh_common.h"
#include "model_opcode.h"
#include "state_binding.h"
#include "state_transition.h"

View file

@ -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)

View file

@ -14,13 +14,13 @@
#include <errno.h>
#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)