Merge branch 'bugfix/sync_zephyr_v2.0_ble_mesh_fixes' into 'master'
ble_mesh: sync Zephyr v2.0 ble mesh fixes Closes BLEMESH-56 See merge request espressif/esp-idf!6892
This commit is contained in:
commit
8ec233dfd0
26 changed files with 1240 additions and 437 deletions
|
@ -590,8 +590,7 @@ if BLE_MESH
|
||||||
endif # BLE_MESH_LOW_POWER
|
endif # BLE_MESH_LOW_POWER
|
||||||
|
|
||||||
config BLE_MESH_FRIEND
|
config BLE_MESH_FRIEND
|
||||||
bool "Support for acting as a Friend Node"
|
bool "Support for Friend feature"
|
||||||
depends on BLE_MESH_NODE
|
|
||||||
help
|
help
|
||||||
Enable this option to be able to act as a Friend Node.
|
Enable this option to be able to act as a Friend Node.
|
||||||
|
|
||||||
|
|
|
@ -356,16 +356,16 @@ typedef struct {
|
||||||
esp_ble_mesh_model_t *model;
|
esp_ble_mesh_model_t *model;
|
||||||
|
|
||||||
uint16_t publish_addr; /*!< Publish Address. */
|
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 ttl; /*!< Publish Time to Live. */
|
||||||
uint8_t retransmit; /*!< Retransmit Count & Interval Steps. */
|
uint8_t retransmit; /*!< Retransmit Count & Interval Steps. */
|
||||||
|
|
||||||
uint8_t period; /*!< Publish Period. */
|
uint8_t period; /*!< Publish Period. */
|
||||||
uint16_t period_div: 4, /*!< Divisor for the Period. */
|
uint8_t period_div:4, /*!< Divisor for the Period. */
|
||||||
cred: 1, /*!< Friendship Credentials Flag. */
|
fast_period:1, /*!< Use FastPeriodDivisor */
|
||||||
fast_period: 1, /*!< Use FastPeriodDivisor */
|
count:3; /*!< Retransmissions left. */
|
||||||
count: 3; /*!< Retransmissions left. */
|
|
||||||
|
|
||||||
uint32_t period_start; /*!< Start of the current period. */
|
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. */
|
/** Destination address of a received message. Not used for sending. */
|
||||||
uint16_t recv_dst;
|
uint16_t recv_dst;
|
||||||
|
|
||||||
|
/** RSSI of received packet. Not used for sending. */
|
||||||
|
int8_t recv_rssi;
|
||||||
|
|
||||||
/** Received TTL value. Not used for sending. */
|
/** Received TTL value. Not used for sending. */
|
||||||
uint8_t recv_ttl: 7;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_NODE
|
|
||||||
#if CONFIG_BLE_MESH_LOW_POWER
|
#if CONFIG_BLE_MESH_LOW_POWER
|
||||||
static void btc_ble_mesh_lpn_cb(u16_t friend_addr, bool established)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLE_MESH_FRIEND */
|
#endif /* CONFIG_BLE_MESH_FRIEND */
|
||||||
#endif /* CONFIG_BLE_MESH_NODE */
|
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
#if CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||||
static void btc_ble_mesh_proxy_client_adv_recv_cb(const bt_mesh_addr_t *addr,
|
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->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->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;
|
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 */
|
#endif /* CONFIG_BLE_MESH_NODE */
|
||||||
#if CONFIG_BLE_MESH_PROVISIONER
|
#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;
|
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;
|
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);
|
bt_mesh_prov_adv_pkt_cb_register(btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb);
|
||||||
#endif /* CONFIG_BLE_MESH_PROVISIONER */
|
#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
|
#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_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);
|
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;
|
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
|
* @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)
|
#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
|
* @def net_buf_pull_u8
|
||||||
* @brief Remove a 8-bit value from the beginning of the buffer
|
* @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)
|
#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;
|
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)
|
void *net_buf_simple_add(struct net_buf_simple *buf, size_t len)
|
||||||
{
|
{
|
||||||
u8_t *tail = net_buf_simple_tail(buf);
|
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);
|
return net_buf_alloc_len(pool, fixed->data_size, timeout);
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
BT_DBG("Publishing took %ums", elapsed);
|
||||||
|
|
||||||
if (elapsed > period) {
|
if (elapsed >= period) {
|
||||||
BT_WARN("Publication sending took longer than the period");
|
BT_WARN("Publication sending took longer than the period");
|
||||||
/* Return smallest positive number since 0 means disabled */
|
/* Return smallest positive number since 0 means disabled */
|
||||||
return K_MSEC(1);
|
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);
|
net_buf_simple_init(msg, 0);
|
||||||
|
|
||||||
if (opcode < 0x100) {
|
switch (BLE_MESH_MODEL_OP_LEN(opcode)) {
|
||||||
/* 1-byte OpCode */
|
case 1:
|
||||||
net_buf_simple_add_u8(msg, opcode);
|
net_buf_simple_add_u8(msg, opcode);
|
||||||
return;
|
break;
|
||||||
}
|
case 2:
|
||||||
|
|
||||||
if (opcode < 0x10000) {
|
|
||||||
/* 2-byte OpCode */
|
|
||||||
net_buf_simple_add_be16(msg, opcode);
|
net_buf_simple_add_be16(msg, opcode);
|
||||||
return;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3-byte OpCode */
|
|
||||||
net_buf_simple_add_u8(msg, ((opcode >> 16) & 0xff));
|
|
||||||
net_buf_simple_add_le16(msg, opcode & 0xffff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ready_to_send(u8_t role, u16_t dst)
|
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) || \
|
#if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \
|
||||||
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
CONFIG_BLE_MESH_GATT_PROXY_CLIENT
|
||||||
u16_t uuid;
|
u16_t uuid = 0x0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) {
|
if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) {
|
||||||
|
|
|
@ -46,15 +46,10 @@ struct bt_mesh_adv {
|
||||||
busy: 1;
|
busy: 1;
|
||||||
u8_t xmit;
|
u8_t xmit;
|
||||||
|
|
||||||
union {
|
/* For transport layer segment sending */
|
||||||
/* Address, used e.g. for Friend Queue messages */
|
struct {
|
||||||
u16_t addr;
|
u8_t attempts;
|
||||||
|
} seg;
|
||||||
/* For transport layer segment sending */
|
|
||||||
struct {
|
|
||||||
u8_t attempts;
|
|
||||||
} seg;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
|
typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id);
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
|
|
||||||
#define CID_NVAL 0xffff
|
#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;
|
s32_t config_msg_timeout;
|
||||||
|
|
||||||
static bt_mesh_config_client_t *cli;
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, op);
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, op);
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
int bt_mesh_cfg_relay_set(struct bt_mesh_msg_ctx *ctx, u8_t new_relay,
|
||||||
u8_t new_transmit)
|
u8_t new_transmit)
|
||||||
{
|
{
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_SET, 2);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
int bt_mesh_cfg_net_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx,
|
||||||
const u8_t net_key[16])
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !net_key) {
|
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,
|
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])
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !app_key) {
|
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,
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, op);
|
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,
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s",
|
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,
|
int bt_mesh_cfg_mod_pub_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr,
|
||||||
u16_t mod_id, u16_t cid)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
u16_t mod_id, u16_t cid,
|
||||||
struct bt_mesh_cfg_mod_pub *pub)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !pub) {
|
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,
|
int bt_mesh_cfg_hb_sub_set(struct bt_mesh_msg_ctx *ctx,
|
||||||
struct bt_mesh_cfg_hb_sub *sub)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !sub) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
int bt_mesh_cfg_hb_pub_set(struct bt_mesh_msg_ctx *ctx,
|
||||||
const struct bt_mesh_cfg_hb_pub *pub)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !pub) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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],
|
u16_t mod_id, u16_t cid, const u8_t label[16],
|
||||||
struct bt_mesh_cfg_mod_pub *pub)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !label || !pub) {
|
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,
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, op);
|
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,
|
int bt_mesh_cfg_net_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx,
|
||||||
const u8_t net_key[16])
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !net_key) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
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])
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr || !app_key) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
static int node_identity_op(u32_t op, struct bt_mesh_msg_ctx *ctx,
|
||||||
u16_t net_idx, u8_t identity)
|
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;
|
int err;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, op);
|
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,
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, op);
|
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,
|
static int kr_phase_op(u32_t op, struct bt_mesh_msg_ctx *ctx,
|
||||||
u16_t net_idx, u8_t transition)
|
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;
|
int err;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, op);
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
if (!ctx || !ctx->addr) {
|
||||||
|
|
|
@ -47,11 +47,7 @@
|
||||||
|
|
||||||
static struct bt_mesh_cfg_srv *conf;
|
static struct bt_mesh_cfg_srv *conf;
|
||||||
|
|
||||||
static struct label {
|
static struct label labels[CONFIG_BLE_MESH_LABEL_COUNT];
|
||||||
u16_t ref;
|
|
||||||
u16_t addr;
|
|
||||||
u8_t uuid[16];
|
|
||||||
} labels[CONFIG_BLE_MESH_LABEL_COUNT];
|
|
||||||
|
|
||||||
static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
|
static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem,
|
||||||
bool primary)
|
bool primary)
|
||||||
|
@ -451,7 +447,7 @@ static void app_key_add(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
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;
|
u16_t key_net_idx, key_app_idx;
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
|
||||||
|
@ -486,7 +482,7 @@ static void app_key_update(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
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;
|
u16_t key_net_idx, key_app_idx;
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
|
||||||
|
@ -549,7 +545,7 @@ static void app_key_del(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
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;
|
u16_t key_net_idx, key_app_idx;
|
||||||
struct bt_mesh_app_key *key;
|
struct bt_mesh_app_key *key;
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
@ -607,8 +603,8 @@ static void app_key_get(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4 +
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_LIST,
|
||||||
IDX_LEN(CONFIG_BLE_MESH_APP_KEY_COUNT));
|
3 + IDX_LEN(CONFIG_BLE_MESH_APP_KEY_COUNT));
|
||||||
u16_t get_idx, i, prev;
|
u16_t get_idx, i, prev;
|
||||||
u8_t status;
|
u8_t status;
|
||||||
|
|
||||||
|
@ -666,8 +662,7 @@ static void beacon_get(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
|
|
||||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
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,
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
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",
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
|
|
||||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
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,
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
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",
|
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,
|
static void send_gatt_proxy_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx)
|
struct bt_mesh_msg_ctx *ctx)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS);
|
bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS);
|
||||||
net_buf_simple_add_u8(&msg, bt_mesh_gatt_proxy_get());
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
|
|
||||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
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,
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
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",
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
|
||||||
|
|
||||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
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,
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4);
|
|
||||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
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",
|
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,
|
bool vnd, struct bt_mesh_model *mod,
|
||||||
u8_t status, u8_t *mod_id)
|
u8_t status, u8_t *mod_id)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 14 + 4);
|
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS);
|
bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS);
|
||||||
|
|
||||||
|
@ -1162,25 +1148,61 @@ send_status:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_LABEL_COUNT > 0
|
struct label *get_label(u16_t index)
|
||||||
static u8_t va_add(u8_t *label_uuid, u16_t *addr)
|
|
||||||
{
|
{
|
||||||
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;
|
int i;
|
||||||
|
|
||||||
|
if (free_slot != NULL) {
|
||||||
|
*free_slot = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(labels); i++) {
|
for (i = 0; i < ARRAY_SIZE(labels); i++) {
|
||||||
if (!labels[i].ref) {
|
if (labels[i].ref == 0) {
|
||||||
free_slot = &labels[i];
|
if (free_slot != NULL) {
|
||||||
|
*free_slot = &labels[i];
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memcmp(labels[i].uuid, label_uuid, 16)) {
|
if (!memcmp(labels[i].uuid, label_uuid, 16)) {
|
||||||
*addr = labels[i].addr;
|
match = &labels[i];
|
||||||
labels[i].ref++;
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
if (!free_slot) {
|
||||||
return STATUS_INSUFF_RESOURCES;
|
return STATUS_INSUFF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
@ -1192,23 +1214,25 @@ static u8_t va_add(u8_t *label_uuid, u16_t *addr)
|
||||||
free_slot->ref = 1U;
|
free_slot->ref = 1U;
|
||||||
free_slot->addr = *addr;
|
free_slot->addr = *addr;
|
||||||
memcpy(free_slot->uuid, label_uuid, 16);
|
memcpy(free_slot->uuid, label_uuid, 16);
|
||||||
|
va_store(free_slot);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8_t va_del(u8_t *label_uuid, u16_t *addr)
|
static u8_t va_del(u8_t *label_uuid, u16_t *addr)
|
||||||
{
|
{
|
||||||
int i;
|
struct label *update;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(labels); i++) {
|
update = va_find(label_uuid, NULL);
|
||||||
if (!memcmp(labels[i].uuid, label_uuid, 16)) {
|
if (update) {
|
||||||
if (addr) {
|
update->ref--;
|
||||||
*addr = labels[i].addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
labels[i].ref--;
|
if (addr) {
|
||||||
return STATUS_SUCCESS;
|
*addr = update->addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
va_store(update);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr) {
|
if (addr) {
|
||||||
|
@ -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,
|
u16_t elem_addr, u16_t sub_addr, u8_t *mod_id,
|
||||||
bool vnd)
|
bool vnd)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_STATUS, 9);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
|
|
||||||
|
|
||||||
BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status,
|
BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status,
|
||||||
elem_addr, sub_addr);
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4 +
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST,
|
||||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
5 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
||||||
struct bt_mesh_model *mod;
|
struct bt_mesh_model *mod;
|
||||||
struct bt_mesh_elem *elem;
|
struct bt_mesh_elem *elem;
|
||||||
u16_t addr, id;
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 7 + 4 +
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST_VND,
|
||||||
CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
7 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2);
|
||||||
struct bt_mesh_model *mod;
|
struct bt_mesh_model *mod;
|
||||||
struct bt_mesh_elem *elem;
|
struct bt_mesh_elem *elem;
|
||||||
u16_t company, addr, id;
|
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,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
u16_t idx, u8_t status)
|
u16_t idx, u8_t status)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_STATUS, 3);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4);
|
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_NET_KEY_STATUS);
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
NET_BUF_SIMPLE_DEFINE(msg,
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_LIST,
|
||||||
2 + 4 + IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT));
|
IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT));
|
||||||
u16_t prev, i;
|
u16_t prev, i;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_NET_KEY_LIST);
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
|
||||||
struct bt_mesh_subnet *sub;
|
struct bt_mesh_subnet *sub;
|
||||||
u8_t node_id;
|
u8_t node_id;
|
||||||
u16_t idx;
|
u16_t idx;
|
||||||
|
@ -2454,8 +2475,7 @@ static void node_identity_set(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
|
||||||
struct bt_mesh_subnet *sub;
|
struct bt_mesh_subnet *sub;
|
||||||
u8_t node_id;
|
u8_t node_id;
|
||||||
u16_t idx;
|
u16_t idx;
|
||||||
|
@ -2531,7 +2551,7 @@ static void mod_app_bind(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
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;
|
u16_t elem_addr, key_app_idx;
|
||||||
struct bt_mesh_model *mod;
|
struct bt_mesh_model *mod;
|
||||||
struct bt_mesh_elem *elem;
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
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;
|
u16_t elem_addr, key_app_idx;
|
||||||
struct bt_mesh_model *mod;
|
struct bt_mesh_model *mod;
|
||||||
struct bt_mesh_elem *elem;
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
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_model *mod;
|
||||||
struct bt_mesh_elem *elem;
|
struct bt_mesh_elem *elem;
|
||||||
u8_t *mod_id, status;
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4);
|
|
||||||
|
|
||||||
BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s",
|
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,
|
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,
|
static void send_friend_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx)
|
struct bt_mesh_msg_ctx *ctx)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS);
|
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 bt_mesh_msg_ctx *ctx,
|
||||||
struct net_buf_simple *buf)
|
struct net_buf_simple *buf)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_STATUS, 5);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4);
|
|
||||||
struct bt_mesh_friend *frnd;
|
struct bt_mesh_friend *frnd;
|
||||||
u16_t lpn_addr;
|
u16_t lpn_addr;
|
||||||
s32_t timeout;
|
s32_t timeout;
|
||||||
|
@ -2864,8 +2885,7 @@ static void send_krp_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx,
|
struct bt_mesh_msg_ctx *ctx,
|
||||||
u16_t idx, u8_t phase, u8_t status)
|
u16_t idx, u8_t phase, u8_t status)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_STATUS, 4);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4);
|
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_KRP_STATUS);
|
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 bt_mesh_msg_ctx *ctx, u8_t status,
|
||||||
struct hb_pub_param *orig_msg)
|
struct hb_pub_param *orig_msg)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (1 byte) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_STATUS, 10);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 1 + 10 + 4);
|
|
||||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||||
|
|
||||||
BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status);
|
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,
|
static void hb_sub_send_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx, u8_t status)
|
struct bt_mesh_msg_ctx *ctx, u8_t status)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_STATUS, 9);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4);
|
|
||||||
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
struct bt_mesh_cfg_srv *cfg = model->user_data;
|
||||||
u16_t period;
|
u16_t period;
|
||||||
s64_t uptime;
|
s64_t uptime;
|
||||||
|
|
|
@ -117,6 +117,17 @@
|
||||||
#define STATUS_UNSPECIFIED 0x10
|
#define STATUS_UNSPECIFIED 0x10
|
||||||
#define STATUS_INVALID_BINDING 0x11
|
#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_cfg_srv_init(struct bt_mesh_model *model, bool primary);
|
||||||
int bt_mesh_health_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);
|
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);
|
u8_t *bt_mesh_label_uuid_get(u16_t addr);
|
||||||
|
|
||||||
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
|
struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void);
|
||||||
|
|
|
@ -26,19 +26,18 @@
|
||||||
#include "access.h"
|
#include "access.h"
|
||||||
#include "foundation.h"
|
#include "foundation.h"
|
||||||
#include "friend.h"
|
#include "friend.h"
|
||||||
|
#include "client_common.h"
|
||||||
|
#include "provisioner_main.h"
|
||||||
|
|
||||||
#ifdef CONFIG_BLE_MESH_FRIEND
|
#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
|
/* 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.
|
* to resend the last sent PDU, which sits separately outside of the queue.
|
||||||
*/
|
*/
|
||||||
#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \
|
#define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \
|
||||||
CONFIG_BLE_MESH_FRIEND_LPN_COUNT)
|
CONFIG_BLE_MESH_FRIEND_LPN_COUNT)
|
||||||
|
|
||||||
#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), \
|
#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), struct friend_adv, adv)
|
||||||
struct friend_adv, adv)
|
|
||||||
|
|
||||||
/* PDUs from Friend to the LPN should only be transmitted once with the
|
/* PDUs from Friend to the LPN should only be transmitted once with the
|
||||||
* smallest possible interval (20ms).
|
* smallest possible interval (20ms).
|
||||||
|
@ -62,7 +61,7 @@ NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT,
|
||||||
|
|
||||||
static struct friend_adv {
|
static struct friend_adv {
|
||||||
struct bt_mesh_adv adv;
|
struct bt_mesh_adv adv;
|
||||||
u64_t seq_auth;
|
u16_t app_idx;
|
||||||
} adv_pool[FRIEND_BUF_COUNT];
|
} adv_pool[FRIEND_BUF_COUNT];
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -75,10 +74,22 @@ enum {
|
||||||
|
|
||||||
static void (*friend_cb)(bool establish, u16_t lpn_addr, u8_t reason);
|
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)
|
static struct bt_mesh_adv *adv_alloc(int id)
|
||||||
{
|
{
|
||||||
|
adv_pool[id].app_idx = BLE_MESH_KEY_UNUSED;
|
||||||
return &adv_pool[id].adv;
|
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 friend_pdu_info *info,
|
||||||
struct net_buf_simple *sdu)
|
struct net_buf_simple *sdu)
|
||||||
{
|
{
|
||||||
struct bt_mesh_subnet *sub;
|
|
||||||
const u8_t *enc, *priv;
|
|
||||||
struct net_buf *buf;
|
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,
|
buf = bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_alloc,
|
||||||
BLE_MESH_ADV_DATA,
|
BLE_MESH_ADV_DATA,
|
||||||
|
@ -333,22 +338,7 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLE_MESH_ADV(buf)->addr = info->src;
|
net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */
|
||||||
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));
|
|
||||||
|
|
||||||
if (info->ctl) {
|
if (info->ctl) {
|
||||||
net_buf_add_u8(buf, info->ttl | 0x80);
|
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);
|
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;
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
failed:
|
struct unseg_app_sdu_meta {
|
||||||
net_buf_unref(buf);
|
struct bt_mesh_net_rx net;
|
||||||
return NULL;
|
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,
|
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 net_buf_simple *sdu)
|
||||||
{
|
{
|
||||||
struct friend_pdu_info info;
|
struct friend_pdu_info info;
|
||||||
u32_t seq;
|
|
||||||
|
|
||||||
BT_DBG("LPN 0x%04x", frnd->lpn);
|
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.ctl = 1U;
|
||||||
info.ttl = 0U;
|
info.ttl = 0U;
|
||||||
|
|
||||||
seq = bt_mesh_next_seq();
|
memset(info.seq, 0, sizeof(info.seq));
|
||||||
info.seq[0] = seq >> 16;
|
|
||||||
info.seq[1] = seq >> 8;
|
|
||||||
info.seq[2] = seq;
|
|
||||||
|
|
||||||
info.iv_index = BLE_MESH_NET_IVI_TX;
|
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;
|
struct bt_mesh_ctl_friend_update *upd;
|
||||||
NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*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);
|
__ASSERT_NO_MSG(sub != NULL);
|
||||||
|
|
||||||
|
@ -450,6 +598,10 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, u8_t xact)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (encrypt_friend_pdu(frnd, buf, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (frnd->last) {
|
if (frnd->last) {
|
||||||
BT_DBG("Discarding last PDU");
|
BT_DBG("Discarding last PDU");
|
||||||
net_buf_unref(frnd->last);
|
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,
|
.send_ttl = BLE_MESH_TTL_MAX,
|
||||||
};
|
};
|
||||||
struct bt_mesh_net_tx tx = {
|
struct bt_mesh_net_tx tx = {
|
||||||
.sub = &bt_mesh.sub[0],
|
.sub = friend_subnet_get(frnd->net_idx),
|
||||||
.ctx = &ctx,
|
.ctx = &ctx,
|
||||||
.src = bt_mesh_primary_addr(),
|
.src = bt_mesh_primary_addr(),
|
||||||
.xmit = bt_mesh_net_transmit_get(),
|
.xmit = bt_mesh_net_transmit_get(),
|
||||||
|
@ -663,6 +815,11 @@ static void send_friend_clear(struct bt_mesh_friend *frnd)
|
||||||
|
|
||||||
BT_DBG("%s", __func__);
|
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,
|
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req,
|
||||||
sizeof(req), NULL, &clear_sent_cb, frnd);
|
sizeof(req), NULL, &clear_sent_cb, frnd);
|
||||||
}
|
}
|
||||||
|
@ -759,6 +916,10 @@ static void enqueue_offer(struct bt_mesh_friend *frnd, s8_t rssi)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (encrypt_friend_pdu(frnd, buf, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
frnd->counter++;
|
frnd->counter++;
|
||||||
|
|
||||||
if (frnd->last) {
|
if (frnd->last) {
|
||||||
|
@ -879,7 +1040,7 @@ init_friend:
|
||||||
frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr);
|
frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr);
|
||||||
|
|
||||||
BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums",
|
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:
|
* Spec says:
|
||||||
|
@ -894,18 +1055,40 @@ init_friend:
|
||||||
}
|
}
|
||||||
|
|
||||||
k_delayed_work_submit(&frnd->timer,
|
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,
|
friend_cred_create(rx->sub, frnd->lpn, frnd->lpn_counter,
|
||||||
frnd->counter);
|
frnd->counter);
|
||||||
|
|
||||||
enqueue_offer(frnd, rx->rssi);
|
enqueue_offer(frnd, rx->ctx.recv_rssi);
|
||||||
|
|
||||||
return 0;
|
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,
|
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)
|
u8_t seg_count)
|
||||||
{
|
{
|
||||||
struct bt_mesh_friend_seg *unassigned = NULL;
|
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++) {
|
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
||||||
struct bt_mesh_friend_seg *seg = &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 &&
|
if (is_seg(seg, src, seq_zero)) {
|
||||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
|
||||||
return seg;
|
return seg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unassigned && !buf) {
|
if (!unassigned && !sys_slist_peek_head(&seg->queue)) {
|
||||||
unassigned = seg;
|
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,
|
static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
||||||
enum bt_mesh_friend_pdu_type type,
|
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 bt_mesh_friend_seg *seg;
|
||||||
struct friend_adv *adv;
|
|
||||||
|
|
||||||
BT_DBG("type %u", type);
|
BT_DBG("type %u", type);
|
||||||
|
|
||||||
|
@ -950,11 +1131,11 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
adv = FRIEND_ADV(buf);
|
u16_t seq_zero = (((buf->data[10] << 8 | buf->data[11]) >> 2) & TRANS_SEQ_ZERO_MASK);
|
||||||
seg = get_seg(frnd, BLE_MESH_ADV(buf)->addr, &adv->seq_auth, seg_count);
|
|
||||||
|
seg = get_seg(frnd, src, seq_zero, seg_count);
|
||||||
if (!seg) {
|
if (!seg) {
|
||||||
BT_ERR("%s, No free friend segment RX contexts for 0x%04x",
|
BT_ERR("No free friend segment RX contexts for 0x%04x", src);
|
||||||
__func__, BLE_MESH_ADV(buf)->addr);
|
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -966,16 +1147,9 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
||||||
enqueue_update(frnd, 1);
|
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);
|
sys_slist_merge_slist(&frnd->queue, &seg->queue);
|
||||||
|
|
||||||
|
frnd->queue_size += seg->seg_count;
|
||||||
seg->seg_count = 0U;
|
seg->seg_count = 0U;
|
||||||
} else {
|
} else {
|
||||||
/* Mark the buffer as having more to come after it */
|
/* Mark the buffer as having more to come after it */
|
||||||
|
@ -1052,6 +1226,10 @@ static void friend_timeout(struct k_work *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (encrypt_friend_pdu(frnd, frnd->last, false)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear the flag we use for segment tracking */
|
/* Clear the flag we use for segment tracking */
|
||||||
frnd->last->flags &= ~NET_BUF_FRAGS;
|
frnd->last->flags &= ~NET_BUF_FRAGS;
|
||||||
frnd->last->frags = NULL;
|
frnd->last->frags = NULL;
|
||||||
|
@ -1094,6 +1272,42 @@ int bt_mesh_friend_init(void)
|
||||||
return 0;
|
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,
|
static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth,
|
||||||
u16_t src)
|
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)) {
|
cur != NULL; prev = cur, cur = sys_slist_peek_next(cur)) {
|
||||||
struct net_buf *buf = (void *)cur;
|
struct net_buf *buf = (void *)cur;
|
||||||
|
|
||||||
if (BLE_MESH_ADV(buf)->addr == src &&
|
if (is_segack(buf, seq_auth, src)) {
|
||||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
|
||||||
BT_DBG("Removing old ack from Friend Queue");
|
BT_DBG("Removing old ack from Friend Queue");
|
||||||
|
|
||||||
sys_slist_remove(&frnd->queue, prev, cur);
|
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 friend_pdu_info info;
|
||||||
struct net_buf *buf;
|
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);
|
BT_DBG("LPN 0x%04x queue_size %u", frnd->lpn, frnd->queue_size);
|
||||||
|
|
||||||
if (type == BLE_MESH_FRIEND_PDU_SINGLE && seq_auth) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seq_auth) {
|
enqueue_friend_pdu(frnd, type, info.src, seg_count, buf);
|
||||||
FRIEND_ADV(buf)->seq_auth = *seq_auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
enqueue_friend_pdu(frnd, type, seg_count, buf);
|
|
||||||
|
|
||||||
BT_DBG("Queued message for LPN 0x%04x, queue_size %u",
|
BT_DBG("Queued message for LPN 0x%04x, queue_size %u",
|
||||||
frnd->lpn, frnd->queue_size);
|
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 friend_pdu_info info;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
u32_t seq;
|
|
||||||
|
|
||||||
BT_DBG("LPN 0x%04x", frnd->lpn);
|
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.ttl = tx->ctx->send_ttl;
|
||||||
info.ctl = (tx->ctx->app_idx == BLE_MESH_KEY_UNUSED);
|
info.ctl = (tx->ctx->app_idx == BLE_MESH_KEY_UNUSED);
|
||||||
|
|
||||||
seq = bt_mesh_next_seq();
|
info.seq[0] = (bt_mesh.seq >> 16);
|
||||||
info.seq[0] = seq >> 16;
|
info.seq[1] = (bt_mesh.seq >> 8);
|
||||||
info.seq[1] = seq >> 8;
|
info.seq[2] = bt_mesh.seq;
|
||||||
info.seq[2] = seq;
|
|
||||||
|
|
||||||
info.iv_index = BLE_MESH_NET_IVI_TX;
|
info.iv_index = BLE_MESH_NET_IVI_TX;
|
||||||
|
|
||||||
|
@ -1203,11 +1418,15 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seq_auth) {
|
if (type == BLE_MESH_FRIEND_PDU_SINGLE && !info.ctl) {
|
||||||
FRIEND_ADV(buf)->seq_auth = *seq_auth;
|
/* 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);
|
BT_DBG("Queued message for LPN 0x%04x", frnd->lpn);
|
||||||
}
|
}
|
||||||
|
@ -1270,17 +1489,11 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, u16_t addr,
|
||||||
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
||||||
struct bt_mesh_friend_seg *seg = &frnd->seg[i];
|
struct bt_mesh_friend_seg *seg = &frnd->seg[i];
|
||||||
|
|
||||||
if (seq_auth) {
|
if (seq_auth && is_seg(seg, addr, *seq_auth & TRANS_SEQ_ZERO_MASK)) {
|
||||||
struct net_buf *buf;
|
|
||||||
|
|
||||||
/* If there's a segment queue for this message then the
|
/* If there's a segment queue for this message then the
|
||||||
* space verification has already happened.
|
* space verification has already happened.
|
||||||
*/
|
*/
|
||||||
buf = (void *)sys_slist_peek_head(&seg->queue);
|
return true;
|
||||||
if (buf && BLE_MESH_ADV(buf)->addr == addr &&
|
|
||||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
total += seg->seg_count;
|
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++) {
|
for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) {
|
||||||
struct bt_mesh_friend_seg *seg = &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 (!is_seg(seg, src, *seq_auth & TRANS_SEQ_ZERO_MASK)) {
|
||||||
if (!buf) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BLE_MESH_ADV(buf)->addr != src) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FRIEND_ADV(buf)->seq_auth != *seq_auth) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1473,8 +1676,19 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src,
|
||||||
|
|
||||||
purge_buffers(&seg->queue);
|
purge_buffers(&seg->queue);
|
||||||
seg->seg_count = 0U;
|
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 */
|
#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);
|
int bt_mesh_friend_init(void);
|
||||||
|
|
||||||
|
void bt_mesh_friend_remove_lpn(u16_t lpn_addr);
|
||||||
|
|
||||||
#endif /* _FRIEND_H_ */
|
#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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
int bt_mesh_health_attention_set(struct bt_mesh_msg_ctx *ctx,
|
||||||
u8_t attention, bool need_ack)
|
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;
|
u32_t opcode;
|
||||||
int err;
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
int bt_mesh_health_period_set(struct bt_mesh_msg_ctx *ctx,
|
||||||
u8_t divisor, bool need_ack)
|
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;
|
u32_t opcode;
|
||||||
int err;
|
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,
|
int bt_mesh_health_fault_test(struct bt_mesh_msg_ctx *ctx,
|
||||||
u16_t cid, u8_t test_id, bool need_ack)
|
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;
|
u32_t opcode;
|
||||||
int err;
|
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,
|
int bt_mesh_health_fault_clear(struct bt_mesh_msg_ctx *ctx,
|
||||||
u16_t cid, bool need_ack)
|
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;
|
u32_t opcode;
|
||||||
int err;
|
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)
|
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;
|
int err;
|
||||||
|
|
||||||
if (!ctx || !ctx->addr) {
|
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,
|
static void send_attention_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx)
|
struct bt_mesh_msg_ctx *ctx)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
struct bt_mesh_health_srv *srv = model->user_data;
|
struct bt_mesh_health_srv *srv = model->user_data;
|
||||||
u8_t time;
|
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,
|
static void send_health_period_status(struct bt_mesh_model *model,
|
||||||
struct bt_mesh_msg_ctx *ctx)
|
struct bt_mesh_msg_ctx *ctx)
|
||||||
{
|
{
|
||||||
/* Needed size: opcode (2 bytes) + msg + MIC */
|
BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_STATUS, 1);
|
||||||
NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4);
|
|
||||||
|
|
||||||
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS);
|
bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS);
|
||||||
net_buf_simple_add_u8(&msg, model->pub->period_div);
|
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. */
|
/** Destination address of a received message. Not used for sending. */
|
||||||
u16_t recv_dst;
|
u16_t recv_dst;
|
||||||
|
|
||||||
|
/** RSSI of received packet. Not used for sending. */
|
||||||
|
s8_t recv_rssi;
|
||||||
|
|
||||||
/** Received TTL value. Not used for sending. */
|
/** Received TTL value. Not used for sending. */
|
||||||
u8_t recv_ttl: 7;
|
u8_t recv_ttl: 7;
|
||||||
|
|
||||||
|
@ -185,6 +188,56 @@ struct bt_mesh_model_op {
|
||||||
/** Helper to define an empty model array */
|
/** Helper to define an empty model array */
|
||||||
#define BLE_MESH_MODEL_NONE ((struct bt_mesh_model []){})
|
#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) \
|
#define BLE_MESH_MODEL(_id, _op, _pub, _user_data) \
|
||||||
{ \
|
{ \
|
||||||
.id = (_id), \
|
.id = (_id), \
|
||||||
|
@ -282,15 +335,15 @@ struct bt_mesh_model_pub {
|
||||||
struct bt_mesh_model *mod;
|
struct bt_mesh_model *mod;
|
||||||
|
|
||||||
u16_t addr; /**< Publish Address. */
|
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 ttl; /**< Publish Time to Live. */
|
||||||
u8_t retransmit; /**< Retransmit Count & Interval Steps. */
|
u8_t retransmit; /**< Retransmit Count & Interval Steps. */
|
||||||
u8_t period; /**< Publish Period. */
|
u8_t period; /**< Publish Period. */
|
||||||
u16_t period_div: 4, /**< Divisor for the Period. */
|
u8_t period_div:4, /**< Divisor for the Period. */
|
||||||
cred: 1, /**< Friendship Credentials Flag. */
|
fast_period:1,/**< Use FastPeriodDivisor */
|
||||||
fast_period: 1, /**< Use FastPeriodDivisor */
|
count:3; /**< Retransmissions left. */
|
||||||
count: 3; /**< Retransmissions left. */
|
|
||||||
|
|
||||||
u32_t period_start; /**< Start of the current period. */
|
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,
|
.criteria = LPN_CRITERIA,
|
||||||
.recv_delay = LPN_RECV_DELAY,
|
.recv_delay = LPN_RECV_DELAY,
|
||||||
.poll_to = LPN_POLL_TO,
|
.poll_to = LPN_POLL_TO,
|
||||||
.prev_addr = lpn->old_friend,
|
.prev_addr = sys_cpu_to_be16(lpn->old_friend),
|
||||||
.num_elem = comp->elem_count,
|
.num_elem = comp->elem_count,
|
||||||
.lpn_counter = sys_cpu_to_be16(lpn->counter),
|
.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();
|
provisioner_pb_gatt_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||||
|
bt_mesh_friend_init();
|
||||||
|
}
|
||||||
|
|
||||||
provisioner_en = true;
|
provisioner_en = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -437,6 +441,10 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers)
|
||||||
bt_mesh_scan_disable();
|
bt_mesh_scan_disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
||||||
|
bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY);
|
||||||
|
}
|
||||||
|
|
||||||
provisioner_en = false;
|
provisioner_en = false;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -789,12 +789,10 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) &&
|
bt_mesh_proxy_relay(&buf->b, dst)) {
|
||||||
bt_mesh_proxy_relay(&buf->b, dst)) {
|
send_cb_finalize(cb, cb_data);
|
||||||
send_cb_finalize(cb, cb_data);
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_mesh_adv_send(buf, cb, cb_data);
|
bt_mesh_adv_send(buf, cb, cb_data);
|
||||||
|
@ -935,8 +933,9 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Deliver to local network interface if necessary */
|
/* Deliver to local network interface if necessary */
|
||||||
if (bt_mesh_fixed_group_match(tx->ctx->addr) ||
|
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() &&
|
||||||
bt_mesh_elem_find(tx->ctx->addr)) {
|
(bt_mesh_fixed_group_match(tx->ctx->addr) ||
|
||||||
|
bt_mesh_elem_find(tx->ctx->addr))) {
|
||||||
if (cb && cb->start) {
|
if (cb && cb->start) {
|
||||||
cb->start(0, 0, cb_data);
|
cb->start(0, 0, cb_data);
|
||||||
}
|
}
|
||||||
|
@ -1122,18 +1121,14 @@ static bool net_find_and_decrypt(const u8_t *data, size_t data_len,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BLE_MESH_NODE
|
|
||||||
if (bt_mesh_is_provisioned()) {
|
|
||||||
#if (defined(CONFIG_BLE_MESH_LOW_POWER) || defined(CONFIG_BLE_MESH_FRIEND))
|
#if (defined(CONFIG_BLE_MESH_LOW_POWER) || defined(CONFIG_BLE_MESH_FRIEND))
|
||||||
if (!friend_decrypt(sub, data, data_len, rx, buf)) {
|
if (!friend_decrypt(sub, data, data_len, rx, buf)) {
|
||||||
rx->friend_cred = 1;
|
rx->friend_cred = 1;
|
||||||
rx->ctx.net_idx = sub->net_idx;
|
rx->ctx.net_idx = sub->net_idx;
|
||||||
rx->sub = sub;
|
rx->sub = sub;
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLE_MESH_NODE */
|
#endif
|
||||||
|
|
||||||
if (NID(data) == sub->keys[0].nid &&
|
if (NID(data) == sub->keys[0].nid &&
|
||||||
!net_decrypt(sub, sub->keys[0].enc, sub->keys[0].privacy,
|
!net_decrypt(sub, sub->keys[0].enc, sub->keys[0].privacy,
|
||||||
|
@ -1308,6 +1303,17 @@ done:
|
||||||
|
|
||||||
#endif /* CONFIG_BLE_MESH_NODE */
|
#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,
|
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)
|
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)
|
enum bt_mesh_net_if net_if)
|
||||||
{
|
{
|
||||||
NET_BUF_SIMPLE_DEFINE(buf, 29);
|
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;
|
struct net_buf_simple_state state;
|
||||||
|
|
||||||
BT_DBG("rssi %d net_if %u", rssi, net_if);
|
BT_DBG("rssi %d net_if %u", rssi, net_if);
|
||||||
|
|
|
@ -224,6 +224,7 @@ enum {
|
||||||
BLE_MESH_HB_PUB_PENDING,
|
BLE_MESH_HB_PUB_PENDING,
|
||||||
BLE_MESH_CFG_PENDING,
|
BLE_MESH_CFG_PENDING,
|
||||||
BLE_MESH_MOD_PENDING,
|
BLE_MESH_MOD_PENDING,
|
||||||
|
BLE_MESH_VA_PENDING,
|
||||||
|
|
||||||
/* Don't touch - intentionally last */
|
/* Don't touch - intentionally last */
|
||||||
BLE_MESH_FLAG_COUNT,
|
BLE_MESH_FLAG_COUNT,
|
||||||
|
@ -296,7 +297,6 @@ struct bt_mesh_net_rx {
|
||||||
local_match: 1, /* Matched a local element */
|
local_match: 1, /* Matched a local element */
|
||||||
friend_match: 1; /* Matched an LPN we're friends for */
|
friend_match: 1; /* Matched an LPN we're friends for */
|
||||||
u16_t msg_cache_idx; /* Index of entry in message cache */
|
u16_t msg_cache_idx; /* Index of entry in message cache */
|
||||||
s8_t rssi;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Encoding context for Network/Transport data */
|
/* 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_start(void);
|
||||||
|
|
||||||
void bt_mesh_net_init(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 */
|
/* Friendship Credential Management */
|
||||||
struct friend_cred {
|
struct friend_cred {
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "adv.h"
|
#include "adv.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "access.h"
|
#include "access.h"
|
||||||
|
#include "friend.h"
|
||||||
|
|
||||||
#include "provisioner_prov.h"
|
#include "provisioner_prov.h"
|
||||||
#include "proxy_client.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]);
|
osi_free(mesh_nodes[node_index]);
|
||||||
mesh_nodes[node_index] = NULL;
|
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);
|
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) {
|
if (client->filter_type == BLACKLIST) {
|
||||||
for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
|
for (i = 0; i < ARRAY_SIZE(client->filter); i++) {
|
||||||
if (client->filter[i] == addr) {
|
if (client->filter[i] == addr) {
|
||||||
|
@ -937,6 +927,18 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client,
|
||||||
return true;
|
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;
|
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/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/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/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
|
#if CONFIG_BLE_MESH_SETTINGS
|
||||||
|
@ -142,6 +144,13 @@ struct mod_pub_val {
|
||||||
cred: 1;
|
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
|
/* 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.
|
* 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);
|
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 struct bt_mesh_setting {
|
||||||
const char *name;
|
const char *name;
|
||||||
int (*func)(const char *name);
|
int (*func)(const char *name);
|
||||||
|
@ -709,6 +778,9 @@ const struct bt_mesh_setting {
|
||||||
{ "mesh/cfg", cfg_set },
|
{ "mesh/cfg", cfg_set },
|
||||||
{ "mesh/sig", sig_mod_set },
|
{ "mesh/sig", sig_mod_set },
|
||||||
{ "mesh/vnd", vnd_mod_set },
|
{ "mesh/vnd", vnd_mod_set },
|
||||||
|
#if CONFIG_BLE_MESH_LABEL_COUNT > 0
|
||||||
|
{ "mesh/vaddr", va_set },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int settings_core_load(void)
|
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)
|
static void store_pending(struct k_work *work)
|
||||||
{
|
{
|
||||||
BT_DBG("%s", __func__);
|
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);
|
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)
|
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);
|
schedule_store(BLE_MESH_MOD_PENDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bt_mesh_store_label(void)
|
||||||
|
{
|
||||||
|
schedule_store(BLE_MESH_VA_PENDING);
|
||||||
|
}
|
||||||
|
|
||||||
int settings_core_init(void)
|
int settings_core_init(void)
|
||||||
{
|
{
|
||||||
BT_DBG("%s", __func__);
|
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_bind(struct bt_mesh_model *mod);
|
||||||
void bt_mesh_store_mod_sub(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_mod_pub(struct bt_mesh_model *mod);
|
||||||
|
void bt_mesh_store_label(void);
|
||||||
|
|
||||||
void bt_mesh_clear_net(void);
|
void bt_mesh_clear_net(void);
|
||||||
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub);
|
void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub);
|
||||||
|
|
|
@ -139,32 +139,30 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu,
|
||||||
|
|
||||||
net_buf_add_mem(buf, sdu->data, sdu->len);
|
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 (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx,
|
||||||
if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx,
|
tx->src, tx->ctx->addr,
|
||||||
tx->src, tx->ctx->addr,
|
NULL, 1)) {
|
||||||
NULL, 1)) {
|
if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
|
||||||
if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
|
BT_ERR("Not enough space in Friend Queue");
|
||||||
BT_ERR("Not enough space in Friend Queue");
|
|
||||||
net_buf_unref(buf);
|
|
||||||
return -ENOBUFS;
|
|
||||||
} else {
|
|
||||||
BT_WARN("No space in Friend Queue");
|
|
||||||
goto send;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bt_mesh_friend_enqueue_tx(tx, BLE_MESH_FRIEND_PDU_SINGLE,
|
|
||||||
NULL, 1, &buf->b) &&
|
|
||||||
BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
|
|
||||||
/* PDUs for a specific Friend should only go
|
|
||||||
* out through the Friend Queue.
|
|
||||||
*/
|
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
send_cb_finalize(cb, cb_data);
|
return -ENOBUFS;
|
||||||
return 0;
|
} else {
|
||||||
|
BT_WARN("No space in Friend Queue");
|
||||||
|
goto send;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bt_mesh_friend_enqueue_tx(tx, BLE_MESH_FRIEND_PDU_SINGLE,
|
||||||
|
NULL, 1, &buf->b) &&
|
||||||
|
BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) {
|
||||||
|
/* PDUs for a specific Friend should only go
|
||||||
|
* out through the Friend Queue.
|
||||||
|
*/
|
||||||
|
net_buf_unref(buf);
|
||||||
|
send_cb_finalize(cb, cb_data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send:
|
send:
|
||||||
|
@ -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;
|
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);
|
BT_DBG("SeqZero 0x%04x", seq_zero);
|
||||||
|
|
||||||
|
@ -413,27 +411,25 @@ 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_add_mem(seg, sdu->data, len);
|
||||||
net_buf_simple_pull(sdu, 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)) {
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) {
|
enum bt_mesh_friend_pdu_type type;
|
||||||
enum bt_mesh_friend_pdu_type type;
|
|
||||||
|
|
||||||
if (seg_o == tx->seg_n) {
|
if (seg_o == tx->seg_n) {
|
||||||
type = BLE_MESH_FRIEND_PDU_COMPLETE;
|
type = BLE_MESH_FRIEND_PDU_COMPLETE;
|
||||||
} else {
|
} else {
|
||||||
type = BLE_MESH_FRIEND_PDU_PARTIAL;
|
type = BLE_MESH_FRIEND_PDU_PARTIAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bt_mesh_friend_enqueue_tx(net_tx, type,
|
if (bt_mesh_friend_enqueue_tx(net_tx, type,
|
||||||
&tx->seq_auth,
|
&tx->seq_auth,
|
||||||
tx->seg_n + 1,
|
tx->seg_n + 1,
|
||||||
&seg->b) &&
|
&seg->b) &&
|
||||||
BLE_MESH_ADDR_IS_UNICAST(net_tx->ctx->addr)) {
|
BLE_MESH_ADDR_IS_UNICAST(net_tx->ctx->addr)) {
|
||||||
/* PDUs for a specific Friend should only go
|
/* PDUs for a specific Friend should only go
|
||||||
* out through the Friend Queue.
|
* out through the Friend Queue.
|
||||||
*/
|
*/
|
||||||
net_buf_unref(seg);
|
net_buf_unref(seg);
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,11 +457,9 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu,
|
||||||
send_cb_finalize(cb, cb_data);
|
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) &&
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
|
bt_mesh_lpn_established()) {
|
||||||
bt_mesh_lpn_established()) {
|
bt_mesh_lpn_poll();
|
||||||
bt_mesh_lpn_poll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
const u8_t *key = NULL;
|
||||||
u8_t *ad, role;
|
u8_t *ad, role;
|
||||||
|
u8_t aid;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (net_buf_simple_tailroom(msg) < 4) {
|
if (net_buf_simple_tailroom(msg) < 4) {
|
||||||
|
@ -513,33 +508,14 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx->ctx->app_idx == BLE_MESH_KEY_DEV) {
|
err = bt_mesh_app_key_get(tx->sub, tx->ctx->app_idx, &key,
|
||||||
key = bt_mesh_tx_devkey_get(role, tx->ctx->addr);
|
&aid, role, tx->ctx->addr);
|
||||||
if (!key) {
|
if (err) {
|
||||||
BT_ERR("%s, Failed to get Device Key", __func__);
|
return err;
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) {
|
||||||
tx->aszmic = 0U;
|
tx->aszmic = 0U;
|
||||||
} else {
|
} else {
|
||||||
|
@ -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++) {
|
for (i = 0; i < ARRAY_SIZE(seg_tx); i++) {
|
||||||
tx = &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;
|
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);
|
seq_zero = net_buf_simple_pull_be16(buf);
|
||||||
obo = seq_zero >> 15;
|
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) {
|
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->friend_match) {
|
||||||
BT_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst);
|
BT_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst);
|
||||||
|
@ -922,49 +898,47 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) {
|
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) {
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) {
|
switch (ctl_op) {
|
||||||
switch (ctl_op) {
|
case TRANS_CTL_OP_FRIEND_POLL:
|
||||||
case TRANS_CTL_OP_FRIEND_POLL:
|
return bt_mesh_friend_poll(rx, buf);
|
||||||
return bt_mesh_friend_poll(rx, buf);
|
case TRANS_CTL_OP_FRIEND_REQ:
|
||||||
case TRANS_CTL_OP_FRIEND_REQ:
|
return bt_mesh_friend_req(rx, buf);
|
||||||
return bt_mesh_friend_req(rx, buf);
|
case TRANS_CTL_OP_FRIEND_CLEAR:
|
||||||
case TRANS_CTL_OP_FRIEND_CLEAR:
|
return bt_mesh_friend_clear(rx, buf);
|
||||||
return bt_mesh_friend_clear(rx, buf);
|
case TRANS_CTL_OP_FRIEND_CLEAR_CFM:
|
||||||
case TRANS_CTL_OP_FRIEND_CLEAR_CFM:
|
return bt_mesh_friend_clear_cfm(rx, buf);
|
||||||
return bt_mesh_friend_clear_cfm(rx, buf);
|
case TRANS_CTL_OP_FRIEND_SUB_ADD:
|
||||||
case TRANS_CTL_OP_FRIEND_SUB_ADD:
|
return bt_mesh_friend_sub_add(rx, buf);
|
||||||
return bt_mesh_friend_sub_add(rx, buf);
|
case TRANS_CTL_OP_FRIEND_SUB_REM:
|
||||||
case TRANS_CTL_OP_FRIEND_SUB_REM:
|
return bt_mesh_friend_sub_rem(rx, buf);
|
||||||
return bt_mesh_friend_sub_rem(rx, buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BLE_MESH_LOW_POWER)
|
#if defined(CONFIG_BLE_MESH_LOW_POWER)
|
||||||
if (ctl_op == TRANS_CTL_OP_FRIEND_OFFER) {
|
if (ctl_op == TRANS_CTL_OP_FRIEND_OFFER) {
|
||||||
return bt_mesh_lpn_friend_offer(rx, buf);
|
return bt_mesh_lpn_friend_offer(rx, buf);
|
||||||
}
|
|
||||||
|
|
||||||
if (rx->ctx.addr == bt_mesh.lpn.frnd) {
|
|
||||||
if (ctl_op == TRANS_CTL_OP_FRIEND_CLEAR_CFM) {
|
|
||||||
return bt_mesh_lpn_friend_clear_cfm(rx, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rx->friend_cred) {
|
|
||||||
BT_WARN("Message from friend with wrong credentials");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ctl_op) {
|
|
||||||
case TRANS_CTL_OP_FRIEND_UPDATE:
|
|
||||||
return bt_mesh_lpn_friend_update(rx, buf);
|
|
||||||
case TRANS_CTL_OP_FRIEND_SUB_CFM:
|
|
||||||
return bt_mesh_lpn_friend_sub_cfm(rx, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_BLE_MESH_LOW_POWER */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rx->ctx.addr == bt_mesh.lpn.frnd) {
|
||||||
|
if (ctl_op == TRANS_CTL_OP_FRIEND_CLEAR_CFM) {
|
||||||
|
return bt_mesh_lpn_friend_clear_cfm(rx, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rx->friend_cred) {
|
||||||
|
BT_WARN("Message from friend with wrong credentials");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ctl_op) {
|
||||||
|
case TRANS_CTL_OP_FRIEND_UPDATE:
|
||||||
|
return bt_mesh_lpn_friend_update(rx, buf);
|
||||||
|
case TRANS_CTL_OP_FRIEND_SUB_CFM:
|
||||||
|
return bt_mesh_lpn_friend_sub_cfm(rx, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLE_MESH_LOW_POWER */
|
||||||
|
|
||||||
BT_WARN("Unhandled TransOpCode 0x%02x", ctl_op);
|
BT_WARN("Unhandled TransOpCode 0x%02x", ctl_op);
|
||||||
|
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
@ -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,
|
.src = obo ? bt_mesh_primary_addr() : src,
|
||||||
.xmit = bt_mesh_net_transmit_get(),
|
.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];
|
u8_t buf[6];
|
||||||
|
|
||||||
BT_DBG("SeqZero 0x%04x Block 0x%08x OBO %u", seq_zero, block, obo);
|
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);
|
seq_zero = net_buf_simple_pull_be16(buf);
|
||||||
seg_o = (seq_zero & 0x03) << 3;
|
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_n = net_buf_simple_pull_u8(buf);
|
||||||
seg_o |= seg_n >> 5;
|
seg_o |= seg_n >> 5;
|
||||||
seg_n &= 0x1f;
|
seg_n &= 0x1f;
|
||||||
|
@ -1499,13 +1473,11 @@ 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
|
* requested the Friend to send them. The messages must also
|
||||||
* be encrypted using the Friend Credentials.
|
* 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) &&
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
|
bt_mesh_lpn_established() && rx->net_if == BLE_MESH_NET_IF_ADV &&
|
||||||
bt_mesh_lpn_established() && rx->net_if == BLE_MESH_NET_IF_ADV &&
|
(!bt_mesh_lpn_waiting_update() || !rx->friend_cred)) {
|
||||||
(!bt_mesh_lpn_waiting_update() || !rx->friend_cred)) {
|
BT_WARN("Ignoring unexpected message in Low Power mode");
|
||||||
BT_WARN("Ignoring unexpected message in Low Power mode");
|
return -EAGAIN;
|
||||||
return -EAGAIN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the app-level state so the buffer can later be placed in
|
/* Save the app-level state so the buffer can later be placed in
|
||||||
|
@ -1538,25 +1510,21 @@ 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.
|
* 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) &&
|
||||||
if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) &&
|
(bt_mesh_lpn_timer() ||
|
||||||
(bt_mesh_lpn_timer() ||
|
(bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()))) {
|
||||||
(bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()))) {
|
bt_mesh_lpn_msg_received(rx);
|
||||||
bt_mesh_lpn_msg_received(rx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
net_buf_simple_restore(buf, &state);
|
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 (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->friend_match && !err) {
|
if (seq_auth == TRANS_SEQ_AUTH_NVAL) {
|
||||||
if (seq_auth == TRANS_SEQ_AUTH_NVAL) {
|
bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL,
|
||||||
bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL,
|
seg_count, buf);
|
||||||
seg_count, buf);
|
} else {
|
||||||
} else {
|
bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth,
|
||||||
bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth,
|
seg_count, buf);
|
||||||
seg_count, buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1664,3 +1632,41 @@ void bt_mesh_heartbeat_send(void)
|
||||||
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb),
|
bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb),
|
||||||
NULL, NULL, NULL);
|
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 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_MASK ((u8_t)BIT_MASK(7))
|
||||||
#define TRANS_CTL_OP(data) ((data)[0] & TRANS_CTL_OP_MASK)
|
#define TRANS_CTL_OP(data) ((data)[0] & TRANS_CTL_OP_MASK)
|
||||||
#define TRANS_CTL_HDR(op, seg) ((op & TRANS_CTL_OP_MASK) | (seg << 7))
|
#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);
|
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_ */
|
#endif /* _TRANSPORT_H_ */
|
||||||
|
|
Loading…
Reference in a new issue