PF_IEEE802154: Add a maximum backlog option. This will prevent overrun of the RX frame queue if many frames are received from the radio, but no application is receiving the queued data.

This commit is contained in:
Gregory Nutt
2017-08-21 07:52:43 -06:00
parent 0eac90f775
commit 6b7a26c95c
5 changed files with 93 additions and 5 deletions
+15 -1
View File
@@ -39,10 +39,24 @@ config NET_IEEE802154_NCONNS
config NET_IEEE802154_NCONTAINERS
int "Number of pre-allocated frame containers"
default 20
default 8
---help---
This specifies the total number of preallocated frame containers.
One must be allocated with each incoming frame.
config NET_IEEE802154_BACKLOG
int "Maximum frame backlog"
default 8
range 0 255
---help---
As frames are received, then are help in an RX queue. They remain
in the RX queue until application logic reads the queue frames. To
prevent overrun, the maximum backlog may be set to a nonzero value.
What the backlog of queue frames reaches that count, the olds frame
will be freed, preventing overrun at the cost of losing the oldest
frames.
NOTE: The special value of zero will disable all backlog checkes.
endif # NET_IEEE802154
endmenu # IEEE 802.15.4 Socket Support
+4 -1
View File
@@ -118,8 +118,11 @@ struct ieee802154_conn_s
struct ieee802154_saddr_s laddr; /* Locally bound / source address */
struct ieee802154_saddr_s raddr; /* Connected remote address */
uint8_t crefs; /* Reference counts on this instance */
#if CONFIG_NET_IEEE802154_BACKLOG > 0
uint8_t backlog; /* Number of frames in RX queue */
#endif
/* List of incoming packets */
/* Queue of incoming packets */
FAR struct ieee802154_container_s *rxhead;
FAR struct ieee802154_container_s *rxtail;
+3 -3
View File
@@ -38,6 +38,7 @@
#include <nuttx/config.h>
#include <semaphore.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
@@ -133,6 +134,7 @@ FAR struct ieee802154_conn_s *ieee802154_conn_alloc(void)
{
/* Enqueue the connection into the active list */
memset(conn, 0, sizeof(struct ieee802154_conn_s));
dq_addlast(&conn->node, &g_active_ieee802154_connections);
}
@@ -167,9 +169,7 @@ void ieee802154_conn_free(FAR struct ieee802154_conn_s *conn)
/* Check if there any any frames attached to the container */
for (container = conn->rxhead;
container != NULL;
container = container->ic_flink)
for (container = conn->rxhead; container != NULL; container = next)
{
/* Remove the frame from the list */
+64
View File
@@ -55,6 +55,36 @@
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: ieee802154_count_frames
*
* Description:
* Return the number of frames in the RX queue.
*
* Parameters:
* conn - The socket connection structure.
*
* Return:
* The number of frames in the queue.
*
****************************************************************************/
#ifdef CONFIG_DEBUG_ASSERTIONS
int ieee802154_count_frames(FAR struct ieee802154_conn_s *conn)
{
FAR struct ieee802154_container_s *container;
int count;
for (count = 0, container = conn->rxhead;
container != NULL;
count++, container = container->ic_flink)
{
}
return count;
}
#endif
/****************************************************************************
* Name: ieee802154_queue_frame
*
@@ -119,6 +149,40 @@ int ieee802154_queue_frame(FAR struct ieee802154_conn_s *conn,
conn->rxtail->ic_flink = container;
}
#if CONFIG_NET_IEEE802154_BACKLOG > 0
/* Increment the count of frames in the queue. If the count exceeds the
* maximum backlog value, then delete the oldest frame from the head of
* the RX queue.
*/
conn->backlog++;
DEBUGASSERT((int)conn->backlog == ieee802154_count_frames(conn));
if (conn->backlog > CONFIG_NET_IEEE802154_BACKLOG)
{
/* Remove the container from the tail RX input queue. */
container = conn->rxhead;
DEBUGASSERT(container != NULL);
conn->rxhead = container->ic_flink;
container->ic_flink = NULL;
/* Did the RX queue become empty? */
if (conn->rxhead == NULL)
{
conn->rxtail = NULL;
}
DEBUGASSERT(container != NULL && container->ic_iob != NULL);
/* Free both the IOB and the container */
iob_free(container->ic_iob);
ieee802154_container_free(container);
}
#endif
return OK;
}
+7
View File
@@ -129,6 +129,13 @@ static ssize_t ieee802154_recvfrom_rxqueue(FAR struct radio_driver_s *radio,
conn->rxtail = NULL;
}
#if CONFIG_NET_IEEE802154_BACKLOG > 0
/* Decrement the count of frames in the queue. */
DEBUGASSERT(conn->backlog > 0);
conn->backlog--;
#endif
/* Extract the IOB containing the frame from the container */
iob = container->ic_iob;