Revert "bluetooth: mesh: Remove illegal use of NET_BUF_FRAG in friend.c"
This reverts commit 5d059117fd
.
Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
This commit is contained in:
parent
fab547f047
commit
7b4f94220d
2 changed files with 27 additions and 43 deletions
|
@ -135,22 +135,13 @@ static void purge_buffers(sys_slist_t *list)
|
||||||
|
|
||||||
buf = (void *)sys_slist_get_not_empty(list);
|
buf = (void *)sys_slist_get_not_empty(list);
|
||||||
|
|
||||||
|
buf->frags = NULL;
|
||||||
|
buf->flags &= ~NET_BUF_FRAGS;
|
||||||
|
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void purge_seg_buffers(struct net_buf *buf)
|
|
||||||
{
|
|
||||||
/* Fragments head has always 2 references: one when allocated, one when becomes
|
|
||||||
* fragments head.
|
|
||||||
*/
|
|
||||||
net_buf_unref(buf);
|
|
||||||
|
|
||||||
do {
|
|
||||||
buf = net_buf_frag_del(NULL, buf);
|
|
||||||
} while (buf != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Intentionally start a little bit late into the ReceiveWindow when
|
/* Intentionally start a little bit late into the ReceiveWindow when
|
||||||
* it's large enough. This may improve reliability with some platforms,
|
* it's large enough. This may improve reliability with some platforms,
|
||||||
* like the PTS, where the receiver might not have sufficiently compensated
|
* like the PTS, where the receiver might not have sufficiently compensated
|
||||||
|
@ -186,10 +177,8 @@ static void friend_clear(struct bt_mesh_friend *frnd)
|
||||||
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
||||||
struct bt_mesh_friend_seg *seg = &frnd->seg[i];
|
struct bt_mesh_friend_seg *seg = &frnd->seg[i];
|
||||||
|
|
||||||
if (seg->buf) {
|
purge_buffers(&seg->queue);
|
||||||
purge_seg_buffers(seg->buf);
|
seg->seg_count = 0U;
|
||||||
seg->seg_count = 0U;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STRUCT_SECTION_FOREACH(bt_mesh_friend_cb, cb) {
|
STRUCT_SECTION_FOREACH(bt_mesh_friend_cb, cb) {
|
||||||
|
@ -1076,7 +1065,7 @@ init_friend:
|
||||||
|
|
||||||
static bool is_seg(struct bt_mesh_friend_seg *seg, uint16_t src, uint16_t seq_zero)
|
static bool is_seg(struct bt_mesh_friend_seg *seg, uint16_t src, uint16_t seq_zero)
|
||||||
{
|
{
|
||||||
struct net_buf *buf = seg->buf;
|
struct net_buf *buf = (void *)sys_slist_peek_head(&seg->queue);
|
||||||
struct net_buf_simple_state state;
|
struct net_buf_simple_state state;
|
||||||
uint16_t buf_seq_zero;
|
uint16_t buf_seq_zero;
|
||||||
uint16_t buf_src;
|
uint16_t buf_src;
|
||||||
|
@ -1109,7 +1098,7 @@ static struct bt_mesh_friend_seg *get_seg(struct bt_mesh_friend *frnd,
|
||||||
return seg;
|
return seg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!unassigned && !seg->buf) {
|
if (!unassigned && !sys_slist_peek_head(&seg->queue)) {
|
||||||
unassigned = seg;
|
unassigned = seg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1144,13 +1133,16 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
seg->buf = net_buf_frag_add(seg->buf, buf);
|
net_buf_slist_put(&seg->queue, buf);
|
||||||
|
|
||||||
if (type == BT_MESH_FRIEND_PDU_COMPLETE) {
|
if (type == BT_MESH_FRIEND_PDU_COMPLETE) {
|
||||||
net_buf_slist_put(&frnd->queue, seg->buf);
|
sys_slist_merge_slist(&frnd->queue, &seg->queue);
|
||||||
|
|
||||||
frnd->queue_size += seg->seg_count;
|
frnd->queue_size += seg->seg_count;
|
||||||
seg->seg_count = 0U;
|
seg->seg_count = 0U;
|
||||||
|
} else {
|
||||||
|
/* Mark the buffer as having more to come after it */
|
||||||
|
buf->flags |= NET_BUF_FRAGS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1267,15 +1259,6 @@ static void friend_timeout(struct k_work *work)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put next segment to the friend queue. */
|
|
||||||
if (frnd->last != net_buf_frag_last(frnd->last)) {
|
|
||||||
struct net_buf *next;
|
|
||||||
|
|
||||||
next = net_buf_frag_del(NULL, frnd->last);
|
|
||||||
net_buf_frag_add(NULL, next);
|
|
||||||
sys_slist_prepend(&frnd->queue, &next->node);
|
|
||||||
}
|
|
||||||
|
|
||||||
md = (uint8_t)(sys_slist_peek_head(&frnd->queue) != NULL);
|
md = (uint8_t)(sys_slist_peek_head(&frnd->queue) != NULL);
|
||||||
|
|
||||||
update_overwrite(frnd->last, md);
|
update_overwrite(frnd->last, md);
|
||||||
|
@ -1284,6 +1267,10 @@ static void friend_timeout(struct k_work *work)
|
||||||
return;
|
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);
|
LOG_DBG("Sending buf %p from Friend Queue of LPN 0x%04x", frnd->last, frnd->lpn);
|
||||||
frnd->queue_size--;
|
frnd->queue_size--;
|
||||||
|
|
||||||
|
@ -1357,11 +1344,16 @@ int bt_mesh_friend_init(void)
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
|
for (i = 0; i < ARRAY_SIZE(bt_mesh.frnd); i++) {
|
||||||
struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
|
struct bt_mesh_friend *frnd = &bt_mesh.frnd[i];
|
||||||
|
int j;
|
||||||
|
|
||||||
sys_slist_init(&frnd->queue);
|
sys_slist_init(&frnd->queue);
|
||||||
|
|
||||||
k_work_init_delayable(&frnd->timer, friend_timeout);
|
k_work_init_delayable(&frnd->timer, friend_timeout);
|
||||||
k_work_init_delayable(&frnd->clear.timer, clear_timeout);
|
k_work_init_delayable(&frnd->clear.timer, clear_timeout);
|
||||||
|
|
||||||
|
for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) {
|
||||||
|
sys_slist_init(&frnd->seg[j].queue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1655,16 +1647,11 @@ static bool friend_queue_prepare_space(struct bt_mesh_friend *frnd, uint16_t add
|
||||||
frnd->queue_size--;
|
frnd->queue_size--;
|
||||||
avail_space++;
|
avail_space++;
|
||||||
|
|
||||||
if (buf != net_buf_frag_last(buf)) {
|
pending_segments = (buf->flags & NET_BUF_FRAGS);
|
||||||
struct net_buf *next;
|
|
||||||
|
|
||||||
next = net_buf_frag_del(NULL, buf);
|
/* Make sure old slist entry state doesn't remain */
|
||||||
|
buf->frags = NULL;
|
||||||
net_buf_frag_add(NULL, next);
|
buf->flags &= ~NET_BUF_FRAGS;
|
||||||
sys_slist_prepend(&frnd->queue, &next->node);
|
|
||||||
|
|
||||||
pending_segments = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
net_buf_unref(buf);
|
net_buf_unref(buf);
|
||||||
}
|
}
|
||||||
|
@ -1785,7 +1772,7 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, uint16_t src,
|
||||||
|
|
||||||
LOG_WRN("Clearing incomplete segments for 0x%04x", src);
|
LOG_WRN("Clearing incomplete segments for 0x%04x", src);
|
||||||
|
|
||||||
purge_seg_buffers(seg->buf);
|
purge_buffers(&seg->queue);
|
||||||
seg->seg_count = 0U;
|
seg->seg_count = 0U;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,10 +67,7 @@ struct bt_mesh_friend {
|
||||||
struct k_work_delayable timer;
|
struct k_work_delayable timer;
|
||||||
|
|
||||||
struct bt_mesh_friend_seg {
|
struct bt_mesh_friend_seg {
|
||||||
/* First received segment of a segmented message. Rest
|
sys_slist_t queue;
|
||||||
* segments are added as net_buf fragments.
|
|
||||||
*/
|
|
||||||
struct net_buf *buf;
|
|
||||||
|
|
||||||
/* The target number of segments, i.e. not necessarily
|
/* The target number of segments, i.e. not necessarily
|
||||||
* the current number of segments, in the queue. This is
|
* the current number of segments, in the queue. This is
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue