From ffc4e716f0e58caadde21b83c743c1e113b7cd7a Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 14 Dec 2022 16:29:47 +0100 Subject: [PATCH] Bluetooth: Mesh: Add extra flag to control seg msg in frnd queue This commit fixes issue introduced in 5d059117fd279ee0eec4fb1c4d0244a37937013c. Use extra flag stored in user data of net_buf to control segmented messages in Friend Queue. The initial idea with using fragments didn't work. This fixes the following PTS tests: - MESH/NODE/FRND/FN/BV-08-C - MESH/NODE/FRND/FN/BV-19-C - MESH/NODE/CFG/HBS/BV-05-C Signed-off-by: Pavel Vasilyev --- subsys/bluetooth/mesh/friend.c | 42 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/subsys/bluetooth/mesh/friend.c b/subsys/bluetooth/mesh/friend.c index 5a9688e3df8..d9cc4279307 100644 --- a/subsys/bluetooth/mesh/friend.c +++ b/subsys/bluetooth/mesh/friend.c @@ -60,18 +60,22 @@ struct friend_pdu_info { uint32_t iv_index; }; -NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT, - BT_MESH_ADV_DATA_SIZE, 8, NULL); - -static struct friend_adv { +struct friend_adv { uint16_t app_idx; -} adv_pool[FRIEND_BUF_COUNT]; + bool seg; +}; + +NET_BUF_POOL_FIXED_DEFINE(friend_buf_pool, FRIEND_BUF_COUNT, BT_MESH_ADV_DATA_SIZE, + sizeof(struct friend_adv), NULL); + +static struct friend_adv adv_pool[FRIEND_BUF_COUNT]; #define FRIEND_ADV(buf) (*(struct friend_adv **)net_buf_user_data(buf)) static struct friend_adv *adv_alloc(int id) { adv_pool[id].app_idx = BT_MESH_KEY_UNUSED; + adv_pool[id].seg = false; return &adv_pool[id]; } @@ -130,14 +134,9 @@ static int friend_cred_create(struct bt_mesh_friend *frnd, uint8_t idx) static void purge_buffers(sys_slist_t *list) { - while (!sys_slist_is_empty(list)) { - struct net_buf *buf; - - buf = (void *)sys_slist_get_not_empty(list); - - buf->frags = NULL; - buf->flags &= ~NET_BUF_FRAGS; + struct net_buf *buf; + while ((buf = (void *)net_buf_slist_get(list))) { net_buf_unref(buf); } } @@ -1141,8 +1140,7 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd, frnd->queue_size += seg->seg_count; seg->seg_count = 0U; } else { - /* Mark the buffer as having more to come after it */ - buf->flags |= NET_BUF_FRAGS; + FRIEND_ADV(buf)->seg = true; } } @@ -1252,7 +1250,7 @@ static void friend_timeout(struct k_work *work) return; } - frnd->last = (void *)sys_slist_get(&frnd->queue); + frnd->last = (void *)net_buf_slist_get(&frnd->queue); if (!frnd->last) { LOG_WRN("Friendship not established with 0x%04x", frnd->lpn); friend_clear(frnd); @@ -1267,10 +1265,6 @@ static void friend_timeout(struct k_work *work) return; } - /* Clear the flag we use for segment tracking */ - frnd->last->flags &= ~NET_BUF_FRAGS; - frnd->last->frags = NULL; - LOG_DBG("Sending buf %p from Friend Queue of LPN 0x%04x", frnd->last, frnd->lpn); frnd->queue_size--; @@ -1411,8 +1405,6 @@ static void friend_purge_old_ack(struct bt_mesh_friend *frnd, sys_slist_remove(&frnd->queue, prev, cur); frnd->queue_size--; - /* Make sure old slist entry state doesn't remain */ - buf->frags = NULL; net_buf_unref(buf); break; @@ -1637,7 +1629,7 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t add pending_segments = false; while (pending_segments || avail_space < seg_count) { - struct net_buf *buf = (void *)sys_slist_get(&frnd->queue); + struct net_buf *buf = (void *)net_buf_slist_get(&frnd->queue); if (!buf) { LOG_ERR("Unable to free up enough buffers"); @@ -1647,11 +1639,7 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t add frnd->queue_size--; avail_space++; - pending_segments = (buf->flags & NET_BUF_FRAGS); - - /* Make sure old slist entry state doesn't remain */ - buf->frags = NULL; - buf->flags &= ~NET_BUF_FRAGS; + pending_segments = FRIEND_ADV(buf)->seg; net_buf_unref(buf); }