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:
commit
56c1646e2a
69 changed files with 2846 additions and 1472 deletions
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "btc/btc_manage.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "btc/btc_manage.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "btc_ble_mesh_prov.h"
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
|
599
components/bt/esp_ble_mesh/mesh_common/include/mesh_byteorder.h
Normal file
599
components/bt/esp_ble_mesh/mesh_common/include/mesh_byteorder.h
Normal 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_ */
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
60
components/bt/esp_ble_mesh/mesh_common/include/mesh_ffs.h
Normal file
60
components/bt/esp_ble_mesh/mesh_common/include/mesh_ffs.h
Normal 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_ */
|
|
@ -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
|
||||
|
|
58
components/bt/esp_ble_mesh/mesh_common/include/mesh_mutex.h
Normal file
58
components/bt/esp_ble_mesh/mesh_common/include/mesh_mutex.h
Normal 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_ */
|
||||
|
267
components/bt/esp_ble_mesh/mesh_common/include/mesh_timer.h
Normal file
267
components/bt/esp_ble_mesh/mesh_common/include/mesh_timer.h
Normal 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_ */
|
||||
|
|
@ -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__); }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "mesh_atomic.h"
|
||||
#include "mesh_kernel.h"
|
||||
#include "mesh_mutex.h"
|
||||
|
||||
#ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
183
components/bt/esp_ble_mesh/mesh_common/mesh_mutex.c
Normal file
183
components/bt/esp_ble_mesh/mesh_common/mesh_mutex.c
Normal 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();
|
||||
}
|
207
components/bt/esp_ble_mesh/mesh_common/mesh_timer.c
Normal file
207
components/bt/esp_ble_mesh/mesh_common/mesh_timer.c
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) ==
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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__);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef _FOUNDATION_H_
|
||||
#define _FOUNDATION_H_
|
||||
|
||||
#include "mesh_byteorder.h"
|
||||
#include "net.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <errno.h>
|
||||
|
||||
#include "mesh_common.h"
|
||||
#include "model_opcode.h"
|
||||
#include "state_binding.h"
|
||||
#include "state_transition.h"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue