Merge branch 'bugfix/sync_zephyr_v2.0_ble_mesh_fixes_v4.0' into 'release/v4.0'
ble_mesh: sync Zephyr v2.0 ble mesh fixes (v4.0) See merge request espressif/esp-idf!7300
This commit is contained in:
commit
6193a439a3
26 changed files with 1240 additions and 437 deletions
|
@ -590,8 +590,7 @@ if BLE_MESH
|
|||
endif # BLE_MESH_LOW_POWER
|
||||
|
||||
config BLE_MESH_FRIEND
|
||||
bool "Support for acting as a Friend Node"
|
||||
depends on BLE_MESH_NODE
|
||||
bool "Support for Friend feature"
|
||||
help
|
||||
Enable this option to be able to act as a Friend Node.
|
||||
|
||||
|
|
|
@ -356,16 +356,16 @@ typedef struct {
|
|||
esp_ble_mesh_model_t *model;
|
||||
|
||||
uint16_t publish_addr; /*!< Publish Address. */
|
||||
uint16_t app_idx; /*!< Publish AppKey Index. */
|
||||
uint16_t app_idx:12, /*!< Publish AppKey Index. */
|
||||
cred:1; /*!< Friendship Credentials Flag. */
|
||||
|
||||
uint8_t ttl; /*!< Publish Time to Live. */
|
||||
uint8_t retransmit; /*!< Retransmit Count & Interval Steps. */
|
||||
|
||||
uint8_t period; /*!< Publish Period. */
|
||||
uint16_t period_div: 4, /*!< Divisor for the Period. */
|
||||
cred: 1, /*!< Friendship Credentials Flag. */
|
||||
fast_period: 1, /*!< Use FastPeriodDivisor */
|
||||
count: 3; /*!< Retransmissions left. */
|
||||
uint8_t period_div:4, /*!< Divisor for the Period. */
|
||||
fast_period:1, /*!< Use FastPeriodDivisor */
|
||||
count:3; /*!< Retransmissions left. */
|
||||
|
||||
uint32_t period_start; /*!< Start of the current period. */
|
||||
|
||||
|
@ -491,6 +491,9 @@ typedef struct {
|
|||
/** Destination address of a received message. Not used for sending. */
|
||||
uint16_t recv_dst;
|
||||
|
||||
/** RSSI of received packet. Not used for sending. */
|
||||
int8_t recv_rssi;
|
||||
|
||||
/** Received TTL value. Not used for sending. */
|
||||
uint8_t recv_ttl: 7;
|
||||
|
||||
|
|
|
@ -783,7 +783,6 @@ static void btc_ble_mesh_heartbeat_msg_recv_cb(u8_t hops, u16_t feature)
|
|||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_NODE
|
||||
#if CONFIG_BLE_MESH_LOW_POWER
|
||||
static void btc_ble_mesh_lpn_cb(u16_t friend_addr, bool established)
|
||||
{
|
||||
|
@ -831,7 +830,6 @@ void btc_ble_mesh_friend_cb(bool establish, u16_t lpn_addr, u8_t reason)
|
|||
return;
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||
#endif /* CONFIG_BLE_MESH_NODE */
|
||||
|
||||
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||
static void btc_ble_mesh_proxy_client_adv_recv_cb(const bt_mesh_addr_t *addr,
|
||||
|
@ -1507,12 +1505,6 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
|
|||
arg->mesh_init.prov->link_close_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_link_close_cb;
|
||||
arg->mesh_init.prov->complete_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_complete_cb;
|
||||
arg->mesh_init.prov->reset_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_reset_cb;
|
||||
#if CONFIG_BLE_MESH_LOW_POWER
|
||||
bt_mesh_lpn_set_cb(btc_ble_mesh_lpn_cb);
|
||||
#endif /* CONFIG_BLE_MESH_LOW_POWER */
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
bt_mesh_friend_set_cb(btc_ble_mesh_friend_cb);
|
||||
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||
#endif /* CONFIG_BLE_MESH_NODE */
|
||||
#if CONFIG_BLE_MESH_PROVISIONER
|
||||
arg->mesh_init.prov->provisioner_prov_read_oob_pub_key = (esp_ble_mesh_cb_t)btc_ble_mesh_provisioner_prov_read_oob_pub_key_cb;
|
||||
|
@ -1523,6 +1515,12 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg)
|
|||
arg->mesh_init.prov->provisioner_prov_comp = (esp_ble_mesh_cb_t)btc_ble_mesh_provisioner_prov_complete_cb;
|
||||
bt_mesh_prov_adv_pkt_cb_register(btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb);
|
||||
#endif /* CONFIG_BLE_MESH_PROVISIONER */
|
||||
#if CONFIG_BLE_MESH_LOW_POWER
|
||||
bt_mesh_lpn_set_cb(btc_ble_mesh_lpn_cb);
|
||||
#endif /* CONFIG_BLE_MESH_LOW_POWER */
|
||||
#if CONFIG_BLE_MESH_FRIEND
|
||||
bt_mesh_friend_set_cb(btc_ble_mesh_friend_cb);
|
||||
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||
bt_mesh_proxy_client_set_adv_recv_cb(btc_ble_mesh_proxy_client_adv_recv_cb);
|
||||
bt_mesh_proxy_client_set_conn_cb(btc_ble_mesh_proxy_client_connect_cb);
|
||||
|
|
|
@ -168,6 +168,19 @@ static inline void net_buf_simple_reset(struct net_buf_simple *buf)
|
|||
buf->data = buf->__buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone buffer state, using the same data buffer.
|
||||
*
|
||||
* Initializes a buffer to point to the same data as an existing buffer.
|
||||
* Allows operations on the same data without altering the length and
|
||||
* offset of the original.
|
||||
*
|
||||
* @param original Buffer to clone.
|
||||
* @param clone The new clone.
|
||||
*/
|
||||
void net_buf_simple_clone(const struct net_buf_simple *original,
|
||||
struct net_buf_simple *clone);
|
||||
|
||||
/**
|
||||
* @brief Prepare data to be added at the end of the buffer
|
||||
*
|
||||
|
@ -963,6 +976,20 @@ static inline void *net_buf_user_data(struct net_buf *buf)
|
|||
*/
|
||||
#define net_buf_pull(buf, len) net_buf_simple_pull(&(buf)->b, len)
|
||||
|
||||
/**
|
||||
* @def net_buf_pull_mem
|
||||
* @brief Remove data from the beginning of the buffer.
|
||||
*
|
||||
* Removes data from the beginning of the buffer by modifying the data
|
||||
* pointer and buffer length.
|
||||
*
|
||||
* @param buf Buffer to update.
|
||||
* @param len Number of bytes to remove.
|
||||
*
|
||||
* @return Pointer to the old beginning of the buffer data.
|
||||
*/
|
||||
#define net_buf_pull_mem(buf, len) net_buf_simple_pull_mem(&(buf)->b, len)
|
||||
|
||||
/**
|
||||
* @def net_buf_pull_u8
|
||||
* @brief Remove a 8-bit value from the beginning of the buffer
|
||||
|
@ -1052,6 +1079,180 @@ static inline void *net_buf_user_data(struct net_buf *buf)
|
|||
*/
|
||||
#define net_buf_headroom(buf) net_buf_simple_headroom(&(buf)->b)
|
||||
|
||||
/**
|
||||
* @def net_buf_tail
|
||||
* @brief Get the tail pointer for a buffer.
|
||||
*
|
||||
* Get a pointer to the end of the data in a buffer.
|
||||
*
|
||||
* @param buf Buffer.
|
||||
*
|
||||
* @return Tail pointer for the buffer.
|
||||
*/
|
||||
#define net_buf_tail(buf) net_buf_simple_tail(&(buf)->b)
|
||||
|
||||
/**
|
||||
* @brief Find the last fragment in the fragment list.
|
||||
*
|
||||
* @return Pointer to last fragment in the list.
|
||||
*/
|
||||
struct net_buf *net_buf_frag_last(struct net_buf *frags);
|
||||
|
||||
/**
|
||||
* @brief Insert a new fragment to a chain of bufs.
|
||||
*
|
||||
* Insert a new fragment into the buffer fragments list after the parent.
|
||||
*
|
||||
* Note: This function takes ownership of the fragment reference so the
|
||||
* caller is not required to unref.
|
||||
*
|
||||
* @param parent Parent buffer/fragment.
|
||||
* @param frag Fragment to insert.
|
||||
*/
|
||||
void net_buf_frag_insert(struct net_buf *parent, struct net_buf *frag);
|
||||
|
||||
/**
|
||||
* @brief Add a new fragment to the end of a chain of bufs.
|
||||
*
|
||||
* Append a new fragment into the buffer fragments list.
|
||||
*
|
||||
* Note: This function takes ownership of the fragment reference so the
|
||||
* caller is not required to unref.
|
||||
*
|
||||
* @param head Head of the fragment chain.
|
||||
* @param frag Fragment to add.
|
||||
*
|
||||
* @return New head of the fragment chain. Either head (if head
|
||||
* was non-NULL) or frag (if head was NULL).
|
||||
*/
|
||||
struct net_buf *net_buf_frag_add(struct net_buf *head, struct net_buf *frag);
|
||||
|
||||
/**
|
||||
* @brief Delete existing fragment from a chain of bufs.
|
||||
*
|
||||
* @param parent Parent buffer/fragment, or NULL if there is no parent.
|
||||
* @param frag Fragment to delete.
|
||||
*
|
||||
* @return Pointer to the buffer following the fragment, or NULL if it
|
||||
* had no further fragments.
|
||||
*/
|
||||
#if defined(CONFIG_BLE_MESH_NET_BUF_LOG)
|
||||
struct net_buf *net_buf_frag_del_debug(struct net_buf *parent,
|
||||
struct net_buf *frag,
|
||||
const char *func, int line);
|
||||
#define net_buf_frag_del(_parent, _frag) \
|
||||
net_buf_frag_del_debug(_parent, _frag, __func__, __LINE__)
|
||||
#else
|
||||
struct net_buf *net_buf_frag_del(struct net_buf *parent, struct net_buf *frag);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Copy bytes from net_buf chain starting at offset to linear buffer
|
||||
*
|
||||
* Copy (extract) @a len bytes from @a src net_buf chain, starting from @a
|
||||
* offset in it, to a linear buffer @a dst. Return number of bytes actually
|
||||
* copied, which may be less than requested, if net_buf chain doesn't have
|
||||
* enough data, or destination buffer is too small.
|
||||
*
|
||||
* @param dst Destination buffer
|
||||
* @param dst_len Destination buffer length
|
||||
* @param src Source net_buf chain
|
||||
* @param offset Starting offset to copy from
|
||||
* @param len Number of bytes to copy
|
||||
* @return number of bytes actually copied
|
||||
*/
|
||||
size_t net_buf_linearize(void *dst, size_t dst_len,
|
||||
struct net_buf *src, size_t offset, size_t len);
|
||||
|
||||
/**
|
||||
* @typedef net_buf_allocator_cb
|
||||
* @brief Network buffer allocator callback.
|
||||
*
|
||||
* @details The allocator callback is called when net_buf_append_bytes
|
||||
* needs to allocate a new net_buf.
|
||||
*
|
||||
* @param timeout Affects the action taken should the net buf pool be empty.
|
||||
* If K_NO_WAIT, then return immediately. If K_FOREVER, then
|
||||
* wait as long as necessary. Otherwise, wait up to the specified
|
||||
* number of milliseconds before timing out.
|
||||
* @param user_data The user data given in net_buf_append_bytes call.
|
||||
* @return pointer to allocated net_buf or NULL on error.
|
||||
*/
|
||||
typedef struct net_buf *(*net_buf_allocator_cb)(s32_t timeout, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Append data to a list of net_buf
|
||||
*
|
||||
* @details Append data to a net_buf. If there is not enough space in the
|
||||
* net_buf then more net_buf will be added, unless there are no free net_buf
|
||||
* and timeout occurs.
|
||||
*
|
||||
* @param buf Network buffer.
|
||||
* @param len Total length of input data
|
||||
* @param value Data to be added
|
||||
* @param timeout Timeout is passed to the net_buf allocator callback.
|
||||
* @param allocate_cb When a new net_buf is required, use this callback.
|
||||
* @param user_data A user data pointer to be supplied to the allocate_cb.
|
||||
* This pointer is can be anything from a mem_pool or a net_pkt, the
|
||||
* logic is left up to the allocate_cb function.
|
||||
*
|
||||
* @return Length of data actually added. This may be less than input
|
||||
* length if other timeout than K_FOREVER was used, and there
|
||||
* were no free fragments in a pool to accommodate all data.
|
||||
*/
|
||||
size_t net_buf_append_bytes(struct net_buf *buf, size_t len,
|
||||
const void *value, s32_t timeout,
|
||||
net_buf_allocator_cb allocate_cb, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Skip N number of bytes in a net_buf
|
||||
*
|
||||
* @details Skip N number of bytes starting from fragment's offset. If the total
|
||||
* length of data is placed in multiple fragments, this function will skip from
|
||||
* all fragments until it reaches N number of bytes. Any fully skipped buffers
|
||||
* are removed from the net_buf list.
|
||||
*
|
||||
* @param buf Network buffer.
|
||||
* @param len Total length of data to be skipped.
|
||||
*
|
||||
* @return Pointer to the fragment or
|
||||
* NULL and pos is 0 after successful skip,
|
||||
* NULL and pos is 0xffff otherwise.
|
||||
*/
|
||||
static inline struct net_buf *net_buf_skip(struct net_buf *buf, size_t len)
|
||||
{
|
||||
while (buf && len--) {
|
||||
net_buf_pull_u8(buf);
|
||||
if (!buf->len) {
|
||||
buf = net_buf_frag_del(NULL, buf);
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate amount of bytes stored in fragments.
|
||||
*
|
||||
* Calculates the total amount of data stored in the given buffer and the
|
||||
* fragments linked to it.
|
||||
*
|
||||
* @param buf Buffer to start off with.
|
||||
*
|
||||
* @return Number of bytes in the buffer and its fragments.
|
||||
*/
|
||||
static inline size_t net_buf_frags_len(struct net_buf *buf)
|
||||
{
|
||||
size_t bytes = 0;
|
||||
|
||||
while (buf) {
|
||||
bytes += buf->len;
|
||||
buf = buf->frags;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,12 @@ static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool,
|
|||
return buf;
|
||||
}
|
||||
|
||||
void net_buf_simple_clone(const struct net_buf_simple *original,
|
||||
struct net_buf_simple *clone)
|
||||
{
|
||||
memcpy(clone, original, sizeof(struct net_buf_simple));
|
||||
}
|
||||
|
||||
void *net_buf_simple_add(struct net_buf_simple *buf, size_t len)
|
||||
{
|
||||
u8_t *tail = net_buf_simple_tail(buf);
|
||||
|
@ -448,3 +454,142 @@ struct net_buf *net_buf_alloc_fixed(struct net_buf_pool *pool, s32_t timeout)
|
|||
return net_buf_alloc_len(pool, fixed->data_size, timeout);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct net_buf *net_buf_frag_last(struct net_buf *buf)
|
||||
{
|
||||
NET_BUF_ASSERT(buf);
|
||||
|
||||
while (buf->frags) {
|
||||
buf = buf->frags;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void net_buf_frag_insert(struct net_buf *parent, struct net_buf *frag)
|
||||
{
|
||||
NET_BUF_ASSERT(parent);
|
||||
NET_BUF_ASSERT(frag);
|
||||
|
||||
if (parent->frags) {
|
||||
net_buf_frag_last(frag)->frags = parent->frags;
|
||||
}
|
||||
/* Take ownership of the fragment reference */
|
||||
parent->frags = frag;
|
||||
}
|
||||
|
||||
struct net_buf *net_buf_frag_add(struct net_buf *head, struct net_buf *frag)
|
||||
{
|
||||
NET_BUF_ASSERT(frag);
|
||||
|
||||
if (!head) {
|
||||
return net_buf_ref(frag);
|
||||
}
|
||||
|
||||
net_buf_frag_insert(net_buf_frag_last(head), frag);
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLE_MESH_NET_BUF_LOG)
|
||||
struct net_buf *net_buf_frag_del_debug(struct net_buf *parent,
|
||||
struct net_buf *frag,
|
||||
const char *func, int line)
|
||||
#else
|
||||
struct net_buf *net_buf_frag_del(struct net_buf *parent, struct net_buf *frag)
|
||||
#endif
|
||||
{
|
||||
struct net_buf *next_frag;
|
||||
|
||||
NET_BUF_ASSERT(frag);
|
||||
|
||||
if (parent) {
|
||||
NET_BUF_ASSERT(parent->frags);
|
||||
NET_BUF_ASSERT(parent->frags == frag);
|
||||
parent->frags = frag->frags;
|
||||
}
|
||||
|
||||
next_frag = frag->frags;
|
||||
|
||||
frag->frags = NULL;
|
||||
|
||||
#if defined(CONFIG_BLE_MESH_NET_BUF_LOG)
|
||||
net_buf_unref_debug(frag, func, line);
|
||||
#else
|
||||
net_buf_unref(frag);
|
||||
#endif
|
||||
|
||||
return next_frag;
|
||||
}
|
||||
|
||||
size_t net_buf_linearize(void *dst, size_t dst_len, struct net_buf *src,
|
||||
size_t offset, size_t len)
|
||||
{
|
||||
struct net_buf *frag;
|
||||
size_t to_copy;
|
||||
size_t copied;
|
||||
|
||||
len = MIN(len, dst_len);
|
||||
|
||||
frag = src;
|
||||
|
||||
/* find the right fragment to start copying from */
|
||||
while (frag && offset >= frag->len) {
|
||||
offset -= frag->len;
|
||||
frag = frag->frags;
|
||||
}
|
||||
|
||||
/* traverse the fragment chain until len bytes are copied */
|
||||
copied = 0;
|
||||
while (frag && len > 0) {
|
||||
to_copy = MIN(len, frag->len - offset);
|
||||
memcpy((u8_t *)dst + copied, frag->data + offset, to_copy);
|
||||
|
||||
copied += to_copy;
|
||||
|
||||
/* to_copy is always <= len */
|
||||
len -= to_copy;
|
||||
frag = frag->frags;
|
||||
|
||||
/* after the first iteration, this value will be 0 */
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
return copied;
|
||||
}
|
||||
|
||||
/* This helper routine will append multiple bytes, if there is no place for
|
||||
* the data in current fragment then create new fragment and add it to
|
||||
* the buffer. It assumes that the buffer has at least one fragment.
|
||||
*/
|
||||
size_t net_buf_append_bytes(struct net_buf *buf, size_t len,
|
||||
const void *value, s32_t timeout,
|
||||
net_buf_allocator_cb allocate_cb, void *user_data)
|
||||
{
|
||||
struct net_buf *frag = net_buf_frag_last(buf);
|
||||
size_t added_len = 0;
|
||||
const u8_t *value8 = value;
|
||||
|
||||
do {
|
||||
u16_t count = MIN(len, net_buf_tailroom(frag));
|
||||
|
||||
net_buf_add_mem(frag, value8, count);
|
||||
len -= count;
|
||||
added_len += count;
|
||||
value8 += count;
|
||||
|
||||
if (len == 0) {
|
||||
return added_len;
|
||||
}
|
||||
|
||||
frag = allocate_cb(timeout, user_data);
|
||||
if (!frag) {
|
||||
return added_len;
|
||||
}
|
||||
|
||||
net_buf_frag_add(buf, frag);
|
||||
} while (1);
|
||||
|
||||
/* Unreachable */
|
||||
return 0;
|
||||
}
|
|
@ -227,7 +227,7 @@ static s32_t next_period(struct bt_mesh_model *mod)
|
|||
|
||||
BT_DBG("Publishing took %ums", elapsed);
|
||||
|
||||
if (elapsed > period) {
|
||||
if (elapsed >= period) {
|
||||
BT_WARN("Publication sending took longer than the period");
|
||||
/* Return smallest positive number since 0 means disabled */
|
||||
return K_MSEC(1);
|
||||
|
@ -761,21 +761,21 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode)
|
|||
{
|
||||
net_buf_simple_init(msg, 0);
|
||||
|
||||
if (opcode < 0x100) {
|
||||
/* 1-byte OpCode */
|
||||
switch (BLE_MESH_MODEL_OP_LEN(opcode)) {
|
||||
case 1:
|
||||
net_buf_simple_add_u8(msg, opcode);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opcode < 0x10000) {
|
||||
/* 2-byte OpCode */
|
||||
break;
|
||||
case 2:
|
||||
net_buf_simple_add_be16(msg, opcode);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 3-byte OpCode */
|
||||
break;
|
||||
case 3:
|
||||
net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff));
|
||||
net_buf_simple_add_le16(msg, opcode & 0xffff);
|
||||
break;
|
||||
default:
|
||||
BT_WARN("Unknown opcode format");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool ready_to_send(u8_t role, u16_t dst)
|
||||
|
|
|
@ -606,7 +606,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi,
|
|||
{
|
||||
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
|
||||
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||
u16_t uuid;
|
||||
u16_t uuid = 0x0;
|
||||
#endif
|
||||
|
||||
if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) {
|
||||
|
|
|
@ -46,15 +46,10 @@ struct bt_mesh_adv {
|
|||
busy: 1;
|
||||
u8_t xmit;
|
||||
|
||||
union {
|
||||
/* Address, used e.g. for Friend Queue messages */
|
||||
u16_t addr;
|
||||
|
||||
/* For transport layer segment sending */
|
||||
struct {
|
||||
u8_t attempts;
|
||||
} seg;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#define CID_NVAL 0xffff
|
||||
|
||||
/* 2 byte dummy opcode for getting compile time buffer sizes. */
|
||||
#define DUMMY_2_BYTE_OP BLE_MESH_MODEL_OP_2(0xff, 0xff)
|
||||
|
||||
s32_t config_msg_timeout;
|
||||
|
||||
static bt_mesh_config_client_t *cli;
|
||||
|
@ -685,7 +688,7 @@ const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = {
|
|||
|
||||
int bt_mesh_cfg_comp_data_get(struct bt_mesh_msg_ctx *ctx, u8_t page)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEV_COMP_DATA_GET, 1);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -707,7 +710,7 @@ int bt_mesh_cfg_comp_data_get(struct bt_mesh_msg_ctx *ctx, u8_t page)
|
|||
|
||||
static int get_state_u8(struct bt_mesh_msg_ctx *ctx, u32_t op)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 0);
|
||||
int err;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, op);
|
||||
|
@ -723,7 +726,7 @@ static int get_state_u8(struct bt_mesh_msg_ctx *ctx, u32_t op)
|
|||
|
||||
static int set_state_u8(struct bt_mesh_msg_ctx *ctx, u32_t op, u8_t new_val)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 1);
|
||||
int err;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, op);
|
||||
|
@ -804,7 +807,7 @@ int bt_mesh_cfg_gatt_proxy_set(struct bt_mesh_msg_ctx *ctx, u8_t val)
|
|||
|
||||
int bt_mesh_cfg_relay_get(struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_GET, 0);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -826,7 +829,7 @@ int bt_mesh_cfg_relay_get(struct bt_mesh_msg_ctx *ctx)
|
|||
int bt_mesh_cfg_relay_set(struct bt_mesh_msg_ctx *ctx, u8_t new_relay,
|
||||
u8_t new_transmit)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_SET, 2);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -850,7 +853,7 @@ int bt_mesh_cfg_relay_set(struct bt_mesh_msg_ctx *ctx, u8_t new_relay,
|
|||
int bt_mesh_cfg_net_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx,
|
||||
const u8_t net_key[16])
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 18 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_ADD, 18);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !net_key) {
|
||||
|
@ -874,7 +877,7 @@ int bt_mesh_cfg_net_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx,
|
|||
int bt_mesh_cfg_app_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx,
|
||||
u16_t key_app_idx, const u8_t app_key[16])
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 1 + 19 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_ADD, 19);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !app_key) {
|
||||
|
@ -898,7 +901,7 @@ int bt_mesh_cfg_app_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx,
|
|||
int bt_mesh_cfg_mod_app_bind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
||||
u16_t mod_app_idx, u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_BIND, 8);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -926,7 +929,7 @@ int bt_mesh_cfg_mod_app_bind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
static int mod_sub(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
||||
u16_t sub_addr, u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 8);
|
||||
int err;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, op);
|
||||
|
@ -976,7 +979,7 @@ int bt_mesh_cfg_mod_sub_overwrite(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
static int mod_sub_va(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
||||
const u8_t label[16], u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 22 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 22);
|
||||
int err;
|
||||
|
||||
BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s",
|
||||
|
@ -1030,7 +1033,7 @@ int bt_mesh_cfg_mod_sub_va_overwrite(struct bt_mesh_msg_ctx *ctx, u16_t elem_add
|
|||
int bt_mesh_cfg_mod_pub_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
||||
u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_GET, 6);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1058,7 +1061,7 @@ int bt_mesh_cfg_mod_pub_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
u16_t mod_id, u16_t cid,
|
||||
struct bt_mesh_cfg_mod_pub *pub)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 13 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_SET, 13);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !pub) {
|
||||
|
@ -1090,7 +1093,7 @@ int bt_mesh_cfg_mod_pub_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
int bt_mesh_cfg_hb_sub_set(struct bt_mesh_msg_ctx *ctx,
|
||||
struct bt_mesh_cfg_hb_sub *sub)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_SET, 5);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !sub) {
|
||||
|
@ -1114,7 +1117,7 @@ int bt_mesh_cfg_hb_sub_set(struct bt_mesh_msg_ctx *ctx,
|
|||
|
||||
int bt_mesh_cfg_hb_sub_get(struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_GET, 0);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1136,7 +1139,7 @@ int bt_mesh_cfg_hb_sub_get(struct bt_mesh_msg_ctx *ctx)
|
|||
int bt_mesh_cfg_hb_pub_set(struct bt_mesh_msg_ctx *ctx,
|
||||
const struct bt_mesh_cfg_hb_pub *pub)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_SET, 9);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !pub) {
|
||||
|
@ -1163,7 +1166,7 @@ int bt_mesh_cfg_hb_pub_set(struct bt_mesh_msg_ctx *ctx,
|
|||
|
||||
int bt_mesh_cfg_hb_pub_get(struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_GET, 0);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1184,7 +1187,7 @@ int bt_mesh_cfg_hb_pub_get(struct bt_mesh_msg_ctx *ctx)
|
|||
|
||||
int bt_mesh_cfg_node_reset(struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET, 0);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1207,7 +1210,7 @@ int bt_mesh_cfg_mod_pub_va_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
u16_t mod_id, u16_t cid, const u8_t label[16],
|
||||
struct bt_mesh_cfg_mod_pub *pub)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 27 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_VA_SET, 27);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !label || !pub) {
|
||||
|
@ -1239,7 +1242,7 @@ int bt_mesh_cfg_mod_pub_va_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
int bt_mesh_cfg_mod_sub_del_all(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
||||
u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_DEL_ALL, 6);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1266,7 +1269,7 @@ int bt_mesh_cfg_mod_sub_del_all(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
static int mod_sub_get(u32_t op, struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t elem_addr, u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 6);
|
||||
int err;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, op);
|
||||
|
@ -1305,7 +1308,7 @@ int bt_mesh_cfg_mod_sub_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
int bt_mesh_cfg_net_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx,
|
||||
const u8_t net_key[16])
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 18 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_UPDATE, 18);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !net_key) {
|
||||
|
@ -1328,7 +1331,7 @@ int bt_mesh_cfg_net_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx,
|
|||
|
||||
int bt_mesh_cfg_net_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_DEL, 2);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1350,7 +1353,7 @@ int bt_mesh_cfg_net_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx)
|
|||
|
||||
int bt_mesh_cfg_net_key_get(struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_GET, 0);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1372,7 +1375,7 @@ int bt_mesh_cfg_net_key_get(struct bt_mesh_msg_ctx *ctx)
|
|||
int bt_mesh_cfg_app_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx,
|
||||
u16_t app_idx, const u8_t app_key[16])
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 1 + 19 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_UPDATE, 19);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr || !app_key) {
|
||||
|
@ -1395,7 +1398,7 @@ int bt_mesh_cfg_app_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx,
|
|||
|
||||
int bt_mesh_cfg_app_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u16_t app_idx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_DEL, 3);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1417,7 +1420,7 @@ int bt_mesh_cfg_app_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u16_t
|
|||
|
||||
int bt_mesh_cfg_app_key_get(struct bt_mesh_msg_ctx *ctx, u16_t net_idx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_GET, 2);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1440,7 +1443,7 @@ int bt_mesh_cfg_app_key_get(struct bt_mesh_msg_ctx *ctx, u16_t net_idx)
|
|||
static int node_identity_op(u32_t op, struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t net_idx, u8_t identity)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 3);
|
||||
int err;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, op);
|
||||
|
@ -1477,7 +1480,7 @@ int bt_mesh_cfg_node_identity_set(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8
|
|||
int bt_mesh_cfg_mod_app_unbind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
||||
u16_t app_idx, u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_UNBIND, 8);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -1505,7 +1508,7 @@ int bt_mesh_cfg_mod_app_unbind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
static int mod_app_get(u32_t op, struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t elem_addr, u16_t mod_id, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 6);
|
||||
int err;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, op);
|
||||
|
@ -1544,7 +1547,7 @@ int bt_mesh_cfg_mod_app_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
|||
static int kr_phase_op(u32_t op, struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t net_idx, u8_t transition)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 3);
|
||||
int err;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, op);
|
||||
|
@ -1580,7 +1583,7 @@ int bt_mesh_cfg_kr_phase_set(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8_t tr
|
|||
|
||||
int bt_mesh_cfg_lpn_timeout_get(struct bt_mesh_msg_ctx *ctx, u16_t lpn_addr)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_GET, 2);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
|
|
@ -47,11 +47,7 @@
|
|||
|
||||
static struct bt_mesh_cfg_srv *conf;
|
||||
|
||||
static struct label {
|
||||
u16_t ref;
|
||||
u16_t addr;
|
||||
u8_t uuid[16];
|
||||
} labels[CONFIG_BLE_MESH_LABEL_COUNT];
|
||||
static struct label labels[CONFIG_BLE_MESH_LABEL_COUNT];
|
||||
|
||||
static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
|
||||
bool primary)
|
||||
|
@ -451,7 +447,7 @@ static void app_key_add(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
|
||||
u16_t key_net_idx, key_app_idx;
|
||||
u8_t status;
|
||||
|
||||
|
@ -486,7 +482,7 @@ static void app_key_update(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
|
||||
u16_t key_net_idx, key_app_idx;
|
||||
u8_t status;
|
||||
|
||||
|
@ -549,7 +545,7 @@ static void app_key_del(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4);
|
||||
u16_t key_net_idx, key_app_idx;
|
||||
struct bt_mesh_app_key *key;
|
||||
u8_t status;
|
||||
|
@ -607,8 +603,8 @@ static void app_key_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4 +
|
||||
IDX_LEN(CONFIG_BLE_MESH_APP_KEY_COUNT));
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_LIST,
|
||||
3 + IDX_LEN(CONFIG_BLE_MESH_APP_KEY_COUNT));
|
||||
u16_t get_idx, i, prev;
|
||||
u8_t status;
|
||||
|
||||
|
@ -666,8 +662,7 @@ static void beacon_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
|
||||
|
||||
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,
|
||||
|
@ -685,8 +680,7 @@ static void beacon_set(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
|
||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
||||
|
@ -728,8 +722,7 @@ static void default_ttl_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
|
||||
|
||||
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,
|
||||
|
@ -747,8 +740,7 @@ static void default_ttl_set(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
|
||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
||||
|
@ -781,8 +773,7 @@ static void default_ttl_set(struct bt_mesh_model *model,
|
|||
static void send_gatt_proxy_status(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1);
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS);
|
||||
net_buf_simple_add_u8(&msg, bt_mesh_gatt_proxy_get());
|
||||
|
@ -878,8 +869,7 @@ static void net_transmit_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
|
||||
|
||||
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,
|
||||
|
@ -897,8 +887,7 @@ static void net_transmit_set(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
|
||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
||||
|
@ -931,8 +920,7 @@ static void relay_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
|
||||
|
||||
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,
|
||||
|
@ -951,8 +939,7 @@ static void relay_set(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
|
||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||
|
||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
||||
|
@ -1005,8 +992,7 @@ static void send_mod_pub_status(struct bt_mesh_model *cfg_mod,
|
|||
bool vnd, struct bt_mesh_model *mod,
|
||||
u8_t status, u8_t *mod_id)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 14 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14);
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS);
|
||||
|
||||
|
@ -1162,25 +1148,61 @@ send_status:
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LABEL_COUNT > 0
|
||||
static u8_t va_add(u8_t *label_uuid, u16_t *addr)
|
||||
struct label *get_label(u16_t index)
|
||||
{
|
||||
struct label *free_slot = NULL;
|
||||
if (index >= ARRAY_SIZE(labels)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &labels[index];
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LABEL_COUNT > 0
|
||||
static inline void va_store(struct label *store)
|
||||
{
|
||||
bt_mesh_atomic_set_bit(store->flags, BLE_MESH_VA_CHANGED);
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) {
|
||||
bt_mesh_store_label();
|
||||
}
|
||||
}
|
||||
|
||||
static struct label *va_find(const u8_t *label_uuid,
|
||||
struct label **free_slot)
|
||||
{
|
||||
struct label *match = NULL;
|
||||
int i;
|
||||
|
||||
if (free_slot != NULL) {
|
||||
*free_slot = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(labels); i++) {
|
||||
if (!labels[i].ref) {
|
||||
free_slot = &labels[i];
|
||||
if (labels[i].ref == 0) {
|
||||
if (free_slot != NULL) {
|
||||
*free_slot = &labels[i];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!memcmp(labels[i].uuid, label_uuid, 16)) {
|
||||
*addr = labels[i].addr;
|
||||
labels[i].ref++;
|
||||
return STATUS_SUCCESS;
|
||||
match = &labels[i];
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
static u8_t va_add(u8_t *label_uuid, u16_t *addr)
|
||||
{
|
||||
struct label *update, *free_slot = NULL;
|
||||
|
||||
update = va_find(label_uuid, &free_slot);
|
||||
if (update) {
|
||||
update->ref++;
|
||||
va_store(update);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!free_slot) {
|
||||
return STATUS_INSUFF_RESOURCES;
|
||||
}
|
||||
|
@ -1192,24 +1214,26 @@ static u8_t va_add(u8_t *label_uuid, u16_t *addr)
|
|||
free_slot->ref = 1U;
|
||||
free_slot->addr = *addr;
|
||||
memcpy(free_slot->uuid, label_uuid, 16);
|
||||
va_store(free_slot);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static u8_t va_del(u8_t *label_uuid, u16_t *addr)
|
||||
{
|
||||
int i;
|
||||
struct label *update;
|
||||
|
||||
update = va_find(label_uuid, NULL);
|
||||
if (update) {
|
||||
update->ref--;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(labels); i++) {
|
||||
if (!memcmp(labels[i].uuid, label_uuid, 16)) {
|
||||
if (addr) {
|
||||
*addr = labels[i].addr;
|
||||
*addr = update->addr;
|
||||
}
|
||||
|
||||
labels[i].ref--;
|
||||
va_store(update);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr) {
|
||||
*addr = BLE_MESH_ADDR_UNASSIGNED;
|
||||
|
@ -1386,8 +1410,7 @@ static void send_mod_sub_status(struct bt_mesh_model *model,
|
|||
u16_t elem_addr, u16_t sub_addr, u8_t *mod_id,
|
||||
bool vnd)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_STATUS, 9);
|
||||
|
||||
BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status,
|
||||
elem_addr, sub_addr);
|
||||
|
@ -1696,8 +1719,8 @@ static void mod_sub_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4 +
|
||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST,
|
||||
5 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
||||
struct bt_mesh_model *mod;
|
||||
struct bt_mesh_elem *elem;
|
||||
u16_t addr, id;
|
||||
|
@ -1752,8 +1775,8 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 7 + 4 +
|
||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST_VND,
|
||||
7 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
||||
struct bt_mesh_model *mod;
|
||||
struct bt_mesh_elem *elem;
|
||||
u16_t company, addr, id;
|
||||
|
@ -2145,8 +2168,7 @@ static void send_net_key_status(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t idx, u8_t status)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_STATUS, 3);
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_NET_KEY_STATUS);
|
||||
|
||||
|
@ -2379,8 +2401,8 @@ static void net_key_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg,
|
||||
2 + 4 + IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT));
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_LIST,
|
||||
IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT));
|
||||
u16_t prev, i;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_NET_KEY_LIST);
|
||||
|
@ -2415,8 +2437,7 @@ static void node_identity_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
|
||||
struct bt_mesh_subnet *sub;
|
||||
u8_t node_id;
|
||||
u16_t idx;
|
||||
|
@ -2454,8 +2475,7 @@ static void node_identity_set(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
|
||||
struct bt_mesh_subnet *sub;
|
||||
u8_t node_id;
|
||||
u16_t idx;
|
||||
|
@ -2531,7 +2551,7 @@ static void mod_app_bind(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
|
||||
u16_t elem_addr, key_app_idx;
|
||||
struct bt_mesh_model *mod;
|
||||
struct bt_mesh_elem *elem;
|
||||
|
@ -2594,7 +2614,7 @@ static void mod_app_unbind(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9);
|
||||
u16_t elem_addr, key_app_idx;
|
||||
struct bt_mesh_model *mod;
|
||||
struct bt_mesh_elem *elem;
|
||||
|
@ -2652,7 +2672,11 @@ static void mod_app_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + KEY_LIST_LEN + 4);
|
||||
NET_BUF_SIMPLE_DEFINE(msg,
|
||||
MAX(BLE_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST,
|
||||
9 + KEY_LIST_LEN),
|
||||
BLE_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST,
|
||||
9 + KEY_LIST_LEN)));
|
||||
struct bt_mesh_model *mod;
|
||||
struct bt_mesh_elem *elem;
|
||||
u8_t *mod_id, status;
|
||||
|
@ -2720,8 +2744,7 @@ static void node_reset(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0);
|
||||
|
||||
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,
|
||||
|
@ -2745,8 +2768,7 @@ static void node_reset(struct bt_mesh_model *model,
|
|||
static void send_friend_status(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1);
|
||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS);
|
||||
|
@ -2818,8 +2840,7 @@ static void lpn_timeout_get(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
struct net_buf_simple *buf)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_STATUS, 5);
|
||||
struct bt_mesh_friend *frnd;
|
||||
u16_t lpn_addr;
|
||||
s32_t timeout;
|
||||
|
@ -2864,8 +2885,7 @@ static void send_krp_status(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t idx, u8_t phase, u8_t status)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_STATUS, 4);
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_KRP_STATUS);
|
||||
|
||||
|
@ -3008,8 +3028,7 @@ static void hb_pub_send_status(struct bt_mesh_model *model,
|
|||
struct bt_mesh_msg_ctx *ctx, u8_t status,
|
||||
struct hb_pub_param *orig_msg)
|
||||
{
|
||||
/* Needed size: opcode (1 byte) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 1 + 10 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_STATUS, 10);
|
||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||
|
||||
BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status);
|
||||
|
@ -3147,8 +3166,7 @@ failed:
|
|||
static void hb_sub_send_status(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx, u8_t status)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_STATUS, 9);
|
||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||
u16_t period;
|
||||
s64_t uptime;
|
||||
|
|
|
@ -117,6 +117,17 @@
|
|||
#define STATUS_UNSPECIFIED 0x10
|
||||
#define STATUS_INVALID_BINDING 0x11
|
||||
|
||||
enum {
|
||||
BLE_MESH_VA_CHANGED, /* Label information changed */
|
||||
};
|
||||
|
||||
struct label {
|
||||
u16_t ref;
|
||||
u16_t addr;
|
||||
u8_t uuid[16];
|
||||
bt_mesh_atomic_t flags[1];
|
||||
};
|
||||
|
||||
int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary);
|
||||
int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary);
|
||||
|
||||
|
@ -129,6 +140,8 @@ void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat);
|
|||
|
||||
void bt_mesh_attention(struct bt_mesh_model *model, u8_t time);
|
||||
|
||||
struct label *get_label(u16_t index);
|
||||
|
||||
u8_t *bt_mesh_label_uuid_get(u16_t addr);
|
||||
|
||||
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
|
||||
|
|
|
@ -26,19 +26,18 @@
|
|||
#include "access.h"
|
||||
#include "foundation.h"
|
||||
#include "friend.h"
|
||||
#include "client_common.h"
|
||||
#include "provisioner_main.h"
|
||||
|
||||
#ifdef CONFIG_BLE_MESH_FRIEND
|
||||
|
||||
#define FRIEND_BUF_SIZE (BLE_MESH_ADV_DATA_SIZE - BLE_MESH_NET_HDR_LEN)
|
||||
|
||||
/* We reserve one extra buffer for each friendship, since we need to be able
|
||||
* to resend the last sent PDU, which sits separately outside of the queue.
|
||||
*/
|
||||
#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \
|
||||
CONFIG_BLE_MESH_FRIEND_LPN_COUNT)
|
||||
|
||||
#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), \
|
||||
struct friend_adv, adv)
|
||||
#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), struct friend_adv, adv)
|
||||
|
||||
/* PDUs from Friend to the LPN should only be transmitted once with the
|
||||
* smallest possible interval (20ms).
|
||||
|
@ -62,7 +61,7 @@ NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
|
|||
|
||||
static struct friend_adv {
|
||||
struct bt_mesh_adv adv;
|
||||
u64_t seq_auth;
|
||||
u16_t app_idx;
|
||||
} adv_pool[FRIEND_BUF_COUNT];
|
||||
|
||||
enum {
|
||||
|
@ -75,10 +74,22 @@ enum {
|
|||
|
||||
static void (*friend_cb)(bool establish, u16_t lpn_addr, u8_t reason);
|
||||
|
||||
static struct bt_mesh_subnet *friend_subnet_get(u16_t net_idx)
|
||||
{
|
||||
struct bt_mesh_subnet *sub = NULL;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
sub = bt_mesh_subnet_get(net_idx);
|
||||
} else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) {
|
||||
sub = provisioner_subnet_get(net_idx);
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
static struct bt_mesh_adv *adv_alloc(int id)
|
||||
{
|
||||
adv_pool[id].app_idx = BLE_MESH_KEY_UNUSED;
|
||||
return &adv_pool[id].adv;
|
||||
}
|
||||
|
||||
|
@ -318,13 +329,7 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
|
|||
struct friend_pdu_info *info,
|
||||
struct net_buf_simple *sdu)
|
||||
{
|
||||
struct bt_mesh_subnet *sub;
|
||||
const u8_t *enc, *priv;
|
||||
struct net_buf *buf;
|
||||
u8_t nid;
|
||||
|
||||
sub = bt_mesh_subnet_get(frnd->net_idx);
|
||||
__ASSERT_NO_MSG(sub != NULL);
|
||||
|
||||
buf = bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_alloc,
|
||||
BLE_MESH_ADV_DATA,
|
||||
|
@ -333,22 +338,7 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BLE_MESH_ADV(buf)->addr = info->src;
|
||||
FRIEND_ADV(buf)->seq_auth = TRANS_SEQ_AUTH_NVAL;
|
||||
|
||||
/* Friend Offer needs master security credentials */
|
||||
if (info->ctl && TRANS_CTL_OP(sdu->data) == TRANS_CTL_OP_FRIEND_OFFER) {
|
||||
enc = sub->keys[sub->kr_flag].enc;
|
||||
priv = sub->keys[sub->kr_flag].privacy;
|
||||
nid = sub->keys[sub->kr_flag].nid;
|
||||
} else {
|
||||
if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) {
|
||||
BT_ERR("%s, friend_cred_get failed", __func__);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
net_buf_add_u8(buf, (nid | (info->iv_index & 1) << 7));
|
||||
net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */
|
||||
|
||||
if (info->ctl) {
|
||||
net_buf_add_u8(buf, info->ttl | 0x80);
|
||||
|
@ -363,25 +353,187 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
|
|||
|
||||
net_buf_add_mem(buf, sdu->data, sdu->len);
|
||||
|
||||
/* We re-encrypt and obfuscate using the received IVI rather than
|
||||
* the normal TX IVI (which may be different) since the transport
|
||||
* layer nonce includes the IVI.
|
||||
*/
|
||||
if (bt_mesh_net_encrypt(enc, &buf->b, info->iv_index, false)) {
|
||||
BT_ERR("%s, Re-encrypting failed", __func__);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (bt_mesh_net_obfuscate(buf->data, info->iv_index, priv)) {
|
||||
BT_ERR("%s, Re-obfuscating failed", __func__);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
failed:
|
||||
net_buf_unref(buf);
|
||||
return NULL;
|
||||
struct unseg_app_sdu_meta {
|
||||
struct bt_mesh_net_rx net;
|
||||
const u8_t *key;
|
||||
struct bt_mesh_subnet *subnet;
|
||||
bool is_dev_key;
|
||||
u8_t aid;
|
||||
u8_t *ad;
|
||||
};
|
||||
|
||||
static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd,
|
||||
struct net_buf *buf,
|
||||
struct unseg_app_sdu_meta *meta)
|
||||
{
|
||||
u16_t app_idx = FRIEND_ADV(buf)->app_idx;
|
||||
u8_t role;
|
||||
int err;
|
||||
|
||||
meta->subnet = friend_subnet_get(frnd->net_idx);
|
||||
if (!meta->subnet) {
|
||||
BT_ERR("Invalid subnet for unseg app sdu");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
role = (IS_ENABLED(CONFIG_BLE_MESH_NODE) &&
|
||||
bt_mesh_is_provisioned()) ? NODE : PROVISIONER;
|
||||
|
||||
meta->is_dev_key = (app_idx == BLE_MESH_KEY_DEV);
|
||||
bt_mesh_net_header_parse(&buf->b, &meta->net);
|
||||
err = bt_mesh_app_key_get(meta->subnet, app_idx, &meta->key,
|
||||
&meta->aid, role, meta->net.ctx.addr);
|
||||
if (err) {
|
||||
BT_ERR("Failed to get AppKey");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (BLE_MESH_ADDR_IS_VIRTUAL(meta->net.ctx.recv_dst)) {
|
||||
meta->ad = bt_mesh_label_uuid_get(meta->net.ctx.recv_dst);
|
||||
if (!meta->ad) {
|
||||
BT_ERR("Failed to get label uuid");
|
||||
return -ENOENT;
|
||||
}
|
||||
} else {
|
||||
meta->ad = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unseg_app_sdu_decrypt(struct bt_mesh_friend *frnd,
|
||||
struct net_buf *buf,
|
||||
const struct unseg_app_sdu_meta *meta)
|
||||
{
|
||||
struct net_buf_simple sdu;
|
||||
|
||||
net_buf_simple_clone(&buf->b, &sdu);
|
||||
net_buf_simple_pull(&sdu, 10);
|
||||
sdu.len -= 4;
|
||||
|
||||
return bt_mesh_app_decrypt(meta->key, meta->is_dev_key, 0, &sdu, &sdu,
|
||||
meta->ad, meta->net.ctx.addr,
|
||||
meta->net.ctx.recv_dst, meta->net.seq,
|
||||
BLE_MESH_NET_IVI_TX);
|
||||
}
|
||||
|
||||
static int unseg_app_sdu_encrypt(struct bt_mesh_friend *frnd,
|
||||
struct net_buf *buf,
|
||||
const struct unseg_app_sdu_meta *meta)
|
||||
{
|
||||
struct net_buf_simple sdu;
|
||||
|
||||
net_buf_simple_clone(&buf->b, &sdu);
|
||||
net_buf_simple_pull(&sdu, 10);
|
||||
sdu.len -= 4;
|
||||
|
||||
return bt_mesh_app_encrypt(meta->key, meta->is_dev_key, 0, &sdu,
|
||||
meta->ad, meta->net.ctx.addr,
|
||||
meta->net.ctx.recv_dst, bt_mesh.seq,
|
||||
BLE_MESH_NET_IVI_TX);
|
||||
}
|
||||
|
||||
static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
struct unseg_app_sdu_meta meta;
|
||||
int err;
|
||||
|
||||
if (FRIEND_ADV(buf)->app_idx == BLE_MESH_KEY_UNUSED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = unseg_app_sdu_unpack(frnd, buf, &meta);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* No need to reencrypt the message if the sequence number is
|
||||
* unchanged.
|
||||
*/
|
||||
if (meta.net.seq == bt_mesh.seq) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = unseg_app_sdu_decrypt(frnd, buf, &meta);
|
||||
if (err) {
|
||||
BT_WARN("Decryption failed! %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = unseg_app_sdu_encrypt(frnd, buf, &meta);
|
||||
if (err) {
|
||||
BT_WARN("Re-encryption failed! %d", err);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf,
|
||||
bool master_cred)
|
||||
{
|
||||
struct bt_mesh_subnet *sub = friend_subnet_get(frnd->net_idx);
|
||||
const u8_t *enc, *priv;
|
||||
u32_t iv_index;
|
||||
u16_t src;
|
||||
u8_t nid;
|
||||
int err;
|
||||
|
||||
if (!sub) {
|
||||
BT_ERR("Invalid subnet to encrypt friend pdu");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (master_cred) {
|
||||
enc = sub->keys[sub->kr_flag].enc;
|
||||
priv = sub->keys[sub->kr_flag].privacy;
|
||||
nid = sub->keys[sub->kr_flag].nid;
|
||||
} else {
|
||||
if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) {
|
||||
BT_ERR("friend_cred_get failed");
|
||||
return -ENOENT;
|
||||
}
|
||||
}
|
||||
|
||||
src = sys_get_be16(&buf->data[5]);
|
||||
|
||||
if (bt_mesh_elem_find(src)) {
|
||||
u32_t seq;
|
||||
|
||||
if (FRIEND_ADV(buf)->app_idx != BLE_MESH_KEY_UNUSED) {
|
||||
err = unseg_app_sdu_prepare(frnd, buf);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
seq = bt_mesh_next_seq();
|
||||
buf->data[2] = seq >> 16;
|
||||
buf->data[3] = seq >> 8;
|
||||
buf->data[4] = seq;
|
||||
iv_index = BLE_MESH_NET_IVI_TX;
|
||||
FRIEND_ADV(buf)->app_idx = BLE_MESH_KEY_UNUSED;
|
||||
} else {
|
||||
u8_t ivi = (buf->data[0] >> 7);
|
||||
iv_index = (bt_mesh.iv_index - ((bt_mesh.iv_index & 1) != ivi));
|
||||
}
|
||||
|
||||
buf->data[0] = (nid | (iv_index & 1) << 7);
|
||||
|
||||
if (bt_mesh_net_encrypt(enc, &buf->b, iv_index, false)) {
|
||||
BT_ERR("Encrypting failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bt_mesh_net_obfuscate(buf->data, iv_index, priv)) {
|
||||
BT_ERR("Obfuscating failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd,
|
||||
|
@ -389,7 +541,6 @@ static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd,
|
|||
struct net_buf_simple *sdu)
|
||||
{
|
||||
struct friend_pdu_info info;
|
||||
u32_t seq;
|
||||
|
||||
BT_DBG("LPN 0x%04x", frnd->lpn);
|
||||
|
||||
|
@ -401,10 +552,7 @@ static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd,
|
|||
info.ctl = 1U;
|
||||
info.ttl = 0U;
|
||||
|
||||
seq = bt_mesh_next_seq();
|
||||
info.seq[0] = seq >> 16;
|
||||
info.seq[1] = seq >> 8;
|
||||
info.seq[2] = seq;
|
||||
memset(info.seq, 0, sizeof(info.seq));
|
||||
|
||||
info.iv_index = BLE_MESH_NET_IVI_TX;
|
||||
|
||||
|
@ -415,7 +563,7 @@ static struct net_buf *encode_update(struct bt_mesh_friend *frnd, u8_t md)
|
|||
{
|
||||
struct bt_mesh_ctl_friend_update *upd;
|
||||
NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*upd));
|
||||
struct bt_mesh_subnet *sub = bt_mesh_subnet_get(frnd->net_idx);
|
||||
struct bt_mesh_subnet *sub = friend_subnet_get(frnd->net_idx);
|
||||
|
||||
__ASSERT_NO_MSG(sub != NULL);
|
||||
|
||||
|
@ -450,6 +598,10 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, u8_t xact)
|
|||
return;
|
||||
}
|
||||
|
||||
if (encrypt_friend_pdu(frnd, buf, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frnd->last) {
|
||||
BT_DBG("Discarding last PDU");
|
||||
net_buf_unref(frnd->last);
|
||||
|
@ -651,7 +803,7 @@ static void send_friend_clear(struct bt_mesh_friend *frnd)
|
|||
.send_ttl = BLE_MESH_TTL_MAX,
|
||||
};
|
||||
struct bt_mesh_net_tx tx = {
|
||||
.sub = &bt_mesh.sub[0],
|
||||
.sub = friend_subnet_get(frnd->net_idx),
|
||||
.ctx = &ctx,
|
||||
.src = bt_mesh_primary_addr(),
|
||||
.xmit = bt_mesh_net_transmit_get(),
|
||||
|
@ -663,6 +815,11 @@ static void send_friend_clear(struct bt_mesh_friend *frnd)
|
|||
|
||||
BT_DBG("%s", __func__);
|
||||
|
||||
if (!tx.sub) {
|
||||
BT_ERR("Invalid subnet for Friend Clear");
|
||||
return;
|
||||
}
|
||||
|
||||
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req,
|
||||
sizeof(req), NULL, &clear_sent_cb, frnd);
|
||||
}
|
||||
|
@ -759,6 +916,10 @@ static void enqueue_offer(struct bt_mesh_friend *frnd, s8_t rssi)
|
|||
return;
|
||||
}
|
||||
|
||||
if (encrypt_friend_pdu(frnd, buf, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
frnd->counter++;
|
||||
|
||||
if (frnd->last) {
|
||||
|
@ -879,7 +1040,7 @@ init_friend:
|
|||
frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr);
|
||||
|
||||
BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums",
|
||||
frnd->lpn, rx->rssi, frnd->recv_delay, frnd->poll_to);
|
||||
frnd->lpn, rx->ctx.recv_rssi, frnd->recv_delay, frnd->poll_to);
|
||||
|
||||
/**
|
||||
* Spec says:
|
||||
|
@ -894,18 +1055,40 @@ init_friend:
|
|||
}
|
||||
|
||||
k_delayed_work_submit(&frnd->timer,
|
||||
offer_delay(frnd, rx->rssi, msg->criteria));
|
||||
offer_delay(frnd, rx->ctx.recv_rssi,
|
||||
msg->criteria));
|
||||
|
||||
friend_cred_create(rx->sub, frnd->lpn, frnd->lpn_counter,
|
||||
frnd->counter);
|
||||
|
||||
enqueue_offer(frnd, rx->rssi);
|
||||
enqueue_offer(frnd, rx->ctx.recv_rssi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_seg(struct bt_mesh_friend_seg *seg, u16_t src, u16_t seq_zero)
|
||||
{
|
||||
struct net_buf *buf = (void *)sys_slist_peek_head(&seg->queue);
|
||||
struct net_buf_simple_state state;
|
||||
u16_t buf_seq_zero;
|
||||
u16_t buf_src;
|
||||
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
net_buf_simple_save(&buf->b, &state);
|
||||
net_buf_skip(buf, 5); /* skip IVI, NID, CTL, TTL, SEQ */
|
||||
buf_src = net_buf_pull_be16(buf);
|
||||
net_buf_skip(buf, 3); /* skip DST, OP/AID */
|
||||
buf_seq_zero = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK);
|
||||
net_buf_simple_restore(&buf->b, &state);
|
||||
|
||||
return ((src == buf_src) && (seq_zero == buf_seq_zero));
|
||||
}
|
||||
|
||||
static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd,
|
||||
u16_t src, u64_t *seq_auth,
|
||||
u16_t src, u16_t seq_zero,
|
||||
u8_t seg_count)
|
||||
{
|
||||
struct bt_mesh_friend_seg *unassigned = NULL;
|
||||
|
@ -913,14 +1096,12 @@ static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd,
|
|||
|
||||
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
||||
struct bt_mesh_friend_seg *seg = &frnd->seg[i];
|
||||
struct net_buf *buf = (void *)sys_slist_peek_head(&seg->queue);
|
||||
|
||||
if (buf && BLE_MESH_ADV(buf)->addr == src &&
|
||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
||||
if (is_seg(seg, src, seq_zero)) {
|
||||
return seg;
|
||||
}
|
||||
|
||||
if (!unassigned && !buf) {
|
||||
if (!unassigned && !sys_slist_peek_head(&seg->queue)) {
|
||||
unassigned = seg;
|
||||
}
|
||||
}
|
||||
|
@ -934,10 +1115,10 @@ static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd,
|
|||
|
||||
static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
||||
enum bt_mesh_friend_pdu_type type,
|
||||
u8_t seg_count, struct net_buf *buf)
|
||||
u16_t src, u8_t seg_count,
|
||||
struct net_buf *buf)
|
||||
{
|
||||
struct bt_mesh_friend_seg *seg;
|
||||
struct friend_adv *adv;
|
||||
|
||||
BT_DBG("type %u", type);
|
||||
|
||||
|
@ -950,11 +1131,11 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
|||
return;
|
||||
}
|
||||
|
||||
adv = FRIEND_ADV(buf);
|
||||
seg = get_seg(frnd, BLE_MESH_ADV(buf)->addr, &adv->seq_auth, seg_count);
|
||||
u16_t seq_zero = (((buf->data[10] << 8 | buf->data[11]) >> 2) & TRANS_SEQ_ZERO_MASK);
|
||||
|
||||
seg = get_seg(frnd, src, seq_zero, seg_count);
|
||||
if (!seg) {
|
||||
BT_ERR("%s, No free friend segment RX contexts for 0x%04x",
|
||||
__func__, BLE_MESH_ADV(buf)->addr);
|
||||
BT_ERR("No free friend segment RX contexts for 0x%04x", src);
|
||||
net_buf_unref(buf);
|
||||
return;
|
||||
}
|
||||
|
@ -966,16 +1147,9 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
|||
enqueue_update(frnd, 1);
|
||||
}
|
||||
|
||||
/* Only acks should have a valid SeqAuth in the Friend queue
|
||||
* (otherwise we can't easily detect them there), so clear
|
||||
* the SeqAuth information from the segments before merging.
|
||||
*/
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&seg->queue, buf, node) {
|
||||
FRIEND_ADV(buf)->seq_auth = TRANS_SEQ_AUTH_NVAL;
|
||||
frnd->queue_size++;
|
||||
}
|
||||
|
||||
sys_slist_merge_slist(&frnd->queue, &seg->queue);
|
||||
|
||||
frnd->queue_size += seg->seg_count;
|
||||
seg->seg_count = 0U;
|
||||
} else {
|
||||
/* Mark the buffer as having more to come after it */
|
||||
|
@ -1052,6 +1226,10 @@ static void friend_timeout(struct k_work *work)
|
|||
return;
|
||||
}
|
||||
|
||||
if (encrypt_friend_pdu(frnd, frnd->last, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear the flag we use for segment tracking */
|
||||
frnd->last->flags &= ~NET_BUF_FRAGS;
|
||||
frnd->last->frags = NULL;
|
||||
|
@ -1094,6 +1272,42 @@ int bt_mesh_friend_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool is_segack(struct net_buf *buf, u64_t *seqauth, u16_t src)
|
||||
{
|
||||
struct net_buf_simple_state state;
|
||||
bool found = false;
|
||||
|
||||
if (buf->len != 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
net_buf_simple_save(&buf->b, &state);
|
||||
|
||||
net_buf_skip(buf, 1); /* skip IVI, NID */
|
||||
|
||||
if (!(net_buf_pull_u8(buf) >> 7)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
net_buf_pull(buf, 3); /* skip SEQNUM */
|
||||
|
||||
if (src != net_buf_pull_be16(buf)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
net_buf_skip(buf, 2); /* skip dst */
|
||||
|
||||
if (TRANS_CTL_OP((u8_t *) net_buf_pull_mem(buf, 1)) != TRANS_CTL_OP_ACK) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
found = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK) ==
|
||||
(*seqauth & TRANS_SEQ_ZERO_MASK);
|
||||
end:
|
||||
net_buf_simple_restore(&buf->b, &state);
|
||||
return found;
|
||||
}
|
||||
|
||||
static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth,
|
||||
u16_t src)
|
||||
{
|
||||
|
@ -1105,8 +1319,7 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth,
|
|||
cur != NULL; prev = cur, cur = sys_slist_peek_next(cur)) {
|
||||
struct net_buf *buf = (void *)cur;
|
||||
|
||||
if (BLE_MESH_ADV(buf)->addr == src &&
|
||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
||||
if (is_segack(buf, seq_auth, src)) {
|
||||
BT_DBG("Removing old ack from Friend Queue");
|
||||
|
||||
sys_slist_remove(&frnd->queue, prev, cur);
|
||||
|
@ -1129,6 +1342,14 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd,
|
|||
struct friend_pdu_info info;
|
||||
struct net_buf *buf;
|
||||
|
||||
/* Because of network loopback, tx packets will also be passed into
|
||||
* this rx function. These packets have already been added to the
|
||||
* queue, and should be ignored.
|
||||
*/
|
||||
if (bt_mesh_elem_find(rx->ctx.addr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("LPN 0x%04x queue_size %u", frnd->lpn, frnd->queue_size);
|
||||
|
||||
if (type == BLE_MESH_FRIEND_PDU_SINGLE && seq_auth) {
|
||||
|
@ -1158,11 +1379,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd,
|
|||
return;
|
||||
}
|
||||
|
||||
if (seq_auth) {
|
||||
FRIEND_ADV(buf)->seq_auth = *seq_auth;
|
||||
}
|
||||
|
||||
enqueue_friend_pdu(frnd, type, seg_count, buf);
|
||||
enqueue_friend_pdu(frnd, type, info.src, seg_count, buf);
|
||||
|
||||
BT_DBG("Queued message for LPN 0x%04x, queue_size %u",
|
||||
frnd->lpn, frnd->queue_size);
|
||||
|
@ -1176,7 +1393,6 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd,
|
|||
{
|
||||
struct friend_pdu_info info;
|
||||
struct net_buf *buf;
|
||||
u32_t seq;
|
||||
|
||||
BT_DBG("LPN 0x%04x", frnd->lpn);
|
||||
|
||||
|
@ -1190,10 +1406,9 @@ 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);
|
||||
|
||||
seq = bt_mesh_next_seq();
|
||||
info.seq[0] = seq >> 16;
|
||||
info.seq[1] = seq >> 8;
|
||||
info.seq[2] = seq;
|
||||
info.seq[0] = (bt_mesh.seq >> 16);
|
||||
info.seq[1] = (bt_mesh.seq >> 8);
|
||||
info.seq[2] = bt_mesh.seq;
|
||||
|
||||
info.iv_index = BLE_MESH_NET_IVI_TX;
|
||||
|
||||
|
@ -1203,11 +1418,15 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd,
|
|||
return;
|
||||
}
|
||||
|
||||
if (seq_auth) {
|
||||
FRIEND_ADV(buf)->seq_auth = *seq_auth;
|
||||
if (type == BLE_MESH_FRIEND_PDU_SINGLE && !info.ctl) {
|
||||
/* Unsegmented application packets may be reencrypted later,
|
||||
* as they depend on the the sequence number being the same
|
||||
* when encrypting in transport and network.
|
||||
*/
|
||||
FRIEND_ADV(buf)->app_idx = tx->ctx->app_idx;
|
||||
}
|
||||
|
||||
enqueue_friend_pdu(frnd, type, seg_count, buf);
|
||||
enqueue_friend_pdu(frnd, type, info.src, seg_count, buf);
|
||||
|
||||
BT_DBG("Queued message for LPN 0x%04x", frnd->lpn);
|
||||
}
|
||||
|
@ -1270,18 +1489,12 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, u16_t addr,
|
|||
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
||||
struct bt_mesh_friend_seg *seg = &frnd->seg[i];
|
||||
|
||||
if (seq_auth) {
|
||||
struct net_buf *buf;
|
||||
|
||||
if (seq_auth && is_seg(seg, addr, *seq_auth & TRANS_SEQ_ZERO_MASK)) {
|
||||
/* If there's a segment queue for this message then the
|
||||
* space verification has already happened.
|
||||
*/
|
||||
buf = (void *)sys_slist_peek_head(&seg->queue);
|
||||
if (buf && BLE_MESH_ADV(buf)->addr == addr &&
|
||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
total += seg->seg_count;
|
||||
}
|
||||
|
@ -1454,18 +1667,8 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src,
|
|||
|
||||
for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) {
|
||||
struct bt_mesh_friend_seg *seg = &frnd->seg[j];
|
||||
struct net_buf *buf;
|
||||
|
||||
buf = (void *)sys_slist_peek_head(&seg->queue);
|
||||
if (!buf) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BLE_MESH_ADV(buf)->addr != src) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FRIEND_ADV(buf)->seq_auth != *seq_auth) {
|
||||
if (!is_seg(seg, src, *seq_auth & TRANS_SEQ_ZERO_MASK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1473,8 +1676,19 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src,
|
|||
|
||||
purge_buffers(&seg->queue);
|
||||
seg->seg_count = 0U;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_friend_remove_lpn(u16_t lpn_addr)
|
||||
{
|
||||
struct bt_mesh_friend *frnd;
|
||||
|
||||
frnd = bt_mesh_friend_find(BLE_MESH_KEY_ANY, lpn_addr, false, false);
|
||||
if (frnd) {
|
||||
friend_clear(frnd, BLE_MESH_FRIENDSHIP_TERMINATE_DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||
|
|
|
@ -51,4 +51,6 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx,
|
|||
|
||||
int bt_mesh_friend_init(void);
|
||||
|
||||
void bt_mesh_friend_remove_lpn(u16_t lpn_addr);
|
||||
|
||||
#endif /* _FRIEND_H_ */
|
||||
|
|
|
@ -235,7 +235,7 @@ const struct bt_mesh_model_op bt_mesh_health_cli_op[] = {
|
|||
|
||||
int bt_mesh_health_attention_get(struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_GET, 0);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -257,7 +257,7 @@ int bt_mesh_health_attention_get(struct bt_mesh_msg_ctx *ctx)
|
|||
int bt_mesh_health_attention_set(struct bt_mesh_msg_ctx *ctx,
|
||||
u8_t attention, bool need_ack)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_SET, 1);
|
||||
u32_t opcode;
|
||||
int err;
|
||||
|
||||
|
@ -285,7 +285,7 @@ int bt_mesh_health_attention_set(struct bt_mesh_msg_ctx *ctx,
|
|||
|
||||
int bt_mesh_health_period_get(struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_GET, 0);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
@ -307,7 +307,7 @@ int bt_mesh_health_period_get(struct bt_mesh_msg_ctx *ctx)
|
|||
int bt_mesh_health_period_set(struct bt_mesh_msg_ctx *ctx,
|
||||
u8_t divisor, bool need_ack)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_SET, 1);
|
||||
u32_t opcode;
|
||||
int err;
|
||||
|
||||
|
@ -336,7 +336,7 @@ int bt_mesh_health_period_set(struct bt_mesh_msg_ctx *ctx,
|
|||
int bt_mesh_health_fault_test(struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t cid, u8_t test_id, bool need_ack)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_TEST, 3);
|
||||
u32_t opcode;
|
||||
int err;
|
||||
|
||||
|
@ -366,7 +366,7 @@ int bt_mesh_health_fault_test(struct bt_mesh_msg_ctx *ctx,
|
|||
int bt_mesh_health_fault_clear(struct bt_mesh_msg_ctx *ctx,
|
||||
u16_t cid, bool need_ack)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_CLEAR, 2);
|
||||
u32_t opcode;
|
||||
int err;
|
||||
|
||||
|
@ -394,7 +394,7 @@ int bt_mesh_health_fault_clear(struct bt_mesh_msg_ctx *ctx,
|
|||
|
||||
int bt_mesh_health_fault_get(struct bt_mesh_msg_ctx *ctx, u16_t cid)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_GET, 2);
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->addr) {
|
||||
|
|
|
@ -227,8 +227,7 @@ static void health_fault_test(struct bt_mesh_model *model,
|
|||
static void send_attention_status(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_STATUS, 1);
|
||||
struct bt_mesh_health_srv *srv = model->user_data;
|
||||
u8_t time;
|
||||
|
||||
|
@ -286,8 +285,7 @@ static void attention_set(struct bt_mesh_model *model,
|
|||
static void send_health_period_status(struct bt_mesh_model *model,
|
||||
struct bt_mesh_msg_ctx *ctx)
|
||||
{
|
||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
||||
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_STATUS, 1);
|
||||
|
||||
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS);
|
||||
net_buf_simple_add_u8(&msg, model->pub->period_div);
|
||||
|
|
|
@ -140,6 +140,9 @@ struct bt_mesh_msg_ctx {
|
|||
/** Destination address of a received message. Not used for sending. */
|
||||
u16_t recv_dst;
|
||||
|
||||
/** RSSI of received packet. Not used for sending. */
|
||||
s8_t recv_rssi;
|
||||
|
||||
/** Received TTL value. Not used for sending. */
|
||||
u8_t recv_ttl: 7;
|
||||
|
||||
|
@ -185,6 +188,56 @@ struct bt_mesh_model_op {
|
|||
/** Helper to define an empty model array */
|
||||
#define BLE_MESH_MODEL_NONE ((struct bt_mesh_model []){})
|
||||
|
||||
/** Length of a short Mesh MIC. */
|
||||
#define BLE_MESH_MIC_SHORT 4
|
||||
/** Length of a long Mesh MIC. */
|
||||
#define BLE_MESH_MIC_LONG 8
|
||||
|
||||
/** @def BLE_MESH_MODEL_OP_LEN
|
||||
*
|
||||
* @brief Helper to determine the length of an opcode.
|
||||
*
|
||||
* @param _op Opcode.
|
||||
*/
|
||||
#define BLE_MESH_MODEL_OP_LEN(_op) ((_op) <= 0xff ? 1 : (_op) <= 0xffff ? 2 : 3)
|
||||
|
||||
/** @def BLE_MESH_MODEL_BUF_LEN
|
||||
*
|
||||
* @brief Helper for model message buffer length.
|
||||
*
|
||||
* Returns the length of a Mesh model message buffer, including the opcode
|
||||
* length and a short MIC.
|
||||
*
|
||||
* @param _op Opcode of the message.
|
||||
* @param _payload_len Length of the model payload.
|
||||
*/
|
||||
#define BLE_MESH_MODEL_BUF_LEN(_op, _payload_len) \
|
||||
(BLE_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BLE_MESH_MIC_SHORT)
|
||||
|
||||
/** @def BLE_MESH_MODEL_BUF_LEN_LONG_MIC
|
||||
*
|
||||
* @brief Helper for model message buffer length.
|
||||
*
|
||||
* Returns the length of a Mesh model message buffer, including the opcode
|
||||
* length and a long MIC.
|
||||
*
|
||||
* @param _op Opcode of the message.
|
||||
* @param _payload_len Length of the model payload.
|
||||
*/
|
||||
#define BLE_MESH_MODEL_BUF_LEN_LONG_MIC(_op, _payload_len) \
|
||||
(BLE_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BLE_MESH_MIC_LONG)
|
||||
|
||||
/** @def BLE_MESH_MODEL_BUF_DEFINE
|
||||
*
|
||||
* @brief Define a Mesh model message buffer using @ref NET_BUF_SIMPLE_DEFINE.
|
||||
*
|
||||
* @param _buf Buffer name.
|
||||
* @param _op Opcode of the message.
|
||||
* @param _payload_len Length of the model message payload.
|
||||
*/
|
||||
#define BLE_MESH_MODEL_BUF_DEFINE(_buf, _op, _payload_len) \
|
||||
NET_BUF_SIMPLE_DEFINE(_buf, BLE_MESH_MODEL_BUF_LEN(_op, (_payload_len)))
|
||||
|
||||
#define BLE_MESH_MODEL(_id, _op, _pub, _user_data) \
|
||||
{ \
|
||||
.id = (_id), \
|
||||
|
@ -282,15 +335,15 @@ struct bt_mesh_model_pub {
|
|||
struct bt_mesh_model *mod;
|
||||
|
||||
u16_t addr; /**< Publish Address. */
|
||||
u16_t key; /**< Publish AppKey Index. */
|
||||
u16_t key:12, /**< Publish AppKey Index. */
|
||||
cred:1; /**< Friendship Credentials Flag. */
|
||||
|
||||
u8_t ttl; /**< Publish Time to Live. */
|
||||
u8_t retransmit; /**< Retransmit Count & Interval Steps. */
|
||||
u8_t period; /**< Publish Period. */
|
||||
u16_t period_div: 4, /**< Divisor for the Period. */
|
||||
cred: 1, /**< Friendship Credentials Flag. */
|
||||
fast_period: 1, /**< Use FastPeriodDivisor */
|
||||
count: 3; /**< Retransmissions left. */
|
||||
u8_t period_div:4, /**< Divisor for the Period. */
|
||||
fast_period:1,/**< Use FastPeriodDivisor */
|
||||
count:3; /**< Retransmissions left. */
|
||||
|
||||
u32_t period_start; /**< Start of the current period. */
|
||||
|
||||
|
|
|
@ -324,7 +324,7 @@ static int send_friend_req(struct bt_mesh_lpn *lpn)
|
|||
.criteria = LPN_CRITERIA,
|
||||
.recv_delay = LPN_RECV_DELAY,
|
||||
.poll_to = LPN_POLL_TO,
|
||||
.prev_addr = lpn->old_friend,
|
||||
.prev_addr = sys_cpu_to_be16(lpn->old_friend),
|
||||
.num_elem = comp->elem_count,
|
||||
.lpn_counter = sys_cpu_to_be16(lpn->counter),
|
||||
};
|
||||
|
|
|
@ -413,6 +413,10 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers)
|
|||
provisioner_pb_gatt_enable();
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||
bt_mesh_friend_init();
|
||||
}
|
||||
|
||||
provisioner_en = true;
|
||||
|
||||
return 0;
|
||||
|
@ -437,6 +441,10 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers)
|
|||
bt_mesh_scan_disable();
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||
bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY);
|
||||
}
|
||||
|
||||
provisioner_en = false;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -789,13 +789,11 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
|
|||
return err;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
|
||||
bt_mesh_proxy_relay(&buf->b, dst)) {
|
||||
send_cb_finalize(cb, cb_data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bt_mesh_adv_send(buf, cb, cb_data);
|
||||
return 0;
|
||||
|
@ -935,8 +933,9 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
|
|||
#endif
|
||||
|
||||
/* Deliver to local network interface if necessary */
|
||||
if (bt_mesh_fixed_group_match(tx->ctx->addr) ||
|
||||
bt_mesh_elem_find(tx->ctx->addr)) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() &&
|
||||
(bt_mesh_fixed_group_match(tx->ctx->addr) ||
|
||||
bt_mesh_elem_find(tx->ctx->addr))) {
|
||||
if (cb && cb->start) {
|
||||
cb->start(0, 0, cb_data);
|
||||
}
|
||||
|
@ -1122,8 +1121,6 @@ static bool net_find_and_decrypt(const u8_t *data, size_t data_len,
|
|||
continue;
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_NODE
|
||||
if (bt_mesh_is_provisioned()) {
|
||||
#if (defined(CONFIG_BLE_MESH_LOW_POWER) || defined(CONFIG_BLE_MESH_FRIEND))
|
||||
if (!friend_decrypt(sub, data, data_len, rx, buf)) {
|
||||
rx->friend_cred = 1;
|
||||
|
@ -1132,8 +1129,6 @@ static bool net_find_and_decrypt(const u8_t *data, size_t data_len,
|
|||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_NODE */
|
||||
|
||||
if (NID(data) == sub->keys[0].nid &&
|
||||
!net_decrypt(sub, sub->keys[0].enc, sub->keys[0].privacy,
|
||||
|
@ -1308,6 +1303,17 @@ done:
|
|||
|
||||
#endif /* CONFIG_BLE_MESH_NODE */
|
||||
|
||||
void bt_mesh_net_header_parse(struct net_buf_simple *buf,
|
||||
struct bt_mesh_net_rx *rx)
|
||||
{
|
||||
rx->old_iv = (IVI(buf->data) != (bt_mesh.iv_index & 0x01));
|
||||
rx->ctl = CTL(buf->data);
|
||||
rx->ctx.recv_ttl = TTL(buf->data);
|
||||
rx->seq = SEQ(buf->data);
|
||||
rx->ctx.addr = SRC(buf->data);
|
||||
rx->ctx.recv_dst = DST(buf->data);
|
||||
}
|
||||
|
||||
int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if,
|
||||
struct bt_mesh_net_rx *rx, struct net_buf_simple *buf)
|
||||
{
|
||||
|
@ -1398,7 +1404,7 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi,
|
|||
enum bt_mesh_net_if net_if)
|
||||
{
|
||||
NET_BUF_SIMPLE_DEFINE(buf, 29);
|
||||
struct bt_mesh_net_rx rx = { .rssi = rssi };
|
||||
struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
|
||||
struct net_buf_simple_state state;
|
||||
|
||||
BT_DBG("rssi %d net_if %u", rssi, net_if);
|
||||
|
|
|
@ -224,6 +224,7 @@ enum {
|
|||
BLE_MESH_HB_PUB_PENDING,
|
||||
BLE_MESH_CFG_PENDING,
|
||||
BLE_MESH_MOD_PENDING,
|
||||
BLE_MESH_VA_PENDING,
|
||||
|
||||
/* Don't touch - intentionally last */
|
||||
BLE_MESH_FLAG_COUNT,
|
||||
|
@ -296,7 +297,6 @@ struct bt_mesh_net_rx {
|
|||
local_match: 1, /* Matched a local element */
|
||||
friend_match: 1; /* Matched an LPN we're friends for */
|
||||
u16_t msg_cache_idx; /* Index of entry in message cache */
|
||||
s8_t rssi;
|
||||
};
|
||||
|
||||
/* Encoding context for Network/Transport data */
|
||||
|
@ -366,6 +366,8 @@ u32_t bt_mesh_next_seq(void);
|
|||
void bt_mesh_net_start(void);
|
||||
|
||||
void bt_mesh_net_init(void);
|
||||
void bt_mesh_net_header_parse(struct net_buf_simple *buf,
|
||||
struct bt_mesh_net_rx *rx);
|
||||
|
||||
/* Friendship Credential Management */
|
||||
struct friend_cred {
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "adv.h"
|
||||
#include "net.h"
|
||||
#include "access.h"
|
||||
#include "friend.h"
|
||||
|
||||
#include "provisioner_prov.h"
|
||||
#include "proxy_client.h"
|
||||
|
@ -142,6 +143,10 @@ int provisioner_node_reset(int node_index)
|
|||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||
bt_mesh_friend_remove_lpn(node->unicast_addr);
|
||||
}
|
||||
|
||||
osi_free(mesh_nodes[node_index]);
|
||||
mesh_nodes[node_index] = NULL;
|
||||
|
||||
|
|
|
@ -917,16 +917,6 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client,
|
|||
|
||||
BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr);
|
||||
|
||||
if (client->filter_type == WHITELIST) {
|
||||
for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
|
||||
if (client->filter[i] == addr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (client->filter_type == BLACKLIST) {
|
||||
for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
|
||||
if (client->filter[i] == addr) {
|
||||
|
@ -937,6 +927,18 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (addr == BLE_MESH_ADDR_ALL_NODES) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (client->filter_type == WHITELIST) {
|
||||
for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
|
||||
if (client->filter[i] == addr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
* key: "mesh/v/xxxx/b" -> write/read to set/get VENDOR MODEL Bind AppKey List
|
||||
* key: "mesh/v/xxxx/s" -> write/read to set/get VENDOR MODEL Subscription List
|
||||
* key: "mesh/v/xxxx/p" -> write/read to set/get VENDOR MODEL Publication
|
||||
* key: "mesh/vaddr" -> write/read to set/get all virtual addresses
|
||||
* key: "mesh/va/xxxx" -> write/read to set/get the "xxxx" virtual address
|
||||
*/
|
||||
|
||||
#if CONFIG_BLE_MESH_SETTINGS
|
||||
|
@ -142,6 +144,13 @@ struct mod_pub_val {
|
|||
cred: 1;
|
||||
};
|
||||
|
||||
/* Virtual Address information */
|
||||
struct va_val {
|
||||
u16_t ref;
|
||||
u16_t addr;
|
||||
u8_t uuid[16];
|
||||
} __packed;
|
||||
|
||||
/* We need this so we don't overwrite app-hardcoded values in case FCB
|
||||
* contains a history of changes but then has a NULL at the end.
|
||||
*/
|
||||
|
@ -695,6 +704,66 @@ static int vnd_mod_set(const char *name)
|
|||
return model_set(true, name);
|
||||
}
|
||||
|
||||
#if CONFIG_BLE_MESH_LABEL_COUNT > 0
|
||||
static int va_set(const char *name)
|
||||
{
|
||||
struct net_buf_simple *buf = NULL;
|
||||
struct va_val va = {0};
|
||||
char get[16] = {'\0'};
|
||||
struct label *lab;
|
||||
size_t length;
|
||||
bool exist;
|
||||
int err = 0;
|
||||
u16_t i;
|
||||
|
||||
BT_DBG("%s", __func__);
|
||||
|
||||
buf = bt_mesh_get_core_settings_item(name);
|
||||
if (!buf) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
length = buf->len;
|
||||
|
||||
for (i = 0U; i < length / SETTINGS_ITEM_SIZE; i++) {
|
||||
u16_t index = net_buf_simple_pull_le16(buf);
|
||||
sprintf(get, "mesh/va/%04x", index);
|
||||
|
||||
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);
|
||||
goto free;
|
||||
}
|
||||
|
||||
if (exist == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (va.ref == 0) {
|
||||
BT_DBG("Ignore virtual address %s with ref = 0", get);
|
||||
goto free;
|
||||
}
|
||||
|
||||
lab = get_label(index);
|
||||
if (lab == NULL) {
|
||||
BT_WARN("%s, Out of labels buffers", __func__);
|
||||
err = -ENOBUFS;
|
||||
goto free;
|
||||
}
|
||||
|
||||
memcpy(lab->uuid, va.uuid, 16);
|
||||
lab->addr = va.addr;
|
||||
lab->ref = va.ref;
|
||||
|
||||
BT_DBG("Restore virtual address 0x%04x ref 0x%04x", index, lab->ref);
|
||||
}
|
||||
|
||||
free:
|
||||
bt_mesh_free_buf(buf);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
const struct bt_mesh_setting {
|
||||
const char *name;
|
||||
int (*func)(const char *name);
|
||||
|
@ -709,6 +778,9 @@ const struct bt_mesh_setting {
|
|||
{ "mesh/cfg", cfg_set },
|
||||
{ "mesh/sig", sig_mod_set },
|
||||
{ "mesh/vnd", vnd_mod_set },
|
||||
#if CONFIG_BLE_MESH_LABEL_COUNT > 0
|
||||
{ "mesh/vaddr", va_set },
|
||||
#endif
|
||||
};
|
||||
|
||||
int settings_core_load(void)
|
||||
|
@ -1331,6 +1403,52 @@ static void store_pending_mod(struct bt_mesh_model *model,
|
|||
}
|
||||
}
|
||||
|
||||
#define IS_VA_DEL(_label) ((_label)->ref == 0)
|
||||
static void store_pending_va(void)
|
||||
{
|
||||
struct va_val va = {0};
|
||||
char name[16] = {'\0'};
|
||||
struct label *lab;
|
||||
u16_t i;
|
||||
int err;
|
||||
|
||||
for (i = 0U; (lab = get_label(i)) != NULL; i++) {
|
||||
if (!bt_mesh_atomic_test_and_clear_bit(lab->flags,
|
||||
BLE_MESH_VA_CHANGED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf(name, "mesh/va/%04x", i);
|
||||
|
||||
if (IS_VA_DEL(lab)) {
|
||||
err = bt_mesh_save_core_settings(name, NULL, 0);
|
||||
} else {
|
||||
va.ref = lab->ref;
|
||||
va.addr = lab->addr;
|
||||
memcpy(va.uuid, lab->uuid, 16);
|
||||
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__,
|
||||
IS_VA_DEL(lab) ? "delete" : "store", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_VA_DEL(lab)) {
|
||||
err = bt_mesh_remove_core_settings_item("mesh/vaddr", i);
|
||||
} else {
|
||||
err = bt_mesh_add_core_settings_item("mesh/vaddr", i);
|
||||
}
|
||||
if (err) {
|
||||
BT_ERR("%s, Failed to %s 0x%04x in mesh/vaddr", __func__,
|
||||
IS_VA_DEL(lab) ? "delete" : "store", i);
|
||||
return;
|
||||
}
|
||||
|
||||
BT_DBG("%s virtual address 0x%04x", IS_VA_DEL(lab) ? "Delete" : "Store", i);
|
||||
}
|
||||
}
|
||||
|
||||
static void store_pending(struct k_work *work)
|
||||
{
|
||||
BT_DBG("%s", __func__);
|
||||
|
@ -1386,6 +1504,10 @@ static void store_pending(struct k_work *work)
|
|||
bt_mesh_save_core_settings("mesh/vnd", NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_VA_PENDING)) {
|
||||
store_pending_va();
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_store_rpl(struct bt_mesh_rpl *entry)
|
||||
|
@ -1570,6 +1692,11 @@ void bt_mesh_store_mod_pub(struct bt_mesh_model *model)
|
|||
schedule_store(BLE_MESH_MOD_PENDING);
|
||||
}
|
||||
|
||||
void bt_mesh_store_label(void)
|
||||
{
|
||||
schedule_store(BLE_MESH_VA_PENDING);
|
||||
}
|
||||
|
||||
int settings_core_init(void)
|
||||
{
|
||||
BT_DBG("%s", __func__);
|
||||
|
|
|
@ -28,6 +28,7 @@ void bt_mesh_store_cfg(void);
|
|||
void bt_mesh_store_mod_bind(struct bt_mesh_model *mod);
|
||||
void bt_mesh_store_mod_sub(struct bt_mesh_model *mod);
|
||||
void bt_mesh_store_mod_pub(struct bt_mesh_model *mod);
|
||||
void bt_mesh_store_label(void);
|
||||
|
||||
void bt_mesh_clear_net(void);
|
||||
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub);
|
||||
|
|
|
@ -139,7 +139,6 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu,
|
|||
|
||||
net_buf_add_mem(buf, sdu->data, sdu->len);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||
if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx,
|
||||
tx->src, tx->ctx->addr,
|
||||
|
@ -165,7 +164,6 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
send:
|
||||
return bt_mesh_net_send(tx, buf, cb, cb_data);
|
||||
|
@ -371,7 +369,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
|||
tx->ttl = net_tx->ctx->send_ttl;
|
||||
}
|
||||
|
||||
seq_zero = tx->seq_auth & 0x1fff;
|
||||
seq_zero = tx->seq_auth & TRANS_SEQ_ZERO_MASK;
|
||||
|
||||
BT_DBG("SeqZero 0x%04x", seq_zero);
|
||||
|
||||
|
@ -413,7 +411,6 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
|||
net_buf_add_mem(seg, sdu->data, len);
|
||||
net_buf_simple_pull(sdu, len);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||
enum bt_mesh_friend_pdu_type type;
|
||||
|
||||
|
@ -435,7 +432,6 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tx->seg[seg_o] = net_buf_ref(seg);
|
||||
|
||||
|
@ -461,12 +457,10 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
|||
send_cb_finalize(cb, cb_data);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
|
||||
bt_mesh_lpn_established()) {
|
||||
bt_mesh_lpn_poll();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -492,6 +486,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
|||
{
|
||||
const u8_t *key = NULL;
|
||||
u8_t *ad, role;
|
||||
u8_t aid;
|
||||
int err;
|
||||
|
||||
if (net_buf_simple_tailroom(msg) < 4) {
|
||||
|
@ -513,32 +508,13 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tx->ctx->app_idx == BLE_MESH_KEY_DEV) {
|
||||
key = bt_mesh_tx_devkey_get(role, tx->ctx->addr);
|
||||
if (!key) {
|
||||
BT_ERR("%s, Failed to get Device Key", __func__);
|
||||
return -EINVAL;
|
||||
err = bt_mesh_app_key_get(tx->sub, tx->ctx->app_idx, &key,
|
||||
&aid, role, tx->ctx->addr);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
tx->aid = 0U;
|
||||
} else {
|
||||
struct bt_mesh_app_key *app_key = NULL;
|
||||
|
||||
app_key = bt_mesh_tx_appkey_get(role, tx->ctx->app_idx, tx->ctx->net_idx);
|
||||
if (!app_key) {
|
||||
BT_ERR("%s, Failed to get AppKey", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (tx->sub->kr_phase == BLE_MESH_KR_PHASE_2 &&
|
||||
app_key->updated) {
|
||||
key = app_key->keys[1].val;
|
||||
tx->aid = app_key->keys[1].id;
|
||||
} else {
|
||||
key = app_key->keys[0].val;
|
||||
tx->aid = app_key->keys[0].id;
|
||||
}
|
||||
}
|
||||
tx->aid = aid;
|
||||
|
||||
if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) {
|
||||
tx->aszmic = 0U;
|
||||
|
@ -780,7 +756,7 @@ static struct seg_tx *seg_tx_lookup(u16_t seq_zero, u8_t obo, u16_t addr)
|
|||
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
||||
tx = &seg_tx[i];
|
||||
|
||||
if ((tx->seq_auth & 0x1fff) != seq_zero) {
|
||||
if ((tx->seq_auth & TRANS_SEQ_ZERO_MASK) != seq_zero) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -818,7 +794,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr,
|
|||
|
||||
seq_zero = net_buf_simple_pull_be16(buf);
|
||||
obo = seq_zero >> 15;
|
||||
seq_zero = (seq_zero >> 2) & 0x1fff;
|
||||
seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->friend_match) {
|
||||
BT_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst);
|
||||
|
@ -922,7 +898,6 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) {
|
||||
switch (ctl_op) {
|
||||
case TRANS_CTL_OP_FRIEND_POLL:
|
||||
|
@ -963,7 +938,6 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr,
|
|||
}
|
||||
}
|
||||
#endif /* CONFIG_BLE_MESH_LOW_POWER */
|
||||
}
|
||||
|
||||
BT_WARN("Unhandled TransOpCode 0x%02x", ctl_op);
|
||||
|
||||
|
@ -1079,7 +1053,7 @@ static int send_ack(struct bt_mesh_subnet *sub, u16_t src, u16_t dst,
|
|||
.src = obo ? bt_mesh_primary_addr() : src,
|
||||
.xmit = bt_mesh_net_transmit_get(),
|
||||
};
|
||||
u16_t seq_zero = *seq_auth & 0x1fff;
|
||||
u16_t seq_zero = *seq_auth & TRANS_SEQ_ZERO_MASK;
|
||||
u8_t buf[6];
|
||||
|
||||
BT_DBG("SeqZero 0x%04x Block 0x%08x OBO %u", seq_zero, block, obo);
|
||||
|
@ -1287,7 +1261,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx,
|
|||
|
||||
seq_zero = net_buf_simple_pull_be16(buf);
|
||||
seg_o = (seq_zero & 0x03) << 3;
|
||||
seq_zero = (seq_zero >> 2) & 0x1fff;
|
||||
seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK;
|
||||
seg_n = net_buf_simple_pull_u8(buf);
|
||||
seg_o |= seg_n >> 5;
|
||||
seg_n &= 0x1f;
|
||||
|
@ -1499,14 +1473,12 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
|
|||
* requested the Friend to send them. The messages must also
|
||||
* be encrypted using the Friend Credentials.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
|
||||
bt_mesh_lpn_established() && rx->net_if == BLE_MESH_NET_IF_ADV &&
|
||||
(!bt_mesh_lpn_waiting_update() || !rx->friend_cred)) {
|
||||
BT_WARN("Ignoring unexpected message in Low Power mode");
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the app-level state so the buffer can later be placed in
|
||||
* the Friend Queue.
|
||||
|
@ -1538,17 +1510,14 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
|
|||
* timer, in which case we want to reset the timer at this point.
|
||||
*
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
|
||||
(bt_mesh_lpn_timer() ||
|
||||
(bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()))) {
|
||||
bt_mesh_lpn_msg_received(rx);
|
||||
}
|
||||
}
|
||||
|
||||
net_buf_simple_restore(buf, &state);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->friend_match && !err) {
|
||||
if (seq_auth == TRANS_SEQ_AUTH_NVAL) {
|
||||
bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL,
|
||||
|
@ -1558,7 +1527,6 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx)
|
|||
seg_count, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1664,3 +1632,41 @@ void bt_mesh_heartbeat_send(void)
|
|||
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb),
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx,
|
||||
const u8_t **key, u8_t *aid, u8_t role, u16_t dst)
|
||||
{
|
||||
struct bt_mesh_app_key *app_key;
|
||||
|
||||
if (app_idx == BLE_MESH_KEY_DEV) {
|
||||
*key = bt_mesh_tx_devkey_get(role, dst);
|
||||
if (!*key) {
|
||||
BT_ERR("%s, Failed to get Device Key", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*aid = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!subnet) {
|
||||
BT_ERR("%s, Invalid subnet", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
app_key = bt_mesh_tx_appkey_get(role, app_idx, subnet->net_idx);
|
||||
if (!app_key) {
|
||||
BT_ERR("%s, Failed to get AppKey", __func__);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (subnet->kr_phase == BLE_MESH_KR_PHASE_2 && app_key->updated) {
|
||||
*key = app_key->keys[1].val;
|
||||
*aid = app_key->keys[1].id;
|
||||
} else {
|
||||
*key = app_key->keys[0].val;
|
||||
*aid = app_key->keys[0].id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#define BLE_MESH_TX_SDU_MAX (CONFIG_BLE_MESH_TX_SEG_MAX * 12)
|
||||
|
||||
#define TRANS_SEQ_ZERO_MASK ((u16_t)BIT_MASK(13))
|
||||
#define TRANS_CTL_OP_MASK ((u8_t)BIT_MASK(7))
|
||||
#define TRANS_CTL_OP(data) ((data)[0] & TRANS_CTL_OP_MASK)
|
||||
#define TRANS_CTL_HDR(op, seg) ((op & TRANS_CTL_OP_MASK) | (seg << 7))
|
||||
|
@ -101,4 +102,7 @@ void bt_mesh_rpl_clear(void);
|
|||
|
||||
void bt_mesh_heartbeat_send(void);
|
||||
|
||||
int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx,
|
||||
const u8_t **key, u8_t *aid, u8_t role, u16_t dst);
|
||||
|
||||
#endif /* _TRANSPORT_H_ */
|
||||
|
|
Loading…
Reference in a new issue