mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-09-16 05:59:55 +00:00
mesh: Fix sys_slist_t port and add net_buf_slist_t port
This patch fixes sys_slist_t port from Zephyr porting it verbatim. It will be used in following patches. It also defines a port of sys_slist_t for os_mbufs called net_buf_slist_t and uses it to fix issues with previous port. This port is needed, because Zephyr's sys_slist_t is not compatible with Mynewt's os_mbufs. We should not use os_mbuf_pkthdr chains to represent a list of packets, this is a hack. For now this is not an issue, because mesh does not use os_mbuf chains. We should change this in the future. X-Original-Commit: 8ac960305f2b4789b6a2b7b94492476800130372
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "os/os_mbuf.h"
|
||||
#include "os/os_callout.h"
|
||||
#include "os/os_eventq.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#include "atomic.h"
|
||||
#include "nimble/ble.h"
|
||||
@@ -394,4 +395,22 @@ static inline int net_buf_id(struct os_mbuf *buf)
|
||||
return (buf_ptr - pool_start) / BUF_SIZE(pool);
|
||||
}
|
||||
|
||||
/* XXX: We should not use os_mbuf_pkthdr chains to represent a list of
|
||||
* packets, this is a hack. For now this is not an issue, because mesh
|
||||
* does not use os_mbuf chains. We should change this in the future.
|
||||
*/
|
||||
STAILQ_HEAD(net_buf_slist_t, os_mbuf_pkthdr);
|
||||
|
||||
void net_buf_slist_init(struct net_buf_slist_t *list);
|
||||
bool net_buf_slist_is_empty(struct net_buf_slist_t *list);
|
||||
struct os_mbuf *net_buf_slist_peek_head(struct net_buf_slist_t *list);
|
||||
struct os_mbuf *net_buf_slist_peek_next(struct os_mbuf *buf);
|
||||
struct os_mbuf *net_buf_slist_get(struct net_buf_slist_t *list);
|
||||
void net_buf_slist_put(struct net_buf_slist_t *list, struct os_mbuf *buf);
|
||||
void net_buf_slist_remove(struct net_buf_slist_t *list, struct os_mbuf *prev,
|
||||
struct os_mbuf *cur);
|
||||
void net_buf_slist_merge_slist(struct net_buf_slist_t *list,
|
||||
struct net_buf_slist_t *list_to_append);
|
||||
#define NET_BUF_SLIST_FOR_EACH_NODE(head, var) STAILQ_FOREACH(var, head, omp_next)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,15 +19,22 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct os_mbuf sys_snode_t;
|
||||
|
||||
STAILQ_HEAD(_slist, os_mbuf_pkthdr);
|
||||
struct _snode {
|
||||
struct _snode *next;
|
||||
};
|
||||
|
||||
typedef struct _snode sys_snode_t;
|
||||
|
||||
struct _slist {
|
||||
sys_snode_t *head;
|
||||
sys_snode_t *tail;
|
||||
};
|
||||
|
||||
typedef struct _slist sys_slist_t;
|
||||
|
||||
@@ -46,9 +53,98 @@ typedef struct _slist sys_slist_t;
|
||||
* @param __sl A pointer on a sys_slist_t to iterate on
|
||||
* @param __sn A sys_snode_t pointer to peek each node of the list
|
||||
*/
|
||||
#define SYS_SLIST_FOR_EACH_NODE(__sl, __sn) \
|
||||
for (__sn = sys_slist_peek_head(__sl); __sn; \
|
||||
__sn = sys_slist_peek_next(__sn))
|
||||
#define SYS_SLIST_FOR_EACH_NODE(__sl, __sn) \
|
||||
for (__sn = sys_slist_peek_head(__sl); __sn; \
|
||||
__sn = sys_slist_peek_next(__sn))
|
||||
|
||||
/**
|
||||
* @brief Provide the primitive to iterate on a list, from a node in the list
|
||||
* Note: the loop is unsafe and thus __sn should not be removed
|
||||
*
|
||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||
*
|
||||
* SYS_SLIST_ITERATE_FROM_NODE(l, n) {
|
||||
* <user code>
|
||||
* }
|
||||
*
|
||||
* Like SYS_SLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
|
||||
* where to start searching for the next entry from. If NULL, it starts from
|
||||
* the head.
|
||||
*
|
||||
* This and other SYS_SLIST_*() macros are not thread safe.
|
||||
*
|
||||
* @param __sl A pointer on a sys_slist_t to iterate on
|
||||
* @param __sn A sys_snode_t pointer to peek each node of the list
|
||||
* it contains the starting node, or NULL to start from the head
|
||||
*/
|
||||
#define SYS_SLIST_ITERATE_FROM_NODE(__sl, __sn) \
|
||||
for (__sn = __sn ? sys_slist_peek_next_no_check(__sn) \
|
||||
: sys_slist_peek_head(__sl); \
|
||||
__sn; \
|
||||
__sn = sys_slist_peek_next(__sn))
|
||||
|
||||
/**
|
||||
* @brief Provide the primitive to safely iterate on a list
|
||||
* Note: __sn can be removed, it will not break the loop.
|
||||
*
|
||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||
*
|
||||
* SYS_SLIST_FOR_EACH_NODE_SAFE(l, n, s) {
|
||||
* <user code>
|
||||
* }
|
||||
*
|
||||
* This and other SYS_SLIST_*() macros are not thread safe.
|
||||
*
|
||||
* @param __sl A pointer on a sys_slist_t to iterate on
|
||||
* @param __sn A sys_snode_t pointer to peek each node of the list
|
||||
* @param __sns A sys_snode_t pointer for the loop to run safely
|
||||
*/
|
||||
#define SYS_SLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \
|
||||
for (__sn = sys_slist_peek_head(__sl), \
|
||||
__sns = sys_slist_peek_next(__sn); \
|
||||
__sn; __sn = __sns, \
|
||||
__sns = sys_slist_peek_next(__sn))
|
||||
|
||||
/*
|
||||
* @brief Provide the primitive to resolve the container of a list node
|
||||
* Note: it is safe to use with NULL pointer nodes
|
||||
*
|
||||
* @param __ln A pointer on a sys_node_t to get its container
|
||||
* @param __cn Container struct type pointer
|
||||
* @param __n The field name of sys_node_t within the container struct
|
||||
*/
|
||||
#define SYS_SLIST_CONTAINER(__ln, __cn, __n) \
|
||||
((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
|
||||
/*
|
||||
* @brief Provide the primitive to peek container of the list head
|
||||
*
|
||||
* @param __sl A pointer on a sys_slist_t to peek
|
||||
* @param __cn Container struct type pointer
|
||||
* @param __n The field name of sys_node_t within the container struct
|
||||
*/
|
||||
#define SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n) \
|
||||
SYS_SLIST_CONTAINER(sys_slist_peek_head(__sl), __cn, __n)
|
||||
|
||||
/*
|
||||
* @brief Provide the primitive to peek container of the list tail
|
||||
*
|
||||
* @param __sl A pointer on a sys_slist_t to peek
|
||||
* @param __cn Container struct type pointer
|
||||
* @param __n The field name of sys_node_t within the container struct
|
||||
*/
|
||||
#define SYS_SLIST_PEEK_TAIL_CONTAINER(__sl, __cn, __n) \
|
||||
SYS_SLIST_CONTAINER(sys_slist_peek_tail(__sl), __cn, __n)
|
||||
|
||||
/*
|
||||
* @brief Provide the primitive to peek the next container
|
||||
*
|
||||
* @param __cn Container struct type pointer
|
||||
* @param __n The field name of sys_node_t within the container struct
|
||||
*/
|
||||
|
||||
#define SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n) \
|
||||
((__cn) ? SYS_SLIST_CONTAINER(sys_slist_peek_next(&((__cn)->__n)), \
|
||||
__cn, __n) : NULL)
|
||||
|
||||
/**
|
||||
* @brief Provide the primitive to iterate on a list under a container
|
||||
@@ -64,17 +160,42 @@ typedef struct _slist sys_slist_t;
|
||||
* @param __cn A pointer to peek each entry of the list
|
||||
* @param __n The field name of sys_node_t within the container struct
|
||||
*/
|
||||
#define SYS_SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \
|
||||
STAILQ_FOREACH(__cn, __sl, omp_next)
|
||||
#define SYS_SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \
|
||||
for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); __cn; \
|
||||
__cn = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
|
||||
|
||||
/**
|
||||
* @brief Provide the primitive to safely iterate on a list under a container
|
||||
* Note: __cn can be detached, it will not break the loop.
|
||||
*
|
||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||
*
|
||||
* SYS_SLIST_FOR_EACH_NODE_SAFE(l, c, cn, n) {
|
||||
* <user code>
|
||||
* }
|
||||
*
|
||||
* @param __sl A pointer on a sys_slist_t to iterate on
|
||||
* @param __cn A pointer to peek each entry of the list
|
||||
* @param __cns A pointer for the loop to run safely
|
||||
* @param __n The field name of sys_node_t within the container struct
|
||||
*/
|
||||
#define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \
|
||||
for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \
|
||||
__cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n); __cn; \
|
||||
__cn = __cns, __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n))
|
||||
|
||||
/**
|
||||
* @brief Initialize a list
|
||||
*
|
||||
* @param list A pointer on the list to initialize
|
||||
*/
|
||||
void sys_slist_init(sys_slist_t *list);
|
||||
static inline void sys_slist_init(sys_slist_t *list)
|
||||
{
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
}
|
||||
|
||||
#define SYS_SLIST_STATIC_INIT(ptr_to_list) STAILQ_HEAD_INITIALIZER(ptr_to_list)
|
||||
#define SYS_SLIST_STATIC_INIT(ptr_to_list) {NULL, NULL}
|
||||
|
||||
/**
|
||||
* @brief Test if the given list is empty
|
||||
@@ -83,7 +204,10 @@ void sys_slist_init(sys_slist_t *list);
|
||||
*
|
||||
* @return a boolean, true if it's empty, false otherwise
|
||||
*/
|
||||
bool sys_slist_is_empty(sys_slist_t *list);
|
||||
static inline bool sys_slist_is_empty(sys_slist_t *list)
|
||||
{
|
||||
return (!list->head);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the first node from the list
|
||||
@@ -92,7 +216,10 @@ bool sys_slist_is_empty(sys_slist_t *list);
|
||||
*
|
||||
* @return A pointer on the first node of the list (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_head(sys_slist_t *list);
|
||||
static inline sys_snode_t *sys_slist_peek_head(sys_slist_t *list)
|
||||
{
|
||||
return list->head;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the last node from the list
|
||||
@@ -101,7 +228,10 @@ sys_snode_t *sys_slist_peek_head(sys_slist_t *list);
|
||||
*
|
||||
* @return A pointer on the last node of the list (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_tail(sys_slist_t *list);
|
||||
static inline sys_snode_t *sys_slist_peek_tail(sys_slist_t *list)
|
||||
{
|
||||
return list->tail;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the next node from current node, node is not NULL
|
||||
@@ -112,7 +242,10 @@ sys_snode_t *sys_slist_peek_tail(sys_slist_t *list);
|
||||
*
|
||||
* @return a pointer on the next node (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node);
|
||||
static inline sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node)
|
||||
{
|
||||
return node->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the next node from current node
|
||||
@@ -121,7 +254,10 @@ sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node);
|
||||
*
|
||||
* @return a pointer on the next node (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_next(sys_snode_t *node);
|
||||
static inline sys_snode_t *sys_slist_peek_next(sys_snode_t *node)
|
||||
{
|
||||
return node ? sys_slist_peek_next_no_check(node) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend a node to the given list
|
||||
@@ -131,7 +267,16 @@ sys_snode_t *sys_slist_peek_next(sys_snode_t *node);
|
||||
* @param list A pointer on the list to affect
|
||||
* @param node A pointer on the node to prepend
|
||||
*/
|
||||
void sys_slist_prepend(sys_slist_t *list, sys_snode_t *node);
|
||||
static inline void sys_slist_prepend(sys_slist_t *list,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
node->next = list->head;
|
||||
list->head = node;
|
||||
|
||||
if (!list->tail) {
|
||||
list->tail = list->head;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a node to the given list
|
||||
@@ -141,7 +286,19 @@ void sys_slist_prepend(sys_slist_t *list, sys_snode_t *node);
|
||||
* @param list A pointer on the list to affect
|
||||
* @param node A pointer on the node to append
|
||||
*/
|
||||
void sys_slist_append(sys_slist_t *list, sys_snode_t *node);
|
||||
static inline void sys_slist_append(sys_slist_t *list,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
node->next = NULL;
|
||||
|
||||
if (!list->tail) {
|
||||
list->tail = node;
|
||||
list->head = node;
|
||||
} else {
|
||||
list->tail->next = node;
|
||||
list->tail = node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a list to the given list
|
||||
@@ -154,7 +311,17 @@ void sys_slist_append(sys_slist_t *list, sys_snode_t *node);
|
||||
* @param head A pointer to the first element of the list to append
|
||||
* @param tail A pointer to the last element of the list to append
|
||||
*/
|
||||
void sys_slist_append_list(sys_slist_t *list, sys_slist_t *list_append);
|
||||
static inline void sys_slist_append_list(sys_slist_t *list,
|
||||
void *head, void *tail)
|
||||
{
|
||||
if (!list->tail) {
|
||||
list->head = (sys_snode_t *)head;
|
||||
list->tail = (sys_snode_t *)tail;
|
||||
} else {
|
||||
list->tail->next = (sys_snode_t *)head;
|
||||
list->tail = (sys_snode_t *)tail;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief merge two slists, appending the second one to the first
|
||||
@@ -165,7 +332,13 @@ void sys_slist_append_list(sys_slist_t *list, sys_slist_t *list_append);
|
||||
* @param list A pointer on the list to affect
|
||||
* @param list_to_append A pointer to the list to append.
|
||||
*/
|
||||
void sys_slist_merge_slist(sys_slist_t *list, sys_slist_t *list_to_append);
|
||||
static inline void sys_slist_merge_slist(sys_slist_t *list,
|
||||
sys_slist_t *list_to_append)
|
||||
{
|
||||
sys_slist_append_list(list, list_to_append->head,
|
||||
list_to_append->tail);
|
||||
sys_slist_init(list_to_append);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a node to the given list
|
||||
@@ -176,9 +349,19 @@ void sys_slist_merge_slist(sys_slist_t *list, sys_slist_t *list_to_append);
|
||||
* @param prev A pointer on the previous node
|
||||
* @param node A pointer on the node to insert
|
||||
*/
|
||||
void sys_slist_insert(sys_slist_t *list,
|
||||
sys_snode_t *prev,
|
||||
sys_snode_t *node);
|
||||
static inline void sys_slist_insert(sys_slist_t *list,
|
||||
sys_snode_t *prev,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
if (!prev) {
|
||||
sys_slist_prepend(list, node);
|
||||
} else if (!prev->next) {
|
||||
sys_slist_append(list, node);
|
||||
} else {
|
||||
node->next = prev->next;
|
||||
prev->next = node;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch and remove the first node of the given list
|
||||
@@ -190,7 +373,18 @@ void sys_slist_insert(sys_slist_t *list,
|
||||
*
|
||||
* @return A pointer to the first node of the list
|
||||
*/
|
||||
sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list);
|
||||
static inline sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list)
|
||||
{
|
||||
sys_snode_t *node = list->head;
|
||||
|
||||
list->head = node->next;
|
||||
if (list->tail == node) {
|
||||
list->tail = list->head;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch and remove the first node of the given list
|
||||
*
|
||||
@@ -200,7 +394,10 @@ sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list);
|
||||
*
|
||||
* @return A pointer to the first node of the list (or NULL if empty)
|
||||
*/
|
||||
sys_snode_t *sys_slist_get(sys_slist_t *list);
|
||||
static inline sys_snode_t *sys_slist_get(sys_slist_t *list)
|
||||
{
|
||||
return sys_slist_is_empty(list) ? NULL : sys_slist_get_not_empty(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a node
|
||||
@@ -212,9 +409,28 @@ sys_snode_t *sys_slist_get(sys_slist_t *list);
|
||||
* (can be NULL, which means the node is the list's head)
|
||||
* @param node A pointer on the node to remove
|
||||
*/
|
||||
void sys_slist_remove(sys_slist_t *list,
|
||||
sys_snode_t *prev_node,
|
||||
sys_snode_t *node);
|
||||
static inline void sys_slist_remove(sys_slist_t *list,
|
||||
sys_snode_t *prev_node,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
if (!prev_node) {
|
||||
list->head = node->next;
|
||||
|
||||
/* Was node also the tail? */
|
||||
if (list->tail == node) {
|
||||
list->tail = list->head;
|
||||
}
|
||||
} else {
|
||||
prev_node->next = node->next;
|
||||
|
||||
/* Was node the tail? */
|
||||
if (list->tail == node) {
|
||||
list->tail = prev_node;
|
||||
}
|
||||
}
|
||||
|
||||
node->next = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find and remove a node from a list
|
||||
@@ -226,12 +442,24 @@ void sys_slist_remove(sys_slist_t *list,
|
||||
*
|
||||
* @return true if node was removed
|
||||
*/
|
||||
bool sys_slist_find_and_remove(sys_slist_t *list,
|
||||
sys_snode_t *node);
|
||||
static inline bool sys_slist_find_and_remove(sys_slist_t *list,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
sys_snode_t *prev = NULL;
|
||||
sys_snode_t *test;
|
||||
|
||||
void net_buf_slist_put(sys_slist_t *list, struct os_mbuf *buf);
|
||||
SYS_SLIST_FOR_EACH_NODE(list, test) {
|
||||
if (test == node) {
|
||||
sys_slist_remove(list, prev, node);
|
||||
return true;
|
||||
}
|
||||
|
||||
prev = test;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct os_mbuf *net_buf_slist_get(sys_slist_t *list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -175,14 +175,14 @@ static void friend_clear(struct bt_mesh_friend *frnd)
|
||||
frnd->last = NULL;
|
||||
}
|
||||
|
||||
while (!sys_slist_is_empty(&frnd->queue)) {
|
||||
while (!net_buf_slist_is_empty(&frnd->queue)) {
|
||||
net_buf_unref(net_buf_slist_get(&frnd->queue));
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(frnd->seg); i++) {
|
||||
struct bt_mesh_friend_seg *seg = &frnd->seg[i];
|
||||
|
||||
while (!sys_slist_is_empty(&seg->queue)) {
|
||||
while (!net_buf_slist_is_empty(&seg->queue)) {
|
||||
net_buf_unref(net_buf_slist_get(&seg->queue));
|
||||
}
|
||||
}
|
||||
@@ -592,7 +592,7 @@ int bt_mesh_friend_poll(struct bt_mesh_net_rx *rx, struct os_mbuf *buf)
|
||||
|
||||
frnd->fsn = msg->fsn;
|
||||
|
||||
if (sys_slist_is_empty(&frnd->queue)) {
|
||||
if (net_buf_slist_is_empty(&frnd->queue)) {
|
||||
enqueue_update(frnd, 0);
|
||||
BT_DBG("Enqueued Friend Update to empty queue");
|
||||
}
|
||||
@@ -894,7 +894,7 @@ 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 os_mbuf *buf = (void *)sys_slist_peek_head(&seg->queue);
|
||||
struct os_mbuf *buf = (void *)net_buf_slist_peek_head(&seg->queue);
|
||||
|
||||
if (buf && BT_MESH_ADV(buf)->addr == src &&
|
||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
||||
@@ -948,14 +948,14 @@ static void enqueue_friend_pdu(struct bt_mesh_friend *frnd,
|
||||
* the SeqAuth information from the segments before merging.
|
||||
*/
|
||||
struct os_mbuf *m;
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
SYS_SLIST_FOR_EACH_CONTAINER(&seg->queue, mp,) {
|
||||
m = OS_MBUF_PKTHDR_TO_MBUF(mp);
|
||||
struct os_mbuf_pkthdr *pkthdr;
|
||||
NET_BUF_SLIST_FOR_EACH_NODE(&seg->queue, pkthdr) {
|
||||
m = OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
|
||||
FRIEND_ADV(m)->seq_auth = TRANS_SEQ_AUTH_NVAL;
|
||||
frnd->queue_size++;
|
||||
}
|
||||
|
||||
sys_slist_merge_slist(&frnd->queue, &seg->queue);
|
||||
net_buf_slist_merge_slist(&frnd->queue, &seg->queue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1058,7 +1058,7 @@ int bt_mesh_friend_init(void)
|
||||
|
||||
frnd->net_idx = BT_MESH_KEY_UNUSED;
|
||||
|
||||
sys_slist_init(&frnd->queue);
|
||||
net_buf_slist_init(&frnd->queue);
|
||||
|
||||
k_delayed_work_init(&frnd->timer, friend_timeout);
|
||||
k_delayed_work_add_arg(&frnd->timer, frnd);
|
||||
@@ -1066,7 +1066,7 @@ int bt_mesh_friend_init(void)
|
||||
k_delayed_work_add_arg(&frnd->clear.timer, frnd);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(frnd->seg); j++) {
|
||||
sys_slist_init(&frnd->seg[j].queue);
|
||||
net_buf_slist_init(&frnd->seg[j].queue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1076,19 +1076,19 @@ int bt_mesh_friend_init(void)
|
||||
static void friend_purge_old_ack(struct bt_mesh_friend *frnd, u64_t *seq_auth,
|
||||
u16_t src)
|
||||
{
|
||||
sys_snode_t *cur, *prev = NULL;
|
||||
struct os_mbuf *cur, *prev = NULL;
|
||||
|
||||
BT_DBG("SeqAuth %llx src 0x%04x", *seq_auth, src);
|
||||
|
||||
for (cur = sys_slist_peek_head(&frnd->queue);
|
||||
cur != NULL; prev = cur, cur = sys_slist_peek_next(cur)) {
|
||||
for (cur = net_buf_slist_peek_head(&frnd->queue);
|
||||
cur != NULL; prev = cur, cur = net_buf_slist_peek_next(cur)) {
|
||||
struct os_mbuf *buf = (void *)cur;
|
||||
|
||||
if (BT_MESH_ADV(buf)->addr == src &&
|
||||
FRIEND_ADV(buf)->seq_auth == *seq_auth) {
|
||||
BT_DBG("Removing old ack from Friend Queue");
|
||||
|
||||
sys_slist_remove(&frnd->queue, prev, cur);
|
||||
net_buf_slist_remove(&frnd->queue, prev, cur);
|
||||
frnd->queue_size--;
|
||||
|
||||
net_buf_unref(buf);
|
||||
@@ -1304,7 +1304,7 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src,
|
||||
struct bt_mesh_friend_seg *seg = &frnd->seg[j];
|
||||
struct os_mbuf *buf;
|
||||
|
||||
buf = (void *)sys_slist_peek_head(&seg->queue);
|
||||
buf = (void *)net_buf_slist_peek_head(&seg->queue);
|
||||
if (!buf) {
|
||||
continue;
|
||||
}
|
||||
@@ -1319,7 +1319,7 @@ void bt_mesh_friend_clear_incomplete(struct bt_mesh_subnet *sub, u16_t src,
|
||||
|
||||
BT_WARN("Clearing incomplete segments for 0x%04x", src);
|
||||
|
||||
while (!sys_slist_is_empty(&seg->queue)) {
|
||||
while (!net_buf_slist_is_empty(&seg->queue)) {
|
||||
net_buf_unref(net_buf_slist_get(&seg->queue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,3 +505,92 @@ bt_mesh_register_gatt(void)
|
||||
bt_mesh_proxy_svcs_register();
|
||||
#endif
|
||||
}
|
||||
|
||||
void net_buf_slist_init(struct net_buf_slist_t *list)
|
||||
{
|
||||
STAILQ_INIT(list);
|
||||
}
|
||||
|
||||
bool net_buf_slist_is_empty(struct net_buf_slist_t *list)
|
||||
{
|
||||
return STAILQ_EMPTY(list);
|
||||
}
|
||||
|
||||
struct os_mbuf *net_buf_slist_peek_head(struct net_buf_slist_t *list)
|
||||
{
|
||||
struct os_mbuf_pkthdr *pkthdr;
|
||||
|
||||
/* Get mbuf pointer from packet header pointer */
|
||||
pkthdr = STAILQ_FIRST(list);
|
||||
if (!pkthdr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
|
||||
}
|
||||
|
||||
struct os_mbuf *net_buf_slist_peek_next(struct os_mbuf *buf)
|
||||
{
|
||||
struct os_mbuf_pkthdr *pkthdr;
|
||||
|
||||
/* Get mbuf pointer from packet header pointer */
|
||||
pkthdr = OS_MBUF_PKTHDR(buf);
|
||||
pkthdr = STAILQ_NEXT(pkthdr, omp_next);
|
||||
if (!pkthdr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return OS_MBUF_PKTHDR_TO_MBUF(pkthdr);
|
||||
}
|
||||
|
||||
struct os_mbuf *net_buf_slist_get(struct net_buf_slist_t *list)
|
||||
{
|
||||
os_sr_t sr;
|
||||
struct os_mbuf *m;
|
||||
|
||||
m = net_buf_slist_peek_head(list);
|
||||
if (!m) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Remove from queue */
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
STAILQ_REMOVE_HEAD(list, omp_next);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
return m;
|
||||
}
|
||||
|
||||
void net_buf_slist_put(struct net_buf_slist_t *list, struct os_mbuf *buf)
|
||||
{
|
||||
struct os_mbuf_pkthdr *pkthdr;
|
||||
|
||||
pkthdr = OS_MBUF_PKTHDR(buf);
|
||||
STAILQ_INSERT_TAIL(list, pkthdr, omp_next);
|
||||
}
|
||||
|
||||
void net_buf_slist_remove(struct net_buf_slist_t *list, struct os_mbuf *prev,
|
||||
struct os_mbuf *cur)
|
||||
{
|
||||
struct os_mbuf_pkthdr *pkthdr, *cur_pkthdr;
|
||||
|
||||
cur_pkthdr = OS_MBUF_PKTHDR(cur);
|
||||
|
||||
STAILQ_FOREACH(pkthdr, list, omp_next) {
|
||||
if (cur_pkthdr == pkthdr) {
|
||||
STAILQ_REMOVE(list, cur_pkthdr, os_mbuf_pkthdr, omp_next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void net_buf_slist_merge_slist(struct net_buf_slist_t *list,
|
||||
struct net_buf_slist_t *list_to_append)
|
||||
{
|
||||
struct os_mbuf_pkthdr *pkthdr;
|
||||
|
||||
STAILQ_FOREACH(pkthdr, list_to_append, omp_next) {
|
||||
STAILQ_INSERT_TAIL(list, pkthdr, omp_next);
|
||||
}
|
||||
|
||||
STAILQ_INIT(list);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ static u16_t msg_cache_next;
|
||||
|
||||
/* Singleton network context (the implementation only supports one) */
|
||||
struct bt_mesh_net bt_mesh = {
|
||||
.local_queue = SYS_SLIST_STATIC_INIT(bt_mesh.local_queue),
|
||||
.local_queue = STAILQ_HEAD_INITIALIZER(bt_mesh.local_queue),
|
||||
.sub = {
|
||||
[0 ... (MYNEWT_VAL(BLE_MESH_SUBNET_COUNT) - 1)] = {
|
||||
.net_idx = BT_MESH_KEY_UNUSED,
|
||||
@@ -1351,4 +1351,5 @@ void bt_mesh_net_init(void)
|
||||
k_delayed_work_init(&bt_mesh.ivu_complete, ivu_complete);
|
||||
|
||||
k_work_init(&bt_mesh.local_work, bt_mesh_net_local);
|
||||
net_buf_slist_init(&bt_mesh.local_queue);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "mesh/mesh.h"
|
||||
#include "mesh/slist.h"
|
||||
#include "mesh/glue.h"
|
||||
|
||||
struct bt_mesh_app_key {
|
||||
u16_t net_idx;
|
||||
@@ -103,12 +103,12 @@ struct bt_mesh_friend {
|
||||
struct k_delayed_work timer;
|
||||
|
||||
struct bt_mesh_friend_seg {
|
||||
sys_slist_t queue;
|
||||
struct net_buf_slist_t queue;
|
||||
} seg[FRIEND_SEG_RX];
|
||||
|
||||
struct os_mbuf *last;
|
||||
|
||||
sys_slist_t queue;
|
||||
struct net_buf_slist_t queue;
|
||||
u32_t queue_size;
|
||||
|
||||
/* Friend Clear Procedure */
|
||||
@@ -201,7 +201,7 @@ struct bt_mesh_net {
|
||||
|
||||
/* Local network interface */
|
||||
struct os_callout local_work;
|
||||
sys_slist_t local_queue;
|
||||
struct net_buf_slist_t local_queue;
|
||||
|
||||
#if MYNEWT_VAL(BLE_MESH_FRIEND)
|
||||
/* Friend state, unique for each LPN that we're Friends for */
|
||||
|
||||
@@ -1,323 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "mesh/slist.h"
|
||||
#include "os/queue.h"
|
||||
#include "os/os.h"
|
||||
#include "os/os_mbuf.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize a list
|
||||
*
|
||||
* @param list A pointer on the list to initialize
|
||||
*/
|
||||
void sys_slist_init(sys_slist_t *list)
|
||||
{
|
||||
STAILQ_INIT(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test if the given list is empty
|
||||
*
|
||||
* @param list A pointer on the list to test
|
||||
*
|
||||
* @return a boolean, true if it's empty, false otherwise
|
||||
*/
|
||||
bool sys_slist_is_empty(sys_slist_t *list)
|
||||
{
|
||||
return STAILQ_EMPTY(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the first node from the list
|
||||
*
|
||||
* @param list A point on the list to peek the first node from
|
||||
*
|
||||
* @return A pointer on the first node of the list (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_head(sys_slist_t *list)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
struct os_mbuf *m;
|
||||
|
||||
mp = STAILQ_FIRST(list);
|
||||
|
||||
if (mp) {
|
||||
m = OS_MBUF_PKTHDR_TO_MBUF(mp);
|
||||
} else {
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the last node from the list
|
||||
*
|
||||
* @param list A point on the list to peek the last node from
|
||||
*
|
||||
* @return A pointer on the last node of the list (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_tail(sys_slist_t *list)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
struct os_mbuf *m;
|
||||
|
||||
mp = STAILQ_LAST(list, os_mbuf_pkthdr, omp_next);
|
||||
|
||||
if (mp) {
|
||||
m = OS_MBUF_PKTHDR_TO_MBUF(mp);
|
||||
} else {
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the next node from current node, node is not NULL
|
||||
*
|
||||
* Faster then sys_slist_peek_next() if node is known not to be NULL.
|
||||
*
|
||||
* @param node A pointer on the node where to peek the next node
|
||||
*
|
||||
* @return a pointer on the next node (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
struct os_mbuf *m;
|
||||
|
||||
mp = OS_MBUF_PKTHDR(node);
|
||||
if (!mp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp = STAILQ_NEXT(mp, omp_next);
|
||||
|
||||
if (mp) {
|
||||
m = OS_MBUF_PKTHDR_TO_MBUF(mp);
|
||||
} else {
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peek the next node from current node
|
||||
*
|
||||
* @param node A pointer on the node where to peek the next node
|
||||
*
|
||||
* @return a pointer on the next node (or NULL if none)
|
||||
*/
|
||||
sys_snode_t *sys_slist_peek_next(sys_snode_t *node)
|
||||
{
|
||||
return node ? sys_slist_peek_next_no_check(node) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepend a node to the given list
|
||||
*
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
* @param node A pointer on the node to prepend
|
||||
*/
|
||||
void sys_slist_prepend(sys_slist_t *list,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
|
||||
mp = OS_MBUF_PKTHDR(node);
|
||||
if (!mp) {
|
||||
return;
|
||||
}
|
||||
|
||||
STAILQ_INSERT_HEAD(list, mp, omp_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a node to the given list
|
||||
*
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
* @param node A pointer on the node to append
|
||||
*/
|
||||
void sys_slist_append(sys_slist_t *list,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
|
||||
mp = OS_MBUF_PKTHDR(node);
|
||||
if (!mp) {
|
||||
return;
|
||||
}
|
||||
|
||||
STAILQ_INSERT_TAIL(list, mp, omp_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Append a list to the given list
|
||||
*
|
||||
* Append a singly-linked, NULL-terminated list consisting of nodes containing
|
||||
* the pointer to the next node as the first element of a node, to @a list.
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
* @param head A pointer to the first element of the list to append
|
||||
* @param tail A pointer to the last element of the list to append
|
||||
*/
|
||||
void sys_slist_append_list(sys_slist_t *list,
|
||||
sys_slist_t *list_append)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
|
||||
STAILQ_FOREACH(mp, list_append, omp_next) {
|
||||
STAILQ_INSERT_TAIL(list, mp, omp_next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief merge two slists, appending the second one to the first
|
||||
*
|
||||
* When the operation is completed, the appending list is empty.
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
* @param list_to_append A pointer to the list to append.
|
||||
*/
|
||||
void sys_slist_merge_slist(sys_slist_t *list,
|
||||
sys_slist_t *list_to_append)
|
||||
{
|
||||
sys_slist_append_list(list, list_to_append);
|
||||
sys_slist_init(list_to_append);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Insert a node to the given list
|
||||
*
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
* @param prev A pointer on the previous node
|
||||
* @param node A pointer on the node to insert
|
||||
*/
|
||||
void sys_slist_insert(sys_slist_t *list,
|
||||
sys_snode_t *prev,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp, *mp_prev;
|
||||
|
||||
if (!prev) {
|
||||
sys_slist_prepend(list, node);
|
||||
} else {
|
||||
mp_prev = OS_MBUF_PKTHDR(prev);
|
||||
mp = OS_MBUF_PKTHDR(node);
|
||||
STAILQ_INSERT_AFTER(list, mp_prev, mp, omp_next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch and remove the first node of the given list
|
||||
*
|
||||
* List must be known to be non-empty.
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
*
|
||||
* @return A pointer to the first node of the list
|
||||
*/
|
||||
sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
struct os_mbuf *m;
|
||||
|
||||
mp = STAILQ_FIRST(list);
|
||||
m = OS_MBUF_PKTHDR_TO_MBUF(mp);
|
||||
|
||||
STAILQ_REMOVE_HEAD(list, omp_next);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fetch and remove the first node of the given list
|
||||
*
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
*
|
||||
* @return A pointer to the first node of the list (or NULL if empty)
|
||||
*/
|
||||
sys_snode_t *sys_slist_get(sys_slist_t *list)
|
||||
{
|
||||
return sys_slist_is_empty(list) ? NULL : sys_slist_get_not_empty(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a node
|
||||
*
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
* @param prev_node A pointer on the previous node
|
||||
* (can be NULL, which means the node is the list's head)
|
||||
* @param node A pointer on the node to remove
|
||||
*/
|
||||
void sys_slist_remove(sys_slist_t *list,
|
||||
sys_snode_t *prev_node,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
struct os_mbuf_pkthdr *mp;
|
||||
|
||||
mp = OS_MBUF_PKTHDR(node);
|
||||
STAILQ_REMOVE(list, mp, os_mbuf_pkthdr, omp_next);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find and remove a node from a list
|
||||
*
|
||||
* This and other sys_slist_*() functions are not thread safe.
|
||||
*
|
||||
* @param list A pointer on the list to affect
|
||||
* @param node A pointer on the node to remove from the list
|
||||
*
|
||||
* @return true if node was removed
|
||||
*/
|
||||
bool sys_slist_find_and_remove(sys_slist_t *list,
|
||||
sys_snode_t *node)
|
||||
{
|
||||
sys_snode_t *prev = NULL;
|
||||
sys_snode_t *test;
|
||||
|
||||
SYS_SLIST_FOR_EACH_NODE(list, test) {
|
||||
if (test == node) {
|
||||
sys_slist_remove(list, prev, node);
|
||||
return true;
|
||||
}
|
||||
|
||||
prev = test;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void net_buf_slist_put(sys_slist_t *list, struct os_mbuf *buf)
|
||||
{
|
||||
sys_slist_append(list, buf);
|
||||
}
|
||||
|
||||
struct os_mbuf *net_buf_slist_get(sys_slist_t *list)
|
||||
{
|
||||
return sys_slist_get(list);
|
||||
}
|
||||
Reference in New Issue
Block a user