From 99a63ce81df6d903450876d22aec6aed1d67192b Mon Sep 17 00:00:00 2001 From: lly Date: Wed, 23 Oct 2019 09:54:44 +0800 Subject: [PATCH 01/21] ble_mesh: Expose SeqZero mask Makes a define for the seqzero 13-bit mask in transport, and exposes it in the header for use in the friend module. --- components/bt/esp_ble_mesh/mesh_core/transport.c | 10 +++++----- components/bt/esp_ble_mesh/mesh_core/transport.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index 62d3a67ab..cc070d563 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -371,7 +371,7 @@ static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, tx->ttl = net_tx->ctx->send_ttl; } - seq_zero = tx->seq_auth & 0x1fff; + seq_zero = tx->seq_auth & TRANS_SEQ_ZERO_MASK; BT_DBG("SeqZero 0x%04x", seq_zero); @@ -780,7 +780,7 @@ static struct seg_tx *seg_tx_lookup(u16_t seq_zero, u8_t obo, u16_t addr) for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { tx = &seg_tx[i]; - if ((tx->seq_auth & 0x1fff) != seq_zero) { + if ((tx->seq_auth & TRANS_SEQ_ZERO_MASK) != seq_zero) { continue; } @@ -818,7 +818,7 @@ static int trans_ack(struct bt_mesh_net_rx *rx, u8_t hdr, seq_zero = net_buf_simple_pull_be16(buf); obo = seq_zero >> 15; - seq_zero = (seq_zero >> 2) & 0x1fff; + seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK; if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->friend_match) { BT_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst); @@ -1079,7 +1079,7 @@ static int send_ack(struct bt_mesh_subnet *sub, u16_t src, u16_t dst, .src = obo ? bt_mesh_primary_addr() : src, .xmit = bt_mesh_net_transmit_get(), }; - u16_t seq_zero = *seq_auth & 0x1fff; + u16_t seq_zero = *seq_auth & TRANS_SEQ_ZERO_MASK; u8_t buf[6]; BT_DBG("SeqZero 0x%04x Block 0x%08x OBO %u", seq_zero, block, obo); @@ -1287,7 +1287,7 @@ static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, seq_zero = net_buf_simple_pull_be16(buf); seg_o = (seq_zero & 0x03) << 3; - seq_zero = (seq_zero >> 2) & 0x1fff; + seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK; seg_n = net_buf_simple_pull_u8(buf); seg_o |= seg_n >> 5; seg_n &= 0x1f; diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.h b/components/bt/esp_ble_mesh/mesh_core/transport.h index 50a7aae1e..87953f2ed 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.h +++ b/components/bt/esp_ble_mesh/mesh_core/transport.h @@ -14,6 +14,7 @@ #define BLE_MESH_TX_SDU_MAX (CONFIG_BLE_MESH_TX_SEG_MAX * 12) +#define TRANS_SEQ_ZERO_MASK ((u16_t)BIT_MASK(13)) #define TRANS_CTL_OP_MASK ((u8_t)BIT_MASK(7)) #define TRANS_CTL_OP(data) ((data)[0] & TRANS_CTL_OP_MASK) #define TRANS_CTL_HDR(op, seg) ((op & TRANS_CTL_OP_MASK) | (seg << 7)) From 89a681fd4a847754bccadc41a7570d5375fef2fc Mon Sep 17 00:00:00 2001 From: lly Date: Wed, 23 Oct 2019 10:51:33 +0800 Subject: [PATCH 02/21] ble_mesh: Encrypt friend packets on send Stores friend queue packets unencrypted, removing any out-of-order issues caused by seqnum allocation. Also moves as much of the metadata storage as possible into the packet, allowing us to free up some bytes of net_buf user data for friend packets. --- .../mesh_common/include/mesh_buf.h | 188 +++++++++++++ .../bt/esp_ble_mesh/mesh_common/mesh_buf.c | 141 +++++++++- components/bt/esp_ble_mesh/mesh_core/adv.h | 13 +- components/bt/esp_ble_mesh/mesh_core/friend.c | 247 ++++++++++-------- 4 files changed, 471 insertions(+), 118 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h index 6f1991dcc..e6e31ae93 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h @@ -963,6 +963,20 @@ static inline void *net_buf_user_data(struct net_buf *buf) */ #define net_buf_pull(buf, len) net_buf_simple_pull(&(buf)->b, len) +/** + * @def net_buf_pull_mem + * @brief Remove data from the beginning of the buffer. + * + * Removes data from the beginning of the buffer by modifying the data + * pointer and buffer length. + * + * @param buf Buffer to update. + * @param len Number of bytes to remove. + * + * @return Pointer to the old beginning of the buffer data. + */ +#define net_buf_pull_mem(buf, len) net_buf_simple_pull_mem(&(buf)->b, len) + /** * @def net_buf_pull_u8 * @brief Remove a 8-bit value from the beginning of the buffer @@ -1052,6 +1066,180 @@ static inline void *net_buf_user_data(struct net_buf *buf) */ #define net_buf_headroom(buf) net_buf_simple_headroom(&(buf)->b) +/** + * @def net_buf_tail + * @brief Get the tail pointer for a buffer. + * + * Get a pointer to the end of the data in a buffer. + * + * @param buf Buffer. + * + * @return Tail pointer for the buffer. + */ +#define net_buf_tail(buf) net_buf_simple_tail(&(buf)->b) + +/** + * @brief Find the last fragment in the fragment list. + * + * @return Pointer to last fragment in the list. + */ +struct net_buf *net_buf_frag_last(struct net_buf *frags); + +/** + * @brief Insert a new fragment to a chain of bufs. + * + * Insert a new fragment into the buffer fragments list after the parent. + * + * Note: This function takes ownership of the fragment reference so the + * caller is not required to unref. + * + * @param parent Parent buffer/fragment. + * @param frag Fragment to insert. + */ +void net_buf_frag_insert(struct net_buf *parent, struct net_buf *frag); + +/** + * @brief Add a new fragment to the end of a chain of bufs. + * + * Append a new fragment into the buffer fragments list. + * + * Note: This function takes ownership of the fragment reference so the + * caller is not required to unref. + * + * @param head Head of the fragment chain. + * @param frag Fragment to add. + * + * @return New head of the fragment chain. Either head (if head + * was non-NULL) or frag (if head was NULL). + */ +struct net_buf *net_buf_frag_add(struct net_buf *head, struct net_buf *frag); + +/** + * @brief Delete existing fragment from a chain of bufs. + * + * @param parent Parent buffer/fragment, or NULL if there is no parent. + * @param frag Fragment to delete. + * + * @return Pointer to the buffer following the fragment, or NULL if it + * had no further fragments. + */ +#if defined(CONFIG_BLE_MESH_NET_BUF_LOG) +struct net_buf *net_buf_frag_del_debug(struct net_buf *parent, + struct net_buf *frag, + const char *func, int line); +#define net_buf_frag_del(_parent, _frag) \ + net_buf_frag_del_debug(_parent, _frag, __func__, __LINE__) +#else +struct net_buf *net_buf_frag_del(struct net_buf *parent, struct net_buf *frag); +#endif + +/** + * @brief Copy bytes from net_buf chain starting at offset to linear buffer + * + * Copy (extract) @a len bytes from @a src net_buf chain, starting from @a + * offset in it, to a linear buffer @a dst. Return number of bytes actually + * copied, which may be less than requested, if net_buf chain doesn't have + * enough data, or destination buffer is too small. + * + * @param dst Destination buffer + * @param dst_len Destination buffer length + * @param src Source net_buf chain + * @param offset Starting offset to copy from + * @param len Number of bytes to copy + * @return number of bytes actually copied + */ +size_t net_buf_linearize(void *dst, size_t dst_len, + struct net_buf *src, size_t offset, size_t len); + +/** + * @typedef net_buf_allocator_cb + * @brief Network buffer allocator callback. + * + * @details The allocator callback is called when net_buf_append_bytes + * needs to allocate a new net_buf. + * + * @param timeout Affects the action taken should the net buf pool be empty. + * If K_NO_WAIT, then return immediately. If K_FOREVER, then + * wait as long as necessary. Otherwise, wait up to the specified + * number of milliseconds before timing out. + * @param user_data The user data given in net_buf_append_bytes call. + * @return pointer to allocated net_buf or NULL on error. + */ +typedef struct net_buf *(*net_buf_allocator_cb)(s32_t timeout, void *user_data); + +/** + * @brief Append data to a list of net_buf + * + * @details Append data to a net_buf. If there is not enough space in the + * net_buf then more net_buf will be added, unless there are no free net_buf + * and timeout occurs. + * + * @param buf Network buffer. + * @param len Total length of input data + * @param value Data to be added + * @param timeout Timeout is passed to the net_buf allocator callback. + * @param allocate_cb When a new net_buf is required, use this callback. + * @param user_data A user data pointer to be supplied to the allocate_cb. + * This pointer is can be anything from a mem_pool or a net_pkt, the + * logic is left up to the allocate_cb function. + * + * @return Length of data actually added. This may be less than input + * length if other timeout than K_FOREVER was used, and there + * were no free fragments in a pool to accommodate all data. + */ +size_t net_buf_append_bytes(struct net_buf *buf, size_t len, + const void *value, s32_t timeout, + net_buf_allocator_cb allocate_cb, void *user_data); + +/** + * @brief Skip N number of bytes in a net_buf + * + * @details Skip N number of bytes starting from fragment's offset. If the total + * length of data is placed in multiple fragments, this function will skip from + * all fragments until it reaches N number of bytes. Any fully skipped buffers + * are removed from the net_buf list. + * + * @param buf Network buffer. + * @param len Total length of data to be skipped. + * + * @return Pointer to the fragment or + * NULL and pos is 0 after successful skip, + * NULL and pos is 0xffff otherwise. + */ +static inline struct net_buf *net_buf_skip(struct net_buf *buf, size_t len) +{ + while (buf && len--) { + net_buf_pull_u8(buf); + if (!buf->len) { + buf = net_buf_frag_del(NULL, buf); + } + } + + return buf; +} + +/** + * @brief Calculate amount of bytes stored in fragments. + * + * Calculates the total amount of data stored in the given buffer and the + * fragments linked to it. + * + * @param buf Buffer to start off with. + * + * @return Number of bytes in the buffer and its fragments. + */ +static inline size_t net_buf_frags_len(struct net_buf *buf) +{ + size_t bytes = 0; + + while (buf) { + bytes += buf->len; + buf = buf->frags; + } + + return bytes; +} + /** * @} */ diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c b/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c index 885c489f5..09198491b 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c @@ -447,4 +447,143 @@ struct net_buf *net_buf_alloc_fixed(struct net_buf_pool *pool, s32_t timeout) return net_buf_alloc_len(pool, fixed->data_size, timeout); } -#endif \ No newline at end of file +#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; +} \ No newline at end of file diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.h b/components/bt/esp_ble_mesh/mesh_core/adv.h index 821e37ef9..7d7cce63f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.h +++ b/components/bt/esp_ble_mesh/mesh_core/adv.h @@ -46,15 +46,10 @@ struct bt_mesh_adv { busy: 1; u8_t xmit; - union { - /* Address, used e.g. for Friend Queue messages */ - u16_t addr; - - /* For transport layer segment sending */ - struct { - u8_t attempts; - } seg; - }; + /* For transport layer segment sending */ + struct { + u8_t attempts; + } seg; }; typedef struct bt_mesh_adv *(*bt_mesh_adv_alloc_t)(int id); diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 794eb2ca4..966382cf6 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -37,9 +37,6 @@ #define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \ CONFIG_BLE_MESH_FRIEND_LPN_COUNT) -#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), \ - struct friend_adv, adv) - /* PDUs from Friend to the LPN should only be transmitted once with the * smallest possible interval (20ms). */ @@ -60,10 +57,7 @@ struct friend_pdu_info { NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT, BLE_MESH_ADV_DATA_SIZE, NULL); -static struct friend_adv { - struct bt_mesh_adv adv; - u64_t seq_auth; -} adv_pool[FRIEND_BUF_COUNT]; +static struct bt_mesh_adv adv_pool[FRIEND_BUF_COUNT]; enum { BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL, @@ -79,7 +73,7 @@ static void (*friend_cb)(bool establish, u16_t lpn_addr, u8_t reason); static struct bt_mesh_adv *adv_alloc(int id) { - return &adv_pool[id].adv; + return &adv_pool[id]; } static bool is_lpn_unicast(struct bt_mesh_friend *frnd, u16_t addr) @@ -318,13 +312,7 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd, struct friend_pdu_info *info, struct net_buf_simple *sdu) { - struct bt_mesh_subnet *sub; - const u8_t *enc, *priv; struct net_buf *buf; - u8_t nid; - - sub = bt_mesh_subnet_get(frnd->net_idx); - __ASSERT_NO_MSG(sub != NULL); buf = bt_mesh_adv_create_from_pool(&friend_buf_pool, adv_alloc, BLE_MESH_ADV_DATA, @@ -333,22 +321,7 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd, return NULL; } - BLE_MESH_ADV(buf)->addr = info->src; - FRIEND_ADV(buf)->seq_auth = TRANS_SEQ_AUTH_NVAL; - - /* Friend Offer needs master security credentials */ - if (info->ctl && TRANS_CTL_OP(sdu->data) == TRANS_CTL_OP_FRIEND_OFFER) { - enc = sub->keys[sub->kr_flag].enc; - priv = sub->keys[sub->kr_flag].privacy; - nid = sub->keys[sub->kr_flag].nid; - } else { - if (friend_cred_get(sub, frnd->lpn, &nid, &enc, &priv)) { - BT_ERR("%s, friend_cred_get failed", __func__); - goto failed; - } - } - - net_buf_add_u8(buf, (nid | (info->iv_index & 1) << 7)); + net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */ if (info->ctl) { net_buf_add_u8(buf, info->ttl | 0x80); @@ -363,25 +336,55 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd, net_buf_add_mem(buf, sdu->data, sdu->len); - /* We re-encrypt and obfuscate using the received IVI rather than - * the normal TX IVI (which may be different) since the transport - * layer nonce includes the IVI. - */ - if (bt_mesh_net_encrypt(enc, &buf->b, info->iv_index, false)) { - BT_ERR("%s, Re-encrypting failed", __func__); - goto failed; - } - - if (bt_mesh_net_obfuscate(buf->data, info->iv_index, priv)) { - BT_ERR("%s, Re-obfuscating failed", __func__); - goto failed; - } - return buf; +} -failed: - net_buf_unref(buf); - return NULL; +static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, bool master_cred) +{ + struct bt_mesh_subnet *sub = bt_mesh_subnet_get(frnd->net_idx); + const u8_t *enc, *priv; + u32_t iv_index; + u16_t src; + u8_t nid; + + 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)) { + /* Local messages were stored with a blank seqnum */ + u32_t 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; + } else { + u8_t ivi = (buf->data[0] >> 7); + iv_index = (bt_mesh.iv_index - ((bt_mesh.iv_index & 1) != ivi)); + } + + buf->data[0] = (nid | (iv_index & 1) << 7); + + if (bt_mesh_net_encrypt(enc, &buf->b, iv_index, false)) { + BT_ERR("Encrypting failed"); + return -EINVAL; + } + + if (bt_mesh_net_obfuscate(buf->data, iv_index, priv)) { + BT_ERR("Obfuscating failed"); + return -EINVAL; + } + + return 0; } static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd, @@ -389,7 +392,6 @@ static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd, struct net_buf_simple *sdu) { struct friend_pdu_info info; - u32_t seq; BT_DBG("LPN 0x%04x", frnd->lpn); @@ -401,10 +403,7 @@ static struct net_buf *encode_friend_ctl(struct bt_mesh_friend *frnd, info.ctl = 1U; info.ttl = 0U; - seq = bt_mesh_next_seq(); - info.seq[0] = seq >> 16; - info.seq[1] = seq >> 8; - info.seq[2] = seq; + memset(info.seq, 0, sizeof(info.seq)); info.iv_index = BLE_MESH_NET_IVI_TX; @@ -450,6 +449,10 @@ static void enqueue_sub_cfm(struct bt_mesh_friend *frnd, u8_t xact) return; } + if (encrypt_friend_pdu(frnd, buf, false)) { + return; + } + if (frnd->last) { BT_DBG("Discarding last PDU"); net_buf_unref(frnd->last); @@ -759,6 +762,10 @@ static void enqueue_offer(struct bt_mesh_friend *frnd, s8_t rssi) return; } + if (encrypt_friend_pdu(frnd, buf, true)) { + return; + } + frnd->counter++; if (frnd->last) { @@ -904,8 +911,29 @@ init_friend: return 0; } +static bool is_seg(struct bt_mesh_friend_seg *seg, u16_t src, u16_t seq_zero) +{ + struct net_buf *buf = (void *)sys_slist_peek_head(&seg->queue); + struct net_buf_simple_state state; + u16_t buf_seq_zero; + u16_t buf_src; + + if (!buf) { + return false; + } + + net_buf_simple_save(&buf->b, &state); + net_buf_skip(buf, 5); /* skip IVI, NID, CTL, TTL, SEQ */ + buf_src = net_buf_pull_be16(buf); + net_buf_skip(buf, 3); /* skip DST, OP/AID */ + buf_seq_zero = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK); + net_buf_simple_restore(&buf->b, &state); + + return ((src == buf_src) && (seq_zero == buf_seq_zero)); +} + static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd, - u16_t src, u64_t *seq_auth, + u16_t src, u16_t seq_zero, u8_t seg_count) { struct bt_mesh_friend_seg *unassigned = NULL; @@ -913,14 +941,12 @@ static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd, for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { struct bt_mesh_friend_seg *seg = &frnd->seg[i]; - struct net_buf *buf = (void *)sys_slist_peek_head(&seg->queue); - if (buf && BLE_MESH_ADV(buf)->addr == src && - FRIEND_ADV(buf)->seq_auth == *seq_auth) { + if (is_seg(seg, src, seq_zero)) { return seg; } - if (!unassigned && !buf) { + if (!unassigned && !sys_slist_peek_head(&seg->queue)) { unassigned = seg; } } @@ -934,10 +960,10 @@ static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd, static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, enum bt_mesh_friend_pdu_type type, - u8_t seg_count, struct net_buf *buf) + u16_t src, u8_t seg_count, + struct net_buf *buf) { struct bt_mesh_friend_seg *seg; - struct friend_adv *adv; BT_DBG("type %u", type); @@ -950,11 +976,11 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, return; } - adv = FRIEND_ADV(buf); - seg = get_seg(frnd, BLE_MESH_ADV(buf)->addr, &adv->seq_auth, seg_count); + u16_t seq_zero = (((buf->data[10] << 8 | buf->data[11]) >> 2) & TRANS_SEQ_ZERO_MASK); + + seg = get_seg(frnd, src, seq_zero, seg_count); if (!seg) { - BT_ERR("%s, No free friend segment RX contexts for 0x%04x", - __func__, BLE_MESH_ADV(buf)->addr); + BT_ERR("No free friend segment RX contexts for 0x%04x", src); net_buf_unref(buf); return; } @@ -966,16 +992,9 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, enqueue_update(frnd, 1); } - /* Only acks should have a valid SeqAuth in the Friend queue - * (otherwise we can't easily detect them there), so clear - * the SeqAuth information from the segments before merging. - */ - SYS_SLIST_FOR_EACH_CONTAINER(&seg->queue, buf, node) { - FRIEND_ADV(buf)->seq_auth = TRANS_SEQ_AUTH_NVAL; - frnd->queue_size++; - } - sys_slist_merge_slist(&frnd->queue, &seg->queue); + + frnd->queue_size += seg->seg_count; seg->seg_count = 0U; } else { /* Mark the buffer as having more to come after it */ @@ -1052,6 +1071,10 @@ static void friend_timeout(struct k_work *work) return; } + if (encrypt_friend_pdu(frnd, frnd->last, false)) { + return; + } + /* Clear the flag we use for segment tracking */ frnd->last->flags &= ~NET_BUF_FRAGS; frnd->last->frags = NULL; @@ -1094,6 +1117,42 @@ int bt_mesh_friend_init(void) return 0; } +static bool is_segack(struct net_buf *buf, u64_t *seqauth, u16_t src) +{ + struct net_buf_simple_state state; + bool found = false; + + if (buf->len != 16) { + return false; + } + + net_buf_simple_save(&buf->b, &state); + + net_buf_skip(buf, 1); /* skip IVI, NID */ + + if (!(net_buf_pull_u8(buf) >> 7)) { + goto end; + } + + net_buf_pull(buf, 3); /* skip SEQNUM */ + + if (src != net_buf_pull_be16(buf)) { + goto end; + } + + net_buf_skip(buf, 2); /* skip dst */ + + if (TRANS_CTL_OP((u8_t *) net_buf_pull_mem(buf, 1)) != TRANS_CTL_OP_ACK) { + goto end; + } + + found = ((net_buf_pull_be16(buf) >> 2) & TRANS_SEQ_ZERO_MASK) == + (*seqauth & TRANS_SEQ_ZERO_MASK); +end: + net_buf_simple_restore(&buf->b, &state); + return found; +} + static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, u16_t src) { @@ -1105,8 +1164,7 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth, cur != NULL; prev = cur, cur = sys_slist_peek_next(cur)) { struct net_buf *buf = (void *)cur; - if (BLE_MESH_ADV(buf)->addr == src && - FRIEND_ADV(buf)->seq_auth == *seq_auth) { + if (is_segack(buf, seq_auth, src)) { BT_DBG("Removing old ack from Friend Queue"); sys_slist_remove(&frnd->queue, prev, cur); @@ -1158,11 +1216,7 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, return; } - if (seq_auth) { - FRIEND_ADV(buf)->seq_auth = *seq_auth; - } - - enqueue_friend_pdu(frnd, type, seg_count, buf); + enqueue_friend_pdu(frnd, type, info.src, seg_count, buf); BT_DBG("Queued message for LPN 0x%04x, queue_size %u", frnd->lpn, frnd->queue_size); @@ -1176,7 +1230,6 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, { struct friend_pdu_info info; struct net_buf *buf; - u32_t seq; BT_DBG("LPN 0x%04x", frnd->lpn); @@ -1190,10 +1243,7 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, info.ttl = tx->ctx->send_ttl; info.ctl = (tx->ctx->app_idx == BLE_MESH_KEY_UNUSED); - seq = bt_mesh_next_seq(); - info.seq[0] = seq >> 16; - info.seq[1] = seq >> 8; - info.seq[2] = seq; + memset(info.seq, 0, sizeof(info.seq)); /* Will be allocated before encryption */ info.iv_index = BLE_MESH_NET_IVI_TX; @@ -1203,11 +1253,7 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, return; } - if (seq_auth) { - FRIEND_ADV(buf)->seq_auth = *seq_auth; - } - - enqueue_friend_pdu(frnd, type, seg_count, buf); + enqueue_friend_pdu(frnd, type, info.src, seg_count, buf); BT_DBG("Queued message for LPN 0x%04x", frnd->lpn); } @@ -1270,17 +1316,11 @@ static bool friend_queue_has_space(struct bt_mesh_friend *frnd, u16_t addr, for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) { struct bt_mesh_friend_seg *seg = &frnd->seg[i]; - if (seq_auth) { - struct net_buf *buf; - + if (seq_auth && is_seg(seg, addr, *seq_auth & TRANS_SEQ_ZERO_MASK)) { /* If there's a segment queue for this message then the * space verification has already happened. */ - buf = (void *)sys_slist_peek_head(&seg->queue); - if (buf && BLE_MESH_ADV(buf)->addr == addr && - FRIEND_ADV(buf)->seq_auth == *seq_auth) { - return true; - } + return true; } total += seg->seg_count; @@ -1454,18 +1494,8 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) { struct bt_mesh_friend_seg *seg = &frnd->seg[j]; - struct net_buf *buf; - buf = (void *)sys_slist_peek_head(&seg->queue); - if (!buf) { - continue; - } - - if (BLE_MESH_ADV(buf)->addr != src) { - continue; - } - - if (FRIEND_ADV(buf)->seq_auth != *seq_auth) { + if (!is_seg(seg, src, *seq_auth & TRANS_SEQ_ZERO_MASK)) { continue; } @@ -1473,6 +1503,7 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, purge_buffers(&seg->queue); seg->seg_count = 0U; + break; } } } From 67cb3062a687be5516c5ae749fea88af37578a67 Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 24 Oct 2019 09:51:16 +0800 Subject: [PATCH 03/21] ble_mesh: Make RSSI value available to mesh applications --- components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h | 3 +++ components/bt/esp_ble_mesh/mesh_core/friend.c | 7 ++++--- components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h | 3 +++ components/bt/esp_ble_mesh/mesh_core/net.c | 2 +- components/bt/esp_ble_mesh/mesh_core/net.h | 1 - 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index d59c29eb6..6263c0124 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -491,6 +491,9 @@ typedef struct { /** Destination address of a received message. Not used for sending. */ uint16_t recv_dst; + /** RSSI of received packet. Not used for sending. */ + int8_t recv_rssi; + /** Received TTL value. Not used for sending. */ uint8_t recv_ttl: 7; diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 966382cf6..dc27079c8 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -886,7 +886,7 @@ init_friend: frnd->clear.frnd = sys_be16_to_cpu(msg->prev_addr); BT_DBG("LPN 0x%04x rssi %d recv_delay %u poll_to %ums", - frnd->lpn, rx->rssi, frnd->recv_delay, frnd->poll_to); + frnd->lpn, rx->ctx.recv_rssi, frnd->recv_delay, frnd->poll_to); /** * Spec says: @@ -901,12 +901,13 @@ init_friend: } k_delayed_work_submit(&frnd->timer, - offer_delay(frnd, rx->rssi, msg->criteria)); + offer_delay(frnd, rx->ctx.recv_rssi, + msg->criteria)); friend_cred_create(rx->sub, frnd->lpn, frnd->lpn_counter, frnd->counter); - enqueue_offer(frnd, rx->rssi); + enqueue_offer(frnd, rx->ctx.recv_rssi); return 0; } diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h index 48b9a188b..cdc620520 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h @@ -140,6 +140,9 @@ struct bt_mesh_msg_ctx { /** Destination address of a received message. Not used for sending. */ u16_t recv_dst; + /** RSSI of received packet. Not used for sending. */ + s8_t recv_rssi; + /** Received TTL value. Not used for sending. */ u8_t recv_ttl: 7; diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 2bfba51d4..9f5bde937 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -1398,7 +1398,7 @@ void bt_mesh_net_recv(struct net_buf_simple *data, s8_t rssi, enum bt_mesh_net_if net_if) { NET_BUF_SIMPLE_DEFINE(buf, 29); - struct bt_mesh_net_rx rx = { .rssi = rssi }; + struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi }; struct net_buf_simple_state state; BT_DBG("rssi %d net_if %u", rssi, net_if); diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index bc600cfd1..2a74f9779 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/components/bt/esp_ble_mesh/mesh_core/net.h @@ -296,7 +296,6 @@ struct bt_mesh_net_rx { local_match: 1, /* Matched a local element */ friend_match: 1; /* Matched an LPN we're friends for */ u16_t msg_cache_idx; /* Index of entry in message cache */ - s8_t rssi; }; /* Encoding context for Network/Transport data */ From 865434e6de5c7ffd4a0eef0f84e7a6370eaa23cb Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 24 Oct 2019 10:13:39 +0800 Subject: [PATCH 04/21] ble_mesh: Remove unused macro FRIEND_BUF_SIZE --- components/bt/esp_ble_mesh/mesh_core/friend.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index dc27079c8..4f02a959f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -29,8 +29,6 @@ #ifdef CONFIG_BLE_MESH_FRIEND -#define FRIEND_BUF_SIZE (BLE_MESH_ADV_DATA_SIZE - BLE_MESH_NET_HDR_LEN) - /* We reserve one extra buffer for each friendship, since we need to be able * to resend the last sent PDU, which sits separately outside of the queue. */ From 906fb9d6e3a3a250939c45e42a388e369b5decf1 Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 24 Oct 2019 15:08:33 +0800 Subject: [PATCH 05/21] ble_mesh: Expose header parsing outside net --- components/bt/esp_ble_mesh/mesh_core/net.c | 11 +++++++++++ components/bt/esp_ble_mesh/mesh_core/net.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 9f5bde937..0592031a7 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -1308,6 +1308,17 @@ done: #endif /* CONFIG_BLE_MESH_NODE */ +void bt_mesh_net_header_parse(struct net_buf_simple *buf, + struct bt_mesh_net_rx *rx) +{ + rx->old_iv = (IVI(buf->data) != (bt_mesh.iv_index & 0x01)); + rx->ctl = CTL(buf->data); + rx->ctx.recv_ttl = TTL(buf->data); + rx->seq = SEQ(buf->data); + rx->ctx.addr = SRC(buf->data); + rx->ctx.recv_dst = DST(buf->data); +} + int bt_mesh_net_decode(struct net_buf_simple *data, enum bt_mesh_net_if net_if, struct bt_mesh_net_rx *rx, struct net_buf_simple *buf) { diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index 2a74f9779..200cf7982 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/components/bt/esp_ble_mesh/mesh_core/net.h @@ -365,6 +365,8 @@ u32_t bt_mesh_next_seq(void); void bt_mesh_net_start(void); void bt_mesh_net_init(void); +void bt_mesh_net_header_parse(struct net_buf_simple *buf, + struct bt_mesh_net_rx *rx); /* Friendship Credential Management */ struct friend_cred { From b88dbf6348ea35321199e9c8e61e3567a2ad698f Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 24 Oct 2019 15:31:42 +0800 Subject: [PATCH 06/21] ble_mesh: Expose app key get function --- .../bt/esp_ble_mesh/mesh_core/transport.c | 70 ++++++++++++------- .../bt/esp_ble_mesh/mesh_core/transport.h | 3 + 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index cc070d563..bedfbe3f6 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -492,6 +492,7 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, { const u8_t *key = NULL; u8_t *ad, role; + u8_t aid; int err; if (net_buf_simple_tailroom(msg) < 4) { @@ -513,33 +514,14 @@ int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, return -EINVAL; } - if (tx->ctx->app_idx == BLE_MESH_KEY_DEV) { - key = bt_mesh_tx_devkey_get(role, tx->ctx->addr); - if (!key) { - BT_ERR("%s, Failed to get Device Key", __func__); - return -EINVAL; - } - - 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; - } + err = bt_mesh_app_key_get(tx->sub, tx->ctx->app_idx, &key, + &aid, role, tx->ctx->addr); + if (err) { + return err; } + tx->aid = aid; + if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) { tx->aszmic = 0U; } else { @@ -1664,3 +1646,41 @@ void bt_mesh_heartbeat_send(void) bt_mesh_ctl_send(&tx, TRANS_CTL_OP_HEARTBEAT, &hb, sizeof(hb), NULL, NULL, NULL); } + +int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx, + const u8_t **key, u8_t *aid, u8_t role, u16_t dst) +{ + struct bt_mesh_app_key *app_key; + + if (app_idx == BLE_MESH_KEY_DEV) { + *key = bt_mesh_tx_devkey_get(role, dst); + if (!*key) { + BT_ERR("%s, Failed to get Device Key", __func__); + return -EINVAL; + } + + *aid = 0U; + return 0; + } + + if (!subnet) { + BT_ERR("%s, Invalid subnet", __func__); + return -EINVAL; + } + + app_key = bt_mesh_tx_appkey_get(role, app_idx, subnet->net_idx); + if (!app_key) { + BT_ERR("%s, Failed to get AppKey", __func__); + return -ENOENT; + } + + if (subnet->kr_phase == BLE_MESH_KR_PHASE_2 && app_key->updated) { + *key = app_key->keys[1].val; + *aid = app_key->keys[1].id; + } else { + *key = app_key->keys[0].val; + *aid = app_key->keys[0].id; + } + + return 0; +} diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.h b/components/bt/esp_ble_mesh/mesh_core/transport.h index 87953f2ed..6fc81fdf2 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.h +++ b/components/bt/esp_ble_mesh/mesh_core/transport.h @@ -102,4 +102,7 @@ void bt_mesh_rpl_clear(void); void bt_mesh_heartbeat_send(void); +int bt_mesh_app_key_get(const struct bt_mesh_subnet *subnet, u16_t app_idx, + const u8_t **key, u8_t *aid, u8_t role, u16_t dst); + #endif /* _TRANSPORT_H_ */ From 6516ab71eaf100d610ee82c844bae7745bb10995 Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 24 Oct 2019 16:06:50 +0800 Subject: [PATCH 07/21] ble_mesh: Ensure seqnum match in app/net Re-encrypts single-segment application messages when the network seqnum has changed, to avoid encrypting messages with different seqnums in network and transport. This operation is only required for unsegmented messages, as segmented messages don't need to use the same seqnum in network. Reinstates the special adv data for friend messages to store the app key index. --- components/bt/esp_ble_mesh/mesh_core/friend.c | 146 +++++++++++++++++- 1 file changed, 140 insertions(+), 6 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 4f02a959f..a7b96d61e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -35,6 +35,8 @@ #define FRIEND_BUF_COUNT ((CONFIG_BLE_MESH_FRIEND_QUEUE_SIZE + 1) * \ CONFIG_BLE_MESH_FRIEND_LPN_COUNT) +#define FRIEND_ADV(buf) CONTAINER_OF(BLE_MESH_ADV(buf), struct friend_adv, adv) + /* PDUs from Friend to the LPN should only be transmitted once with the * smallest possible interval (20ms). */ @@ -55,7 +57,10 @@ struct friend_pdu_info { NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT, BLE_MESH_ADV_DATA_SIZE, NULL); -static struct bt_mesh_adv adv_pool[FRIEND_BUF_COUNT]; +static struct friend_adv { + struct bt_mesh_adv adv; + u16_t app_idx; +} adv_pool[FRIEND_BUF_COUNT]; enum { BLE_MESH_FRIENDSHIP_TERMINATE_ESTABLISH_FAIL, @@ -71,7 +76,8 @@ static void (*friend_cb)(bool establish, u16_t lpn_addr, u8_t reason); static struct bt_mesh_adv *adv_alloc(int id) { - return &adv_pool[id]; + adv_pool[id].app_idx = BLE_MESH_KEY_UNUSED; + return &adv_pool[id].adv; } static bool is_lpn_unicast(struct bt_mesh_friend *frnd, u16_t addr) @@ -337,13 +343,122 @@ static struct net_buf *create_friend_pdu(struct bt_mesh_friend *frnd, return buf; } -static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, bool master_cred) +struct unseg_app_sdu_meta { + struct bt_mesh_net_rx net; + const u8_t *key; + struct bt_mesh_subnet *subnet; + bool is_dev_key; + u8_t aid; + u8_t *ad; +}; + +static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd, + struct net_buf *buf, + struct unseg_app_sdu_meta *meta) +{ + u16_t app_idx = FRIEND_ADV(buf)->app_idx; + int err; + + meta->subnet = bt_mesh_subnet_get(frnd->net_idx); + 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, NODE, meta->net.ctx.addr); + if (err) { + 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) { + 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 = { + .len = buf->len - 14, + .data = &buf->data[10], + .__buf = &buf->data[10], + .size = buf->len - 10, + }; + + 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 = { + .len = buf->len - 14, + .data = &buf->data[10], + .__buf = &buf->data[10], + .size = buf->len - 10, + }; + + 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 = bt_mesh_subnet_get(frnd->net_idx); const u8_t *enc, *priv; u32_t iv_index; u16_t src; u8_t nid; + int err; if (master_cred) { enc = sub->keys[sub->kr_flag].enc; @@ -359,12 +474,21 @@ static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, src = sys_get_be16(&buf->data[5]); if (bt_mesh_elem_find(src)) { - /* Local messages were stored with a blank seqnum */ - u32_t seq = bt_mesh_next_seq(); + 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)); @@ -1242,7 +1366,9 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, info.ttl = tx->ctx->send_ttl; info.ctl = (tx->ctx->app_idx == BLE_MESH_KEY_UNUSED); - memset(info.seq, 0, sizeof(info.seq)); /* Will be allocated before encryption */ + info.seq[0] = (bt_mesh.seq >> 16); + info.seq[1] = (bt_mesh.seq >> 8); + info.seq[2] = bt_mesh.seq; info.iv_index = BLE_MESH_NET_IVI_TX; @@ -1252,6 +1378,14 @@ static void friend_lpn_enqueue_tx(struct bt_mesh_friend *frnd, return; } + if (type == BLE_MESH_FRIEND_PDU_SINGLE && !info.ctl) { + /* Unsegmented application packets may be reencrypted later, + * as they depend on the the sequence number being the same + * when encrypting in transport and network. + */ + FRIEND_ADV(buf)->app_idx = tx->ctx->app_idx; + } + enqueue_friend_pdu(frnd, type, info.src, seg_count, buf); BT_DBG("Queued message for LPN 0x%04x", frnd->lpn); From aec696a3a4e9882dd0b2c4f0c133450b90174e3a Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 24 Oct 2019 16:10:35 +0800 Subject: [PATCH 08/21] ble_mesh: Skip local messages in rx Local messages are already enqueued for the LPN in the tx path, and don't have to be added again in the rx path. --- components/bt/esp_ble_mesh/mesh_core/friend.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index a7b96d61e..2531e4171 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -1310,6 +1310,14 @@ static void friend_lpn_enqueue_rx(struct bt_mesh_friend *frnd, struct friend_pdu_info info; struct net_buf *buf; + /* Because of network loopback, tx packets will also be passed into + * this rx function. These packets have already been added to the + * queue, and should be ignored. + */ + if (bt_mesh_elem_find(rx->ctx.addr)) { + return; + } + BT_DBG("LPN 0x%04x queue_size %u", frnd->lpn, frnd->queue_size); if (type == BLE_MESH_FRIEND_PDU_SINGLE && seq_auth) { From f3b9b099cd7bc0cb946cc0f3187ccd5c8dd000c9 Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 24 Oct 2019 16:17:22 +0800 Subject: [PATCH 09/21] ble_mesh: Use net_buf_simple_clone Uses net_buf_simple_clone to access the sdu of an unsegmented app packet for re-encryption. --- .../mesh_common/include/mesh_buf.h | 13 +++++++++++ .../bt/esp_ble_mesh/mesh_common/mesh_buf.c | 6 +++++ components/bt/esp_ble_mesh/mesh_core/friend.c | 22 +++++++++---------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h index e6e31ae93..e32569589 100644 --- a/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h +++ b/components/bt/esp_ble_mesh/mesh_common/include/mesh_buf.h @@ -168,6 +168,19 @@ static inline void net_buf_simple_reset(struct net_buf_simple *buf) buf->data = buf->__buf; } +/** + * Clone buffer state, using the same data buffer. + * + * Initializes a buffer to point to the same data as an existing buffer. + * Allows operations on the same data without altering the length and + * offset of the original. + * + * @param original Buffer to clone. + * @param clone The new clone. + */ +void net_buf_simple_clone(const struct net_buf_simple *original, + struct net_buf_simple *clone); + /** * @brief Prepare data to be added at the end of the buffer * diff --git a/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c b/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c index 09198491b..2cb31d6d5 100644 --- a/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c +++ b/components/bt/esp_ble_mesh/mesh_common/mesh_buf.c @@ -31,6 +31,12 @@ static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool, return buf; } +void net_buf_simple_clone(const struct net_buf_simple *original, + struct net_buf_simple *clone) +{ + memcpy(clone, original, sizeof(struct net_buf_simple)); +} + void *net_buf_simple_add(struct net_buf_simple *buf, size_t len) { u8_t *tail = net_buf_simple_tail(buf); diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 2531e4171..880b123e6 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -384,12 +384,11 @@ 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 = { - .len = buf->len - 14, - .data = &buf->data[10], - .__buf = &buf->data[10], - .size = buf->len - 10, - }; + 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, @@ -401,12 +400,11 @@ 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 = { - .len = buf->len - 14, - .data = &buf->data[10], - .__buf = &buf->data[10], - .size = buf->len - 10, - }; + 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, From 1338fc4ff1977d6e19751f4a3be48288202db0bd Mon Sep 17 00:00:00 2001 From: lly Date: Mon, 4 Nov 2019 17:54:50 +0800 Subject: [PATCH 10/21] ble_mesh: Model message macros Creates macros for determining model message lengths based on opcode, payload length and MIC size. Also adds macro wrapping NET_BUF_SIMPLE_DEFINE to serve the most common use case. --- components/bt/esp_ble_mesh/mesh_core/access.c | 24 ++--- .../bt/esp_ble_mesh/mesh_core/cfg_cli.c | 65 ++++++------- .../bt/esp_ble_mesh/mesh_core/cfg_srv.c | 92 ++++++++----------- .../bt/esp_ble_mesh/mesh_core/health_cli.c | 14 +-- .../bt/esp_ble_mesh/mesh_core/health_srv.c | 6 +- .../mesh_core/include/mesh_access.h | 50 ++++++++++ 6 files changed, 143 insertions(+), 108 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/access.c b/components/bt/esp_ble_mesh/mesh_core/access.c index 43e6e746a..989b1f0a6 100644 --- a/components/bt/esp_ble_mesh/mesh_core/access.c +++ b/components/bt/esp_ble_mesh/mesh_core/access.c @@ -761,21 +761,21 @@ void bt_mesh_model_msg_init(struct net_buf_simple *msg, u32_t opcode) { net_buf_simple_init(msg, 0); - if (opcode < 0x100) { - /* 1-byte OpCode */ + switch (BLE_MESH_MODEL_OP_LEN(opcode)) { + case 1: net_buf_simple_add_u8(msg, opcode); - return; - } - - if (opcode < 0x10000) { - /* 2-byte OpCode */ + break; + case 2: net_buf_simple_add_be16(msg, opcode); - return; + 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) diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c index c3e73c23f..3cb08f076 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_cli.c @@ -29,6 +29,9 @@ #define CID_NVAL 0xffff +/* 2 byte dummy opcode for getting compile time buffer sizes. */ +#define DUMMY_2_BYTE_OP BLE_MESH_MODEL_OP_2(0xff, 0xff) + s32_t config_msg_timeout; static bt_mesh_config_client_t *cli; @@ -685,7 +688,7 @@ const struct bt_mesh_model_op bt_mesh_cfg_cli_op[] = { int bt_mesh_cfg_comp_data_get(struct bt_mesh_msg_ctx *ctx, u8_t page) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEV_COMP_DATA_GET, 1); int err; if (!ctx || !ctx->addr) { @@ -707,7 +710,7 @@ int bt_mesh_cfg_comp_data_get(struct bt_mesh_msg_ctx *ctx, u8_t page) static int get_state_u8(struct bt_mesh_msg_ctx *ctx, u32_t op) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 0); int err; bt_mesh_model_msg_init(&msg, op); @@ -723,7 +726,7 @@ static int get_state_u8(struct bt_mesh_msg_ctx *ctx, u32_t op) static int set_state_u8(struct bt_mesh_msg_ctx *ctx, u32_t op, u8_t new_val) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 1); int err; bt_mesh_model_msg_init(&msg, op); @@ -804,7 +807,7 @@ int bt_mesh_cfg_gatt_proxy_set(struct bt_mesh_msg_ctx *ctx, u8_t val) int bt_mesh_cfg_relay_get(struct bt_mesh_msg_ctx *ctx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_GET, 0); int err; if (!ctx || !ctx->addr) { @@ -826,7 +829,7 @@ int bt_mesh_cfg_relay_get(struct bt_mesh_msg_ctx *ctx) int bt_mesh_cfg_relay_set(struct bt_mesh_msg_ctx *ctx, u8_t new_relay, u8_t new_transmit) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_SET, 2); int err; if (!ctx || !ctx->addr) { @@ -850,7 +853,7 @@ int bt_mesh_cfg_relay_set(struct bt_mesh_msg_ctx *ctx, u8_t new_relay, int bt_mesh_cfg_net_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx, const u8_t net_key[16]) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 18 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_ADD, 18); int err; if (!ctx || !ctx->addr || !net_key) { @@ -874,7 +877,7 @@ int bt_mesh_cfg_net_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx, int bt_mesh_cfg_app_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx, u16_t key_app_idx, const u8_t app_key[16]) { - NET_BUF_SIMPLE_DEFINE(msg, 1 + 19 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_ADD, 19); int err; if (!ctx || !ctx->addr || !app_key) { @@ -898,7 +901,7 @@ int bt_mesh_cfg_app_key_add(struct bt_mesh_msg_ctx *ctx, u16_t key_net_idx, int bt_mesh_cfg_mod_app_bind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_app_idx, u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_BIND, 8); int err; if (!ctx || !ctx->addr) { @@ -926,7 +929,7 @@ int bt_mesh_cfg_mod_app_bind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, static int mod_sub(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t sub_addr, u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 8); int err; bt_mesh_model_msg_init(&msg, op); @@ -976,7 +979,7 @@ int bt_mesh_cfg_mod_sub_overwrite(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, static int mod_sub_va(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, const u8_t label[16], u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 22 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 22); int err; BT_DBG("net_idx 0x%04x addr 0x%04x elem_addr 0x%04x label %s", @@ -1030,7 +1033,7 @@ int bt_mesh_cfg_mod_sub_va_overwrite(struct bt_mesh_msg_ctx *ctx, u16_t elem_add int bt_mesh_cfg_mod_pub_get(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_GET, 6); int err; if (!ctx || !ctx->addr) { @@ -1058,7 +1061,7 @@ int bt_mesh_cfg_mod_pub_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid, struct bt_mesh_cfg_mod_pub *pub) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 13 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_SET, 13); int err; if (!ctx || !ctx->addr || !pub) { @@ -1090,7 +1093,7 @@ int bt_mesh_cfg_mod_pub_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, int bt_mesh_cfg_hb_sub_set(struct bt_mesh_msg_ctx *ctx, struct bt_mesh_cfg_hb_sub *sub) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_SET, 5); int err; if (!ctx || !ctx->addr || !sub) { @@ -1114,7 +1117,7 @@ int bt_mesh_cfg_hb_sub_set(struct bt_mesh_msg_ctx *ctx, int bt_mesh_cfg_hb_sub_get(struct bt_mesh_msg_ctx *ctx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_GET, 0); int err; if (!ctx || !ctx->addr) { @@ -1136,7 +1139,7 @@ int bt_mesh_cfg_hb_sub_get(struct bt_mesh_msg_ctx *ctx) int bt_mesh_cfg_hb_pub_set(struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_cfg_hb_pub *pub) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_SET, 9); int err; if (!ctx || !ctx->addr || !pub) { @@ -1163,7 +1166,7 @@ int bt_mesh_cfg_hb_pub_set(struct bt_mesh_msg_ctx *ctx, int bt_mesh_cfg_hb_pub_get(struct bt_mesh_msg_ctx *ctx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_GET, 0); int err; if (!ctx || !ctx->addr) { @@ -1184,7 +1187,7 @@ int bt_mesh_cfg_hb_pub_get(struct bt_mesh_msg_ctx *ctx) int bt_mesh_cfg_node_reset(struct bt_mesh_msg_ctx *ctx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET, 0); int err; if (!ctx || !ctx->addr) { @@ -1207,7 +1210,7 @@ int bt_mesh_cfg_mod_pub_va_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid, const u8_t label[16], struct bt_mesh_cfg_mod_pub *pub) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 27 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_VA_SET, 27); int err; if (!ctx || !ctx->addr || !label || !pub) { @@ -1239,7 +1242,7 @@ int bt_mesh_cfg_mod_pub_va_set(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, int bt_mesh_cfg_mod_sub_del_all(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_DEL_ALL, 6); int err; if (!ctx || !ctx->addr) { @@ -1266,7 +1269,7 @@ int bt_mesh_cfg_mod_sub_del_all(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, static int mod_sub_get(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 6); int err; bt_mesh_model_msg_init(&msg, op); @@ -1305,7 +1308,7 @@ int bt_mesh_cfg_mod_sub_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, int bt_mesh_cfg_net_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, const u8_t net_key[16]) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 18 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_UPDATE, 18); int err; if (!ctx || !ctx->addr || !net_key) { @@ -1328,7 +1331,7 @@ int bt_mesh_cfg_net_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, int bt_mesh_cfg_net_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_DEL, 2); int err; if (!ctx || !ctx->addr) { @@ -1350,7 +1353,7 @@ int bt_mesh_cfg_net_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx) int bt_mesh_cfg_net_key_get(struct bt_mesh_msg_ctx *ctx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_GET, 0); int err; if (!ctx || !ctx->addr) { @@ -1372,7 +1375,7 @@ int bt_mesh_cfg_net_key_get(struct bt_mesh_msg_ctx *ctx) int bt_mesh_cfg_app_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u16_t app_idx, const u8_t app_key[16]) { - NET_BUF_SIMPLE_DEFINE(msg, 1 + 19 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_UPDATE, 19); int err; if (!ctx || !ctx->addr || !app_key) { @@ -1395,7 +1398,7 @@ int bt_mesh_cfg_app_key_update(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, int bt_mesh_cfg_app_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u16_t app_idx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_DEL, 3); int err; if (!ctx || !ctx->addr) { @@ -1417,7 +1420,7 @@ int bt_mesh_cfg_app_key_delete(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u16_t int bt_mesh_cfg_app_key_get(struct bt_mesh_msg_ctx *ctx, u16_t net_idx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_GET, 2); int err; if (!ctx || !ctx->addr) { @@ -1440,7 +1443,7 @@ int bt_mesh_cfg_app_key_get(struct bt_mesh_msg_ctx *ctx, u16_t net_idx) static int node_identity_op(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8_t identity) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 3); int err; bt_mesh_model_msg_init(&msg, op); @@ -1477,7 +1480,7 @@ int bt_mesh_cfg_node_identity_set(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8 int bt_mesh_cfg_mod_app_unbind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t app_idx, u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 8 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_UNBIND, 8); int err; if (!ctx || !ctx->addr) { @@ -1505,7 +1508,7 @@ int bt_mesh_cfg_mod_app_unbind(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, static int mod_app_get(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, u16_t mod_id, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 6 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 6); int err; bt_mesh_model_msg_init(&msg, op); @@ -1544,7 +1547,7 @@ int bt_mesh_cfg_mod_app_get_vnd(struct bt_mesh_msg_ctx *ctx, u16_t elem_addr, static int kr_phase_op(u32_t op, struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8_t transition) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, DUMMY_2_BYTE_OP, 3); int err; bt_mesh_model_msg_init(&msg, op); @@ -1580,7 +1583,7 @@ int bt_mesh_cfg_kr_phase_set(struct bt_mesh_msg_ctx *ctx, u16_t net_idx, u8_t tr int bt_mesh_cfg_lpn_timeout_get(struct bt_mesh_msg_ctx *ctx, u16_t lpn_addr) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_GET, 2); int err; if (!ctx || !ctx->addr) { diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c index c7f72a07d..a17c3fd93 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c @@ -451,7 +451,7 @@ static void app_key_add(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4); u16_t key_net_idx, key_app_idx; u8_t status; @@ -486,7 +486,7 @@ static void app_key_update(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4); u16_t key_net_idx, key_app_idx; u8_t status; @@ -549,7 +549,7 @@ static void app_key_del(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_STATUS, 4); u16_t key_net_idx, key_app_idx; struct bt_mesh_app_key *key; u8_t status; @@ -607,8 +607,8 @@ static void app_key_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4 + - IDX_LEN(CONFIG_BLE_MESH_APP_KEY_COUNT)); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_APP_KEY_LIST, + 3 + IDX_LEN(CONFIG_BLE_MESH_APP_KEY_COUNT)); u16_t get_idx, i, prev; u8_t status; @@ -666,8 +666,7 @@ static void beacon_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, @@ -685,8 +684,7 @@ static void beacon_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_BEACON_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -728,8 +726,7 @@ static void default_ttl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, @@ -747,8 +744,7 @@ static void default_ttl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_DEFAULT_TTL_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -781,8 +777,7 @@ static void default_ttl_set(struct bt_mesh_model *model, static void send_gatt_proxy_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_GATT_PROXY_STATUS, 1); bt_mesh_model_msg_init(&msg, OP_GATT_PROXY_STATUS); net_buf_simple_add_u8(&msg, bt_mesh_gatt_proxy_get()); @@ -878,8 +873,7 @@ static void net_transmit_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, @@ -897,8 +891,7 @@ static void net_transmit_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_TRANSMIT_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -931,8 +924,7 @@ static void relay_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, @@ -951,8 +943,7 @@ static void relay_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_RELAY_STATUS, 2); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", @@ -1005,8 +996,7 @@ static void send_mod_pub_status(struct bt_mesh_model *cfg_mod, bool vnd, struct bt_mesh_model *mod, u8_t status, u8_t *mod_id) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 14 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_PUB_STATUS, 14); bt_mesh_model_msg_init(&msg, OP_MOD_PUB_STATUS); @@ -1386,8 +1376,7 @@ static void send_mod_sub_status(struct bt_mesh_model *model, u16_t elem_addr, u16_t sub_addr, u8_t *mod_id, bool vnd) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_STATUS, 9); BT_DBG("status 0x%02x elem_addr 0x%04x sub_addr 0x%04x", status, elem_addr, sub_addr); @@ -1696,8 +1685,8 @@ static void mod_sub_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4 + - CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST, + 5 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2); struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u16_t addr, id; @@ -1752,8 +1741,8 @@ static void mod_sub_get_vnd(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 7 + 4 + - CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_SUB_LIST_VND, + 7 + CONFIG_BLE_MESH_MODEL_GROUP_COUNT * 2); struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u16_t company, addr, id; @@ -2145,8 +2134,7 @@ static void send_net_key_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u16_t idx, u8_t status) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_STATUS, 3); bt_mesh_model_msg_init(&msg, OP_NET_KEY_STATUS); @@ -2379,8 +2367,8 @@ static void net_key_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, - 2 + 4 + IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT)); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NET_KEY_LIST, + IDX_LEN(CONFIG_BLE_MESH_SUBNET_COUNT)); u16_t prev, i; bt_mesh_model_msg_init(&msg, OP_NET_KEY_LIST); @@ -2415,8 +2403,7 @@ static void node_identity_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4); struct bt_mesh_subnet *sub; u8_t node_id; u16_t idx; @@ -2454,8 +2441,7 @@ static void node_identity_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_IDENTITY_STATUS, 4); struct bt_mesh_subnet *sub; u8_t node_id; u16_t idx; @@ -2531,7 +2517,7 @@ static void mod_app_bind(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9); u16_t elem_addr, key_app_idx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -2594,7 +2580,7 @@ static void mod_app_unbind(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_MOD_APP_STATUS, 9); u16_t elem_addr, key_app_idx; struct bt_mesh_model *mod; struct bt_mesh_elem *elem; @@ -2652,7 +2638,11 @@ static void mod_app_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + KEY_LIST_LEN + 4); + NET_BUF_SIMPLE_DEFINE(msg, + MAX(BLE_MESH_MODEL_BUF_LEN(OP_VND_MOD_APP_LIST, + 9 + KEY_LIST_LEN), + BLE_MESH_MODEL_BUF_LEN(OP_SIG_MOD_APP_LIST, + 9 + KEY_LIST_LEN))); struct bt_mesh_model *mod; struct bt_mesh_elem *elem; u8_t *mod_id, status; @@ -2720,8 +2710,7 @@ static void node_reset(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_NODE_RESET_STATUS, 0); BT_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, @@ -2745,8 +2734,7 @@ static void node_reset(struct bt_mesh_model *model, static void send_friend_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_FRIEND_STATUS, 1); struct bt_mesh_cfg_srv *cfg = model->user_data; bt_mesh_model_msg_init(&msg, OP_FRIEND_STATUS); @@ -2818,8 +2806,7 @@ static void lpn_timeout_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 5 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_LPN_TIMEOUT_STATUS, 5); struct bt_mesh_friend *frnd; u16_t lpn_addr; s32_t timeout; @@ -2864,8 +2851,7 @@ static void send_krp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u16_t idx, u8_t phase, u8_t status) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 4 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_KRP_STATUS, 4); bt_mesh_model_msg_init(&msg, OP_KRP_STATUS); @@ -3008,8 +2994,7 @@ static void hb_pub_send_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u8_t status, struct hb_pub_param *orig_msg) { - /* Needed size: opcode (1 byte) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 1 + 10 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_PUB_STATUS, 10); struct bt_mesh_cfg_srv *cfg = model->user_data; BT_DBG("src 0x%04x status 0x%02x", ctx->addr, status); @@ -3147,8 +3132,7 @@ failed: static void hb_sub_send_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, u8_t status) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 9 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEARTBEAT_SUB_STATUS, 9); struct bt_mesh_cfg_srv *cfg = model->user_data; u16_t period; s64_t uptime; diff --git a/components/bt/esp_ble_mesh/mesh_core/health_cli.c b/components/bt/esp_ble_mesh/mesh_core/health_cli.c index 0d5d5c813..66c15d44f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/health_cli.c +++ b/components/bt/esp_ble_mesh/mesh_core/health_cli.c @@ -235,7 +235,7 @@ const struct bt_mesh_model_op bt_mesh_health_cli_op[] = { int bt_mesh_health_attention_get(struct bt_mesh_msg_ctx *ctx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_GET, 0); int err; if (!ctx || !ctx->addr) { @@ -257,7 +257,7 @@ int bt_mesh_health_attention_get(struct bt_mesh_msg_ctx *ctx) int bt_mesh_health_attention_set(struct bt_mesh_msg_ctx *ctx, u8_t attention, bool need_ack) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_SET, 1); u32_t opcode; int err; @@ -285,7 +285,7 @@ int bt_mesh_health_attention_set(struct bt_mesh_msg_ctx *ctx, int bt_mesh_health_period_get(struct bt_mesh_msg_ctx *ctx) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 0 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_GET, 0); int err; if (!ctx || !ctx->addr) { @@ -307,7 +307,7 @@ int bt_mesh_health_period_get(struct bt_mesh_msg_ctx *ctx) int bt_mesh_health_period_set(struct bt_mesh_msg_ctx *ctx, u8_t divisor, bool need_ack) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_SET, 1); u32_t opcode; int err; @@ -336,7 +336,7 @@ int bt_mesh_health_period_set(struct bt_mesh_msg_ctx *ctx, int bt_mesh_health_fault_test(struct bt_mesh_msg_ctx *ctx, u16_t cid, u8_t test_id, bool need_ack) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 3 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_TEST, 3); u32_t opcode; int err; @@ -366,7 +366,7 @@ int bt_mesh_health_fault_test(struct bt_mesh_msg_ctx *ctx, int bt_mesh_health_fault_clear(struct bt_mesh_msg_ctx *ctx, u16_t cid, bool need_ack) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_CLEAR, 2); u32_t opcode; int err; @@ -394,7 +394,7 @@ int bt_mesh_health_fault_clear(struct bt_mesh_msg_ctx *ctx, int bt_mesh_health_fault_get(struct bt_mesh_msg_ctx *ctx, u16_t cid) { - NET_BUF_SIMPLE_DEFINE(msg, 2 + 2 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_FAULT_GET, 2); int err; if (!ctx || !ctx->addr) { diff --git a/components/bt/esp_ble_mesh/mesh_core/health_srv.c b/components/bt/esp_ble_mesh/mesh_core/health_srv.c index 344b62d10..6b039b6f4 100644 --- a/components/bt/esp_ble_mesh/mesh_core/health_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/health_srv.c @@ -227,8 +227,7 @@ static void health_fault_test(struct bt_mesh_model *model, static void send_attention_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_ATTENTION_STATUS, 1); struct bt_mesh_health_srv *srv = model->user_data; u8_t time; @@ -286,8 +285,7 @@ static void attention_set(struct bt_mesh_model *model, static void send_health_period_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx) { - /* Needed size: opcode (2 bytes) + msg + MIC */ - NET_BUF_SIMPLE_DEFINE(msg, 2 + 1 + 4); + BLE_MESH_MODEL_BUF_DEFINE(msg, OP_HEALTH_PERIOD_STATUS, 1); bt_mesh_model_msg_init(&msg, OP_HEALTH_PERIOD_STATUS); net_buf_simple_add_u8(&msg, model->pub->period_div); diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h index cdc620520..0d5e4f66f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h @@ -188,6 +188,56 @@ struct bt_mesh_model_op { /** Helper to define an empty model array */ #define BLE_MESH_MODEL_NONE ((struct bt_mesh_model []){}) +/** Length of a short Mesh MIC. */ +#define BLE_MESH_MIC_SHORT 4 +/** Length of a long Mesh MIC. */ +#define BLE_MESH_MIC_LONG 8 + +/** @def BLE_MESH_MODEL_OP_LEN + * + * @brief Helper to determine the length of an opcode. + * + * @param _op Opcode. + */ +#define BLE_MESH_MODEL_OP_LEN(_op) ((_op) <= 0xff ? 1 : (_op) <= 0xffff ? 2 : 3) + +/** @def BLE_MESH_MODEL_BUF_LEN + * + * @brief Helper for model message buffer length. + * + * Returns the length of a Mesh model message buffer, including the opcode + * length and a short MIC. + * + * @param _op Opcode of the message. + * @param _payload_len Length of the model payload. + */ +#define BLE_MESH_MODEL_BUF_LEN(_op, _payload_len) \ + (BLE_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BLE_MESH_MIC_SHORT) + +/** @def BLE_MESH_MODEL_BUF_LEN_LONG_MIC + * + * @brief Helper for model message buffer length. + * + * Returns the length of a Mesh model message buffer, including the opcode + * length and a long MIC. + * + * @param _op Opcode of the message. + * @param _payload_len Length of the model payload. + */ +#define BLE_MESH_MODEL_BUF_LEN_LONG_MIC(_op, _payload_len) \ + (BLE_MESH_MODEL_OP_LEN(_op) + (_payload_len) + BLE_MESH_MIC_LONG) + +/** @def BLE_MESH_MODEL_BUF_DEFINE + * + * @brief Define a Mesh model message buffer using @ref NET_BUF_SIMPLE_DEFINE. + * + * @param _buf Buffer name. + * @param _op Opcode of the message. + * @param _payload_len Length of the model message payload. + */ +#define BLE_MESH_MODEL_BUF_DEFINE(_buf, _op, _payload_len) \ + NET_BUF_SIMPLE_DEFINE(_buf, BLE_MESH_MODEL_BUF_LEN(_op, (_payload_len))) + #define BLE_MESH_MODEL(_id, _op, _pub, _user_data) \ { \ .id = (_id), \ From 74d0bd3134ddf2a3878da9c90efb9ce13dc731b2 Mon Sep 17 00:00:00 2001 From: lly Date: Mon, 4 Nov 2019 18:08:03 +0800 Subject: [PATCH 11/21] ble_mesh: Proxy forwards ALL_NODES addr Unless explicitly blacklisted, the Proxy node will forward all messages for the ALL_NODES address to the GATT proxy client. --- .../bt/esp_ble_mesh/mesh_core/proxy_server.c | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c index f5d361e8f..319f0ad2f 100644 --- a/components/bt/esp_ble_mesh/mesh_core/proxy_server.c +++ b/components/bt/esp_ble_mesh/mesh_core/proxy_server.c @@ -917,16 +917,6 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, BT_DBG("filter_type %u addr 0x%04x", client->filter_type, addr); - if (client->filter_type == WHITELIST) { - for (i = 0; i < ARRAY_SIZE(client->filter); i++) { - if (client->filter[i] == addr) { - return true; - } - } - - return false; - } - if (client->filter_type == BLACKLIST) { for (i = 0; i < ARRAY_SIZE(client->filter); i++) { if (client->filter[i] == addr) { @@ -937,6 +927,18 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return true; } + if (addr == BLE_MESH_ADDR_ALL_NODES) { + return true; + } + + if (client->filter_type == WHITELIST) { + for (i = 0; i < ARRAY_SIZE(client->filter); i++) { + if (client->filter[i] == addr) { + return true; + } + } + } + return false; } From e8440ac2f9047fd6fb82aba977f51b1d66f2b38a Mon Sep 17 00:00:00 2001 From: lly Date: Mon, 4 Nov 2019 20:04:52 +0800 Subject: [PATCH 12/21] ble_mesh: Persistent storage of Virtual Address The 16-bit format group addresses will be stored, but we don't store (or restore) the virtual label UUIDs, i.e. after a power cycle the 16-bit group addresses would be meaningless. --- .../bt/esp_ble_mesh/mesh_core/cfg_srv.c | 75 ++++++++--- .../bt/esp_ble_mesh/mesh_core/foundation.h | 13 ++ components/bt/esp_ble_mesh/mesh_core/net.h | 1 + .../bt/esp_ble_mesh/mesh_core/settings.c | 127 ++++++++++++++++++ .../bt/esp_ble_mesh/mesh_core/settings.h | 1 + 5 files changed, 196 insertions(+), 21 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c index a17c3fd93..e02da1d5e 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c @@ -47,11 +47,7 @@ static struct bt_mesh_cfg_srv *conf; -static struct label { - u16_t ref; - u16_t addr; - u8_t uuid[16]; -} labels[CONFIG_BLE_MESH_LABEL_COUNT]; +static struct label labels[CONFIG_BLE_MESH_LABEL_COUNT]; static int comp_add_elem(struct net_buf_simple *buf, struct bt_mesh_elem *elem, bool primary) @@ -1152,25 +1148,61 @@ send_status: } } -#if CONFIG_BLE_MESH_LABEL_COUNT > 0 -static u8_t va_add(u8_t *label_uuid, u16_t *addr) +struct label *get_label(u16_t index) { - struct label *free_slot = NULL; + if (index >= ARRAY_SIZE(labels)) { + return NULL; + } + + return &labels[index]; +} + +#if CONFIG_BLE_MESH_LABEL_COUNT > 0 +static inline void va_store(struct label *store) +{ + bt_mesh_atomic_set_bit(store->flags, BLE_MESH_VA_CHANGED); + if (IS_ENABLED(CONFIG_BLE_MESH_SETTINGS)) { + bt_mesh_store_label(); + } +} + +static struct label *va_find(const u8_t *label_uuid, + struct label **free_slot) +{ + struct label *match = NULL; int i; + if (free_slot != NULL) { + *free_slot = NULL; + } + for (i = 0; i < ARRAY_SIZE(labels); i++) { - if (!labels[i].ref) { - free_slot = &labels[i]; + if (labels[i].ref == 0) { + if (free_slot != NULL) { + *free_slot = &labels[i]; + } continue; } if (!memcmp(labels[i].uuid, label_uuid, 16)) { - *addr = labels[i].addr; - labels[i].ref++; - return STATUS_SUCCESS; + match = &labels[i]; } } + return match; +} + +static u8_t va_add(u8_t *label_uuid, u16_t *addr) +{ + struct label *update, *free_slot = NULL; + + update = va_find(label_uuid, &free_slot); + if (update) { + update->ref++; + va_store(update); + return 0; + } + if (!free_slot) { return STATUS_INSUFF_RESOURCES; } @@ -1182,23 +1214,24 @@ static u8_t va_add(u8_t *label_uuid, u16_t *addr) free_slot->ref = 1U; free_slot->addr = *addr; memcpy(free_slot->uuid, label_uuid, 16); + va_store(free_slot); return STATUS_SUCCESS; } static u8_t va_del(u8_t *label_uuid, u16_t *addr) { - int i; + struct label *update; - for (i = 0; i < ARRAY_SIZE(labels); i++) { - if (!memcmp(labels[i].uuid, label_uuid, 16)) { - if (addr) { - *addr = labels[i].addr; - } + update = va_find(label_uuid, NULL); + if (update) { + update->ref--; - labels[i].ref--; - return STATUS_SUCCESS; + if (addr) { + *addr = update->addr; } + + va_store(update); } if (addr) { diff --git a/components/bt/esp_ble_mesh/mesh_core/foundation.h b/components/bt/esp_ble_mesh/mesh_core/foundation.h index d1ccd31ae..19bc96dd7 100644 --- a/components/bt/esp_ble_mesh/mesh_core/foundation.h +++ b/components/bt/esp_ble_mesh/mesh_core/foundation.h @@ -117,6 +117,17 @@ #define STATUS_UNSPECIFIED 0x10 #define STATUS_INVALID_BINDING 0x11 +enum { + BLE_MESH_VA_CHANGED, /* Label information changed */ +}; + +struct label { + u16_t ref; + u16_t addr; + u8_t uuid[16]; + bt_mesh_atomic_t flags[1]; +}; + int bt_mesh_cfg_srv_init(struct bt_mesh_model *model, bool primary); int bt_mesh_health_srv_init(struct bt_mesh_model *model, bool primary); @@ -129,6 +140,8 @@ void bt_mesh_heartbeat(u16_t src, u16_t dst, u8_t hops, u16_t feat); void bt_mesh_attention(struct bt_mesh_model *model, u8_t time); +struct label *get_label(u16_t index); + u8_t *bt_mesh_label_uuid_get(u16_t addr); struct bt_mesh_hb_pub *bt_mesh_hb_pub_get(void); diff --git a/components/bt/esp_ble_mesh/mesh_core/net.h b/components/bt/esp_ble_mesh/mesh_core/net.h index 200cf7982..47657f495 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.h +++ b/components/bt/esp_ble_mesh/mesh_core/net.h @@ -224,6 +224,7 @@ enum { BLE_MESH_HB_PUB_PENDING, BLE_MESH_CFG_PENDING, BLE_MESH_MOD_PENDING, + BLE_MESH_VA_PENDING, /* Don't touch - intentionally last */ BLE_MESH_FLAG_COUNT, diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.c b/components/bt/esp_ble_mesh/mesh_core/settings.c index 8705b1c9a..57393b903 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.c +++ b/components/bt/esp_ble_mesh/mesh_core/settings.c @@ -55,6 +55,8 @@ * key: "mesh/v/xxxx/b" -> write/read to set/get VENDOR MODEL Bind AppKey List * key: "mesh/v/xxxx/s" -> write/read to set/get VENDOR MODEL Subscription List * key: "mesh/v/xxxx/p" -> write/read to set/get VENDOR MODEL Publication + * key: "mesh/vaddr" -> write/read to set/get all virtual addresses + * key: "mesh/va/xxxx" -> write/read to set/get the "xxxx" virtual address */ #if CONFIG_BLE_MESH_SETTINGS @@ -142,6 +144,13 @@ struct mod_pub_val { cred: 1; }; +/* Virtual Address information */ +struct va_val { + u16_t ref; + u16_t addr; + u8_t uuid[16]; +} __packed; + /* We need this so we don't overwrite app-hardcoded values in case FCB * contains a history of changes but then has a NULL at the end. */ @@ -695,6 +704,66 @@ static int vnd_mod_set(const char *name) return model_set(true, name); } +#if CONFIG_BLE_MESH_LABEL_COUNT > 0 +static int va_set(const char *name) +{ + struct net_buf_simple *buf = NULL; + struct va_val va = {0}; + char get[16] = {'\0'}; + struct label *lab; + size_t length; + bool exist; + int err = 0; + u16_t i; + + BT_DBG("%s", __func__); + + buf = bt_mesh_get_core_settings_item(name); + if (!buf) { + return 0; + } + + length = buf->len; + + for (i = 0U; i < length / SETTINGS_ITEM_SIZE; i++) { + u16_t index = net_buf_simple_pull_le16(buf); + sprintf(get, "mesh/va/%04x", index); + + err = bt_mesh_load_core_settings(get, (u8_t *)&va, sizeof(va), &exist); + if (err) { + BT_ERR("%s, Failed to load virtual address %s", __func__, get); + goto free; + } + + if (exist == false) { + continue; + } + + if (va.ref == 0) { + BT_DBG("Ignore virtual address %s with ref = 0", get); + goto free; + } + + lab = get_label(index); + if (lab == NULL) { + BT_WARN("%s, Out of labels buffers", __func__); + err = -ENOBUFS; + goto free; + } + + memcpy(lab->uuid, va.uuid, 16); + lab->addr = va.addr; + lab->ref = va.ref; + + BT_DBG("Restore virtual address 0x%04x ref 0x%04x", index, lab->ref); + } + +free: + bt_mesh_free_buf(buf); + return err; +} +#endif + const struct bt_mesh_setting { const char *name; int (*func)(const char *name); @@ -709,6 +778,9 @@ const struct bt_mesh_setting { { "mesh/cfg", cfg_set }, { "mesh/sig", sig_mod_set }, { "mesh/vnd", vnd_mod_set }, +#if CONFIG_BLE_MESH_LABEL_COUNT > 0 + { "mesh/vaddr", va_set }, +#endif }; int settings_core_load(void) @@ -1331,6 +1403,52 @@ static void store_pending_mod(struct bt_mesh_model *model, } } +#define IS_VA_DEL(_label) ((_label)->ref == 0) +static void store_pending_va(void) +{ + struct va_val va = {0}; + char name[16] = {'\0'}; + struct label *lab; + u16_t i; + int err; + + for (i = 0U; (lab = get_label(i)) != NULL; i++) { + if (!bt_mesh_atomic_test_and_clear_bit(lab->flags, + BLE_MESH_VA_CHANGED)) { + continue; + } + + sprintf(name, "mesh/va/%04x", i); + + if (IS_VA_DEL(lab)) { + err = bt_mesh_save_core_settings(name, NULL, 0); + } else { + va.ref = lab->ref; + va.addr = lab->addr; + memcpy(va.uuid, lab->uuid, 16); + err = bt_mesh_save_core_settings(name, (const u8_t *)&va, sizeof(va)); + } + if (err) { + BT_ERR("%s, Failed to %s virtual address %s", __func__, + IS_VA_DEL(lab) ? "delete" : "store", name); + return; + } + + if (IS_VA_DEL(lab)) { + err = bt_mesh_remove_core_settings_item("mesh/vaddr", i); + } else { + err = bt_mesh_add_core_settings_item("mesh/vaddr", i); + } + if (err) { + BT_ERR("%s, Failed to %s 0x%04x in mesh/vaddr", __func__, + IS_VA_DEL(lab) ? "delete" : "store", i); + return; + } + + BT_DBG("%s virtual address 0x%04x", IS_VA_DEL(lab) ? "Delete" : "Store", i); + } +} + static void store_pending(struct k_work *work) { BT_DBG("%s", __func__); @@ -1386,6 +1504,10 @@ static void store_pending(struct k_work *work) bt_mesh_save_core_settings("mesh/vnd", NULL, 0); } } + + if (bt_mesh_atomic_test_and_clear_bit(bt_mesh.flags, BLE_MESH_VA_PENDING)) { + store_pending_va(); + } } void bt_mesh_store_rpl(struct bt_mesh_rpl *entry) @@ -1570,6 +1692,11 @@ void bt_mesh_store_mod_pub(struct bt_mesh_model *model) schedule_store(BLE_MESH_MOD_PENDING); } +void bt_mesh_store_label(void) +{ + schedule_store(BLE_MESH_VA_PENDING); +} + int settings_core_init(void) { BT_DBG("%s", __func__); diff --git a/components/bt/esp_ble_mesh/mesh_core/settings.h b/components/bt/esp_ble_mesh/mesh_core/settings.h index 84b5e182b..3b1c4c696 100644 --- a/components/bt/esp_ble_mesh/mesh_core/settings.h +++ b/components/bt/esp_ble_mesh/mesh_core/settings.h @@ -28,6 +28,7 @@ void bt_mesh_store_cfg(void); void bt_mesh_store_mod_bind(struct bt_mesh_model *mod); void bt_mesh_store_mod_sub(struct bt_mesh_model *mod); void bt_mesh_store_mod_pub(struct bt_mesh_model *mod); +void bt_mesh_store_label(void); void bt_mesh_clear_net(void); void bt_mesh_clear_subnet(struct bt_mesh_subnet *sub); From 197e54053e95a0d096f5f2de23b98fbfd798673d Mon Sep 17 00:00:00 2001 From: lly Date: Fri, 29 Nov 2019 17:07:59 +0800 Subject: [PATCH 13/21] ble_mesh: fix virtual addr wrong return value Fixes missing return value on `va_del` Fixes wrong return value on `va_add` --- components/bt/esp_ble_mesh/mesh_core/cfg_srv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c index e02da1d5e..b3c2b2609 100644 --- a/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c +++ b/components/bt/esp_ble_mesh/mesh_core/cfg_srv.c @@ -1200,7 +1200,7 @@ static u8_t va_add(u8_t *label_uuid, u16_t *addr) if (update) { update->ref++; va_store(update); - return 0; + return STATUS_SUCCESS; } if (!free_slot) { @@ -1232,6 +1232,7 @@ static u8_t va_del(u8_t *label_uuid, u16_t *addr) } va_store(update); + return STATUS_SUCCESS; } if (addr) { From 131a4e7c222b36a9899fce43cbbb921d44fbf739 Mon Sep 17 00:00:00 2001 From: lly Date: Mon, 2 Dec 2019 17:42:40 +0800 Subject: [PATCH 14/21] ble_mesh: fix provisioner failed to send msg to 0xFFFF According to Mesh Spec 3.4.5.3, a node shall implement a local network interface. And here we limit the situation just based on the spec, and Provisioner directly sending the msg without passing through the local network interface. --- components/bt/esp_ble_mesh/mesh_core/net.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 0592031a7..55ba8afb1 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -935,8 +935,9 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, #endif /* Deliver to local network interface if necessary */ - if (bt_mesh_fixed_group_match(tx->ctx->addr) || - bt_mesh_elem_find(tx->ctx->addr)) { + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned() && + (bt_mesh_fixed_group_match(tx->ctx->addr) || + bt_mesh_elem_find(tx->ctx->addr))) { if (cb && cb->start) { cb->start(0, 0, cb_data); } From 77e7d023b9b3762ffa86aba2c74d344531ca86dd Mon Sep 17 00:00:00 2001 From: lly Date: Fri, 6 Dec 2019 11:58:35 +0800 Subject: [PATCH 15/21] ble_mesh: Fixes wrong subnet info used for Friend Clear When Friend node tries to send Friend Clear message to other Friend nodes, it should use the subnet information based on the net_idx from friendship. --- components/bt/esp_ble_mesh/mesh_core/friend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 880b123e6..67a9ef04c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -363,7 +363,7 @@ static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd, 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, NODE, meta->net.ctx.addr); + &meta->aid, 0x0, meta->net.ctx.addr); if (err) { return err; } @@ -774,7 +774,7 @@ static void send_friend_clear(struct bt_mesh_friend *frnd) .send_ttl = BLE_MESH_TTL_MAX, }; struct bt_mesh_net_tx tx = { - .sub = &bt_mesh.sub[0], + .sub = bt_mesh_subnet_get(frnd->net_idx), .ctx = &ctx, .src = bt_mesh_primary_addr(), .xmit = bt_mesh_net_transmit_get(), From d83c37faed3c799b4cd4ad65a5596d1b03eaf0c8 Mon Sep 17 00:00:00 2001 From: lly Date: Fri, 6 Dec 2019 15:34:18 +0800 Subject: [PATCH 16/21] ble_mesh: Fixes Provisioner not support friend feature --- components/bt/esp_ble_mesh/Kconfig.in | 3 +- .../bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c | 14 +- components/bt/esp_ble_mesh/mesh_core/friend.c | 54 +++++++- components/bt/esp_ble_mesh/mesh_core/friend.h | 2 + components/bt/esp_ble_mesh/mesh_core/main.c | 8 ++ components/bt/esp_ble_mesh/mesh_core/net.c | 16 +-- .../esp_ble_mesh/mesh_core/provisioner_main.c | 5 + .../bt/esp_ble_mesh/mesh_core/transport.c | 128 +++++++++--------- 8 files changed, 138 insertions(+), 92 deletions(-) diff --git a/components/bt/esp_ble_mesh/Kconfig.in b/components/bt/esp_ble_mesh/Kconfig.in index 44d7fec6b..4309cdb3e 100644 --- a/components/bt/esp_ble_mesh/Kconfig.in +++ b/components/bt/esp_ble_mesh/Kconfig.in @@ -590,8 +590,7 @@ if BLE_MESH endif # BLE_MESH_LOW_POWER config BLE_MESH_FRIEND - bool "Support for acting as a Friend Node" - depends on BLE_MESH_NODE + bool "Support for Friend feature" help Enable this option to be able to act as a Friend Node. diff --git a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c index 415a543a0..7bd500ae2 100644 --- a/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c +++ b/components/bt/esp_ble_mesh/btc/btc_ble_mesh_prov.c @@ -783,7 +783,6 @@ static void btc_ble_mesh_heartbeat_msg_recv_cb(u8_t hops, u16_t feature) return; } -#if CONFIG_BLE_MESH_NODE #if CONFIG_BLE_MESH_LOW_POWER static void btc_ble_mesh_lpn_cb(u16_t friend_addr, bool established) { @@ -831,7 +830,6 @@ void btc_ble_mesh_friend_cb(bool establish, u16_t lpn_addr, u8_t reason) return; } #endif /* CONFIG_BLE_MESH_FRIEND */ -#endif /* CONFIG_BLE_MESH_NODE */ #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT static void btc_ble_mesh_proxy_client_adv_recv_cb(const bt_mesh_addr_t *addr, @@ -1507,12 +1505,6 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) arg->mesh_init.prov->link_close_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_link_close_cb; arg->mesh_init.prov->complete_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_complete_cb; arg->mesh_init.prov->reset_cb = (esp_ble_mesh_cb_t)btc_ble_mesh_reset_cb; -#if CONFIG_BLE_MESH_LOW_POWER - bt_mesh_lpn_set_cb(btc_ble_mesh_lpn_cb); -#endif /* CONFIG_BLE_MESH_LOW_POWER */ -#if CONFIG_BLE_MESH_FRIEND - bt_mesh_friend_set_cb(btc_ble_mesh_friend_cb); -#endif /* CONFIG_BLE_MESH_FRIEND */ #endif /* CONFIG_BLE_MESH_NODE */ #if CONFIG_BLE_MESH_PROVISIONER arg->mesh_init.prov->provisioner_prov_read_oob_pub_key = (esp_ble_mesh_cb_t)btc_ble_mesh_provisioner_prov_read_oob_pub_key_cb; @@ -1523,6 +1515,12 @@ void btc_ble_mesh_prov_call_handler(btc_msg_t *msg) arg->mesh_init.prov->provisioner_prov_comp = (esp_ble_mesh_cb_t)btc_ble_mesh_provisioner_prov_complete_cb; bt_mesh_prov_adv_pkt_cb_register(btc_ble_mesh_provisioner_recv_unprov_adv_pkt_cb); #endif /* CONFIG_BLE_MESH_PROVISIONER */ +#if CONFIG_BLE_MESH_LOW_POWER + bt_mesh_lpn_set_cb(btc_ble_mesh_lpn_cb); +#endif /* CONFIG_BLE_MESH_LOW_POWER */ +#if CONFIG_BLE_MESH_FRIEND + bt_mesh_friend_set_cb(btc_ble_mesh_friend_cb); +#endif /* CONFIG_BLE_MESH_FRIEND */ #if CONFIG_BLE_MESH_GATT_PROXY_CLIENT bt_mesh_proxy_client_set_adv_recv_cb(btc_ble_mesh_proxy_client_adv_recv_cb); bt_mesh_proxy_client_set_conn_cb(btc_ble_mesh_proxy_client_connect_cb); diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.c b/components/bt/esp_ble_mesh/mesh_core/friend.c index 67a9ef04c..894e88cf5 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.c +++ b/components/bt/esp_ble_mesh/mesh_core/friend.c @@ -26,6 +26,8 @@ #include "access.h" #include "foundation.h" #include "friend.h" +#include "client_common.h" +#include "provisioner_main.h" #ifdef CONFIG_BLE_MESH_FRIEND @@ -72,7 +74,18 @@ enum { static void (*friend_cb)(bool establish, u16_t lpn_addr, u8_t reason); +static struct bt_mesh_subnet *friend_subnet_get(u16_t net_idx) +{ + struct bt_mesh_subnet *sub = NULL; + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { + sub = bt_mesh_subnet_get(net_idx); + } else if (IS_ENABLED(CONFIG_BLE_MESH_PROVISIONER) && bt_mesh_is_provisioner_en()) { + sub = provisioner_subnet_get(net_idx); + } + + return sub; +} static struct bt_mesh_adv *adv_alloc(int id) { @@ -357,20 +370,31 @@ static int unseg_app_sdu_unpack(struct bt_mesh_friend *frnd, struct unseg_app_sdu_meta *meta) { u16_t app_idx = FRIEND_ADV(buf)->app_idx; + u8_t role; int err; - meta->subnet = bt_mesh_subnet_get(frnd->net_idx); + 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, 0x0, meta->net.ctx.addr); + &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 { @@ -451,13 +475,18 @@ static int unseg_app_sdu_prepare(struct bt_mesh_friend *frnd, static int encrypt_friend_pdu(struct bt_mesh_friend *frnd, struct net_buf *buf, bool master_cred) { - struct bt_mesh_subnet *sub = bt_mesh_subnet_get(frnd->net_idx); + 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; @@ -534,7 +563,7 @@ static struct net_buf *encode_update(struct bt_mesh_friend *frnd, u8_t md) { struct bt_mesh_ctl_friend_update *upd; NET_BUF_SIMPLE_DEFINE(sdu, 1 + sizeof(*upd)); - struct bt_mesh_subnet *sub = bt_mesh_subnet_get(frnd->net_idx); + struct bt_mesh_subnet *sub = friend_subnet_get(frnd->net_idx); __ASSERT_NO_MSG(sub != NULL); @@ -774,7 +803,7 @@ static void send_friend_clear(struct bt_mesh_friend *frnd) .send_ttl = BLE_MESH_TTL_MAX, }; struct bt_mesh_net_tx tx = { - .sub = bt_mesh_subnet_get(frnd->net_idx), + .sub = friend_subnet_get(frnd->net_idx), .ctx = &ctx, .src = bt_mesh_primary_addr(), .xmit = bt_mesh_net_transmit_get(), @@ -786,6 +815,11 @@ static void send_friend_clear(struct bt_mesh_friend *frnd) BT_DBG("%s", __func__); + if (!tx.sub) { + BT_ERR("Invalid subnet for Friend Clear"); + return; + } + bt_mesh_ctl_send(&tx, TRANS_CTL_OP_FRIEND_CLEAR, &req, sizeof(req), NULL, &clear_sent_cb, frnd); } @@ -1647,4 +1681,14 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src, } } +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 */ diff --git a/components/bt/esp_ble_mesh/mesh_core/friend.h b/components/bt/esp_ble_mesh/mesh_core/friend.h index c6ecf7e6c..8c1fbe57b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/friend.h +++ b/components/bt/esp_ble_mesh/mesh_core/friend.h @@ -51,4 +51,6 @@ int bt_mesh_friend_sub_rem(struct bt_mesh_net_rx *rx, int bt_mesh_friend_init(void); +void bt_mesh_friend_remove_lpn(u16_t lpn_addr); + #endif /* _FRIEND_H_ */ diff --git a/components/bt/esp_ble_mesh/mesh_core/main.c b/components/bt/esp_ble_mesh/mesh_core/main.c index 13dc03610..90b00e635 100644 --- a/components/bt/esp_ble_mesh/mesh_core/main.c +++ b/components/bt/esp_ble_mesh/mesh_core/main.c @@ -413,6 +413,10 @@ int bt_mesh_provisioner_enable(bt_mesh_prov_bearer_t bearers) provisioner_pb_gatt_enable(); } + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { + bt_mesh_friend_init(); + } + provisioner_en = true; return 0; @@ -437,6 +441,10 @@ int bt_mesh_provisioner_disable(bt_mesh_prov_bearer_t bearers) bt_mesh_scan_disable(); } + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { + bt_mesh_friend_clear_net_idx(BLE_MESH_KEY_ANY); + } + provisioner_en = false; return 0; diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 55ba8afb1..640ad61ae 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -1123,18 +1123,14 @@ static bool net_find_and_decrypt(const u8_t *data, size_t data_len, continue; } -#if CONFIG_BLE_MESH_NODE - if (bt_mesh_is_provisioned()) { #if (defined(CONFIG_BLE_MESH_LOW_POWER) || defined(CONFIG_BLE_MESH_FRIEND)) - if (!friend_decrypt(sub, data, data_len, rx, buf)) { - rx->friend_cred = 1; - rx->ctx.net_idx = sub->net_idx; - rx->sub = sub; - return true; - } -#endif + if (!friend_decrypt(sub, data, data_len, rx, buf)) { + rx->friend_cred = 1; + rx->ctx.net_idx = sub->net_idx; + rx->sub = sub; + return true; } -#endif /* CONFIG_BLE_MESH_NODE */ +#endif if (NID(data) == sub->keys[0].nid && !net_decrypt(sub, sub->keys[0].enc, sub->keys[0].privacy, diff --git a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c index 7b40331a0..8fc1d4b3c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c +++ b/components/bt/esp_ble_mesh/mesh_core/provisioner_main.c @@ -28,6 +28,7 @@ #include "adv.h" #include "net.h" #include "access.h" +#include "friend.h" #include "provisioner_prov.h" #include "proxy_client.h" @@ -142,6 +143,10 @@ int provisioner_node_reset(int node_index) } } + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { + bt_mesh_friend_remove_lpn(node->unicast_addr); + } + osi_free(mesh_nodes[node_index]); mesh_nodes[node_index] = NULL; diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index bedfbe3f6..2235f7719 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -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); - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { - if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, - tx->src, tx->ctx->addr, - NULL, 1)) { - if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - 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. - */ + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { + if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, + tx->src, tx->ctx->addr, + NULL, 1)) { + if (BLE_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { + BT_ERR("Not enough space in Friend Queue"); net_buf_unref(buf); - send_cb_finalize(cb, cb_data); - return 0; + 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); + send_cb_finalize(cb, cb_data); + return 0; + } } send: @@ -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_simple_pull(sdu, len); - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { - enum bt_mesh_friend_pdu_type type; + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND)) { + enum bt_mesh_friend_pdu_type type; - if (seg_o == tx->seg_n) { - type = BLE_MESH_FRIEND_PDU_COMPLETE; - } else { - type = BLE_MESH_FRIEND_PDU_PARTIAL; - } + if (seg_o == tx->seg_n) { + type = BLE_MESH_FRIEND_PDU_COMPLETE; + } else { + type = BLE_MESH_FRIEND_PDU_PARTIAL; + } - if (bt_mesh_friend_enqueue_tx(net_tx, type, - &tx->seq_auth, - tx->seg_n + 1, - &seg->b) && - BLE_MESH_ADDR_IS_UNICAST(net_tx->ctx->addr)) { - /* PDUs for a specific Friend should only go - * out through the Friend Queue. - */ - net_buf_unref(seg); - continue; - } + if (bt_mesh_friend_enqueue_tx(net_tx, type, + &tx->seq_auth, + tx->seg_n + 1, + &seg->b) && + BLE_MESH_ADDR_IS_UNICAST(net_tx->ctx->addr)) { + /* PDUs for a specific Friend should only go + * out through the Friend Queue. + */ + net_buf_unref(seg); + continue; } } @@ -904,24 +900,24 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr, return 0; } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) { - switch (ctl_op) { - case TRANS_CTL_OP_FRIEND_POLL: - return bt_mesh_friend_poll(rx, buf); - case TRANS_CTL_OP_FRIEND_REQ: - return bt_mesh_friend_req(rx, buf); - case TRANS_CTL_OP_FRIEND_CLEAR: - return bt_mesh_friend_clear(rx, buf); - case TRANS_CTL_OP_FRIEND_CLEAR_CFM: - return bt_mesh_friend_clear_cfm(rx, buf); - case TRANS_CTL_OP_FRIEND_SUB_ADD: - return bt_mesh_friend_sub_add(rx, buf); - case TRANS_CTL_OP_FRIEND_SUB_REM: - return bt_mesh_friend_sub_rem(rx, buf); - } + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && !bt_mesh_lpn_established()) { + switch (ctl_op) { + case TRANS_CTL_OP_FRIEND_POLL: + return bt_mesh_friend_poll(rx, buf); + case TRANS_CTL_OP_FRIEND_REQ: + return bt_mesh_friend_req(rx, buf); + case TRANS_CTL_OP_FRIEND_CLEAR: + return bt_mesh_friend_clear(rx, buf); + case TRANS_CTL_OP_FRIEND_CLEAR_CFM: + return bt_mesh_friend_clear_cfm(rx, buf); + case TRANS_CTL_OP_FRIEND_SUB_ADD: + return bt_mesh_friend_sub_add(rx, buf); + case TRANS_CTL_OP_FRIEND_SUB_REM: + return bt_mesh_friend_sub_rem(rx, buf); } + } + if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { #if defined(CONFIG_BLE_MESH_LOW_POWER) if (ctl_op == TRANS_CTL_OP_FRIEND_OFFER) { return bt_mesh_lpn_friend_offer(rx, buf); @@ -1530,15 +1526,13 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) net_buf_simple_restore(buf, &state); - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->friend_match && !err) { - if (seq_auth == TRANS_SEQ_AUTH_NVAL) { - bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL, - seg_count, buf); - } else { - bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth, - seg_count, buf); - } + if (IS_ENABLED(CONFIG_BLE_MESH_FRIEND) && rx->friend_match && !err) { + if (seq_auth == TRANS_SEQ_AUTH_NVAL) { + bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL, + seg_count, buf); + } else { + bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth, + seg_count, buf); } } From b836674d8e1349943ce37d87b7895a8cfe6bd35c Mon Sep 17 00:00:00 2001 From: lly Date: Fri, 6 Dec 2019 15:59:10 +0800 Subject: [PATCH 17/21] ble_mesh: Remove useless CONFIG_BLE_MESH_NODE For Low Power node and Proxy Server, the two features depend on BLE_MESH_NODE in Kconfig.in, here in the stack there is no need to judge if CONFIG_BLE_MESH_NODE is enabled. --- components/bt/esp_ble_mesh/mesh_core/net.c | 10 +-- .../bt/esp_ble_mesh/mesh_core/transport.c | 74 +++++++++---------- 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/net.c b/components/bt/esp_ble_mesh/mesh_core/net.c index 640ad61ae..d021d333c 100644 --- a/components/bt/esp_ble_mesh/mesh_core/net.c +++ b/components/bt/esp_ble_mesh/mesh_core/net.c @@ -789,12 +789,10 @@ int bt_mesh_net_resend(struct bt_mesh_subnet *sub, struct net_buf *buf, return err; } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && - bt_mesh_proxy_relay(&buf->b, dst)) { - send_cb_finalize(cb, cb_data); - return 0; - } + if (IS_ENABLED(CONFIG_BLE_MESH_GATT_PROXY_SERVER) && + bt_mesh_proxy_relay(&buf->b, dst)) { + send_cb_finalize(cb, cb_data); + return 0; } bt_mesh_adv_send(buf, cb, cb_data); diff --git a/components/bt/esp_ble_mesh/mesh_core/transport.c b/components/bt/esp_ble_mesh/mesh_core/transport.c index 2235f7719..5b0a9a968 100644 --- a/components/bt/esp_ble_mesh/mesh_core/transport.c +++ b/components/bt/esp_ble_mesh/mesh_core/transport.c @@ -457,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); } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && - bt_mesh_lpn_established()) { - bt_mesh_lpn_poll(); - } + if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && + bt_mesh_lpn_established()) { + bt_mesh_lpn_poll(); } return 0; @@ -917,32 +915,30 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, u8_t hdr, } } - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { #if defined(CONFIG_BLE_MESH_LOW_POWER) - if (ctl_op == TRANS_CTL_OP_FRIEND_OFFER) { - 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 (ctl_op == TRANS_CTL_OP_FRIEND_OFFER) { + 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 */ + BT_WARN("Unhandled TransOpCode 0x%02x", ctl_op); return -ENOENT; @@ -1477,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 * be encrypted using the Friend Credentials. */ - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && - bt_mesh_lpn_established() && rx->net_if == BLE_MESH_NET_IF_ADV && - (!bt_mesh_lpn_waiting_update() || !rx->friend_cred)) { - BT_WARN("Ignoring unexpected message in Low Power mode"); - return -EAGAIN; - } + if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && + bt_mesh_lpn_established() && rx->net_if == BLE_MESH_NET_IF_ADV && + (!bt_mesh_lpn_waiting_update() || !rx->friend_cred)) { + BT_WARN("Ignoring unexpected message in Low Power mode"); + return -EAGAIN; } /* Save the app-level state so the buffer can later be placed in @@ -1516,12 +1510,10 @@ int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) * timer, in which case we want to reset the timer at this point. * */ - if (IS_ENABLED(CONFIG_BLE_MESH_NODE) && bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && - (bt_mesh_lpn_timer() || - (bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()))) { - bt_mesh_lpn_msg_received(rx); - } + if (IS_ENABLED(CONFIG_BLE_MESH_LOW_POWER) && + (bt_mesh_lpn_timer() || + (bt_mesh_lpn_established() && bt_mesh_lpn_waiting_update()))) { + bt_mesh_lpn_msg_received(rx); } net_buf_simple_restore(buf, &state); From 82b4b89dea358bcaec416b8e9120cd3c80c11201 Mon Sep 17 00:00:00 2001 From: lly Date: Tue, 17 Dec 2019 14:36:36 +0800 Subject: [PATCH 18/21] ble_mesh: Fix compile error when using release optimization level --- components/bt/esp_ble_mesh/mesh_core/adv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/adv.c b/components/bt/esp_ble_mesh/mesh_core/adv.c index c57853182..e61eb259b 100644 --- a/components/bt/esp_ble_mesh/mesh_core/adv.c +++ b/components/bt/esp_ble_mesh/mesh_core/adv.c @@ -606,7 +606,7 @@ static void bt_mesh_scan_cb(const bt_mesh_addr_t *addr, s8_t rssi, { #if (CONFIG_BLE_MESH_PROVISIONER && CONFIG_BLE_MESH_PB_GATT) || \ CONFIG_BLE_MESH_GATT_PROXY_CLIENT - u16_t uuid; + u16_t uuid = 0x0; #endif if (adv_type != BLE_MESH_ADV_NONCONN_IND && adv_type != BLE_MESH_ADV_IND) { From 7d7bbec5fefb27b18549eeee779416dd929e5ec5 Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 19 Dec 2019 22:13:19 +0800 Subject: [PATCH 19/21] ble_mesh: Make model publication struct more compact Previously the FastPeriodDivisor value was introduced to the model publication struct. Based on the way it was grouped it seems the intention was to fit it within the same octet as other bit fields, but it actually makes the octet overflow by one bit. This ends up creating another u8_t variable which in turn adds 24 bits of padding after it. To keep the size of the struct as compact as possible, group the flag together with the key index, since that only requires 12 bits. Some care is needed here, since the mesh stack does have special internal key index values that require more than 12 bits such as BLE_MESH_KEY_UNUSED and BLE_MESH_KEY_DEV. In this case restricting ourselves to 12 bits is fine since the value in the model publication struct follows 1:1 the value received in the Config Model Publication Set message, and there the parameter is defined to be exactly 12 bits. --- components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h | 10 +++++----- .../bt/esp_ble_mesh/mesh_core/include/mesh_access.h | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h index 6263c0124..733c718aa 100644 --- a/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h +++ b/components/bt/esp_ble_mesh/api/esp_ble_mesh_defs.h @@ -356,16 +356,16 @@ typedef struct { esp_ble_mesh_model_t *model; uint16_t publish_addr; /*!< Publish Address. */ - uint16_t app_idx; /*!< Publish AppKey Index. */ + uint16_t app_idx:12, /*!< Publish AppKey Index. */ + cred:1; /*!< Friendship Credentials Flag. */ uint8_t ttl; /*!< Publish Time to Live. */ uint8_t retransmit; /*!< Retransmit Count & Interval Steps. */ uint8_t period; /*!< Publish Period. */ - uint16_t period_div: 4, /*!< Divisor for the Period. */ - cred: 1, /*!< Friendship Credentials Flag. */ - fast_period: 1, /*!< Use FastPeriodDivisor */ - count: 3; /*!< Retransmissions left. */ + uint8_t period_div:4, /*!< Divisor for the Period. */ + fast_period:1, /*!< Use FastPeriodDivisor */ + count:3; /*!< Retransmissions left. */ uint32_t period_start; /*!< Start of the current period. */ diff --git a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h index 0d5e4f66f..8c387a681 100644 --- a/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h +++ b/components/bt/esp_ble_mesh/mesh_core/include/mesh_access.h @@ -335,15 +335,15 @@ struct bt_mesh_model_pub { struct bt_mesh_model *mod; u16_t addr; /**< Publish Address. */ - u16_t key; /**< Publish AppKey Index. */ + u16_t key:12, /**< Publish AppKey Index. */ + cred:1; /**< Friendship Credentials Flag. */ u8_t ttl; /**< Publish Time to Live. */ u8_t retransmit; /**< Retransmit Count & Interval Steps. */ u8_t period; /**< Publish Period. */ - u16_t period_div: 4, /**< Divisor for the Period. */ - cred: 1, /**< Friendship Credentials Flag. */ - fast_period: 1, /**< Use FastPeriodDivisor */ - count: 3; /**< Retransmissions left. */ + u8_t period_div:4, /**< Divisor for the Period. */ + fast_period:1,/**< Use FastPeriodDivisor */ + count:3; /**< Retransmissions left. */ u32_t period_start; /**< Start of the current period. */ From fc80d107ad50790a7c48f2e30a2a98242b4914a1 Mon Sep 17 00:00:00 2001 From: lly Date: Thu, 19 Dec 2019 22:29:19 +0800 Subject: [PATCH 20/21] ble_mesh: Fix next_period computation If the duration to publish is roughly the same as the period, we might end up with elapsed == period, which returns 0 and cancel the periodic publication. Instead 1 should be returned, just like when the elapsed time is greater than the period. --- components/bt/esp_ble_mesh/mesh_core/access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/access.c b/components/bt/esp_ble_mesh/mesh_core/access.c index 989b1f0a6..65b0f9129 100644 --- a/components/bt/esp_ble_mesh/mesh_core/access.c +++ b/components/bt/esp_ble_mesh/mesh_core/access.c @@ -227,7 +227,7 @@ static s32_t next_period(struct bt_mesh_model *mod) BT_DBG("Publishing took %ums", elapsed); - if (elapsed > period) { + if (elapsed >= period) { BT_WARN("Publication sending took longer than the period"); /* Return smallest positive number since 0 means disabled */ return K_MSEC(1); From 8116a787cd4970e6324a4a0d294027b1f100b999 Mon Sep 17 00:00:00 2001 From: lly Date: Mon, 6 Jan 2020 16:18:52 +0800 Subject: [PATCH 21/21] ble_mesh: Fix PreviousAddress endianess in Friend Request The upper transport layer is using big endian ordering. The PreviousAddress field of a Friend Request message should therefore be converted to native endianess using sys_cpu_to_be16(). --- components/bt/esp_ble_mesh/mesh_core/lpn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/mesh_core/lpn.c b/components/bt/esp_ble_mesh/mesh_core/lpn.c index 06358cac4..a99b28dc4 100644 --- a/components/bt/esp_ble_mesh/mesh_core/lpn.c +++ b/components/bt/esp_ble_mesh/mesh_core/lpn.c @@ -324,7 +324,7 @@ static int send_friend_req(struct bt_mesh_lpn *lpn) .criteria = LPN_CRITERIA, .recv_delay = LPN_RECV_DELAY, .poll_to = LPN_POLL_TO, - .prev_addr = lpn->old_friend, + .prev_addr = sys_cpu_to_be16(lpn->old_friend), .num_elem = comp->elem_count, .lpn_counter = sys_cpu_to_be16(lpn->counter), };