gnrc_sixlowpan_frag: Expose functions to finish datagram
This will be used in the IPHC refactoring to control the reassembly buffer as a context. I also adapted the name of `gnrc_sixlowpan_frag_gc_rbuf()` to be in line with the rest of the newer functions.
This commit is contained in:
parent
16e1f972ab
commit
64fed621d2
@ -31,6 +31,7 @@
|
|||||||
#include "byteorder.h"
|
#include "byteorder.h"
|
||||||
#include "kernel_types.h"
|
#include "kernel_types.h"
|
||||||
#include "net/gnrc/pkt.h"
|
#include "net/gnrc/pkt.h"
|
||||||
|
#include "net/gnrc/netif/hdr.h"
|
||||||
#include "net/ieee802154.h"
|
#include "net/ieee802154.h"
|
||||||
#include "net/sixlowpan.h"
|
#include "net/sixlowpan.h"
|
||||||
|
|
||||||
@ -131,7 +132,39 @@ void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page);
|
|||||||
/**
|
/**
|
||||||
* @brief Garbage collect reassembly buffer.
|
* @brief Garbage collect reassembly buffer.
|
||||||
*/
|
*/
|
||||||
void gnrc_sixlowpan_frag_gc_rbuf(void);
|
void gnrc_sixlowpan_frag_rbuf_gc(void);
|
||||||
|
|
||||||
|
#if defined(MODULE_GNRC_SIXLOWPAN_FRAG) || defined(DOXYGEN)
|
||||||
|
/**
|
||||||
|
* @brief Removes an entry from the reassembly buffer
|
||||||
|
*
|
||||||
|
* @pre `rbuf != NULL`
|
||||||
|
*
|
||||||
|
* @param[in] rbuf A reassembly buffer entry. Must not be NULL.
|
||||||
|
*/
|
||||||
|
void gnrc_sixlowpan_frag_rbuf_remove(gnrc_sixlowpan_rbuf_t *rbuf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if a reassembly buffer entry is complete and dispatches it
|
||||||
|
* to the next layer if that is the case
|
||||||
|
*
|
||||||
|
* @pre `rbuf != NULL`
|
||||||
|
* @pre `netif != NULL`
|
||||||
|
*
|
||||||
|
* @param[in] rbuf A reassembly buffer entry. Must not be NULL.
|
||||||
|
* @param[in] netif Original @ref gnrc_netif_hdr_t of the last received frame.
|
||||||
|
* Used to construct the @ref gnrc_netif_hdr_t of the completed
|
||||||
|
* datagram. Must not be NULL.
|
||||||
|
*/
|
||||||
|
void gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(gnrc_sixlowpan_rbuf_t *rbuf,
|
||||||
|
gnrc_netif_hdr_t *netif);
|
||||||
|
#else
|
||||||
|
/* NOPs to be used with gnrc_sixlowpan_iphc if gnrc_sixlowpan_frag is not
|
||||||
|
* compiled in */
|
||||||
|
#define gnrc_sixlowpan_frag_rbuf_remove(rbuf) (void)(rbuf)
|
||||||
|
#define gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(rbuf, netif) \
|
||||||
|
(void)(rbuf); (void)(netif)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -320,9 +320,48 @@ void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
|
|||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gnrc_sixlowpan_frag_gc_rbuf(void)
|
void gnrc_sixlowpan_frag_rbuf_gc(void)
|
||||||
{
|
{
|
||||||
rbuf_gc();
|
rbuf_gc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gnrc_sixlowpan_frag_rbuf_remove(gnrc_sixlowpan_rbuf_t *rbuf)
|
||||||
|
{
|
||||||
|
assert(rbuf != NULL);
|
||||||
|
rbuf_rm((rbuf_t *)rbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(gnrc_sixlowpan_rbuf_t *rbuf,
|
||||||
|
gnrc_netif_hdr_t *netif_hdr)
|
||||||
|
{
|
||||||
|
assert(rbuf);
|
||||||
|
assert(netif_hdr);
|
||||||
|
if (rbuf->current_size == rbuf->pkt->size) {
|
||||||
|
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(rbuf->src,
|
||||||
|
rbuf->src_len,
|
||||||
|
rbuf->dst,
|
||||||
|
rbuf->dst_len);
|
||||||
|
|
||||||
|
if (netif == NULL) {
|
||||||
|
DEBUG("6lo rbuf: error allocating netif header\n");
|
||||||
|
gnrc_pktbuf_release(rbuf->pkt);
|
||||||
|
gnrc_sixlowpan_frag_rbuf_remove(rbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy the transmit information of the latest fragment into the newly
|
||||||
|
* created header to have some link_layer information. The link_layer
|
||||||
|
* info of the previous fragments is discarded.
|
||||||
|
*/
|
||||||
|
gnrc_netif_hdr_t *new_netif_hdr = netif->data;
|
||||||
|
new_netif_hdr->if_pid = netif_hdr->if_pid;
|
||||||
|
new_netif_hdr->flags = netif_hdr->flags;
|
||||||
|
new_netif_hdr->lqi = netif_hdr->lqi;
|
||||||
|
new_netif_hdr->rssi = netif_hdr->rssi;
|
||||||
|
LL_APPEND(rbuf->pkt, netif);
|
||||||
|
gnrc_sixlowpan_dispatch_recv(rbuf->pkt, NULL, 0);
|
||||||
|
gnrc_sixlowpan_frag_rbuf_remove(rbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@ -58,8 +58,6 @@ static msg_t _gc_timer_msg = { .type = GNRC_SIXLOWPAN_MSG_FRAG_GC_RBUF };
|
|||||||
static inline bool _rbuf_int_overlap_partially(rbuf_int_t *i, uint16_t start, uint16_t end);
|
static inline bool _rbuf_int_overlap_partially(rbuf_int_t *i, uint16_t start, uint16_t end);
|
||||||
/* gets a free entry from interval buffer */
|
/* gets a free entry from interval buffer */
|
||||||
static rbuf_int_t *_rbuf_int_get_free(void);
|
static rbuf_int_t *_rbuf_int_get_free(void);
|
||||||
/* remove entry from reassembly buffer */
|
|
||||||
static void _rbuf_rem(rbuf_t *entry);
|
|
||||||
/* update interval buffer of entry */
|
/* update interval buffer of entry */
|
||||||
static bool _rbuf_update_ints(rbuf_t *entry, uint16_t offset, size_t frag_size);
|
static bool _rbuf_update_ints(rbuf_t *entry, uint16_t offset, size_t frag_size);
|
||||||
/* gets an entry identified by its tupel */
|
/* gets an entry identified by its tupel */
|
||||||
@ -108,7 +106,7 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
if (iphc_len == 0) {
|
if (iphc_len == 0) {
|
||||||
DEBUG("6lo rfrag: could not decode IPHC dispatch\n");
|
DEBUG("6lo rfrag: could not decode IPHC dispatch\n");
|
||||||
gnrc_pktbuf_release(entry->super.pkt);
|
gnrc_pktbuf_release(entry->super.pkt);
|
||||||
_rbuf_rem(entry);
|
rbuf_rm(entry);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data += iphc_len; /* take remaining data as data */
|
data += iphc_len; /* take remaining data as data */
|
||||||
@ -127,7 +125,7 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
if ((offset + frag_size) > entry->super.pkt->size) {
|
if ((offset + frag_size) > entry->super.pkt->size) {
|
||||||
DEBUG("6lo rfrag: fragment too big for resulting datagram, discarding datagram\n");
|
DEBUG("6lo rfrag: fragment too big for resulting datagram, discarding datagram\n");
|
||||||
gnrc_pktbuf_release(entry->super.pkt);
|
gnrc_pktbuf_release(entry->super.pkt);
|
||||||
_rbuf_rem(entry);
|
rbuf_rm(entry);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +136,7 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
if (_rbuf_int_overlap_partially(ptr, offset, offset + frag_size - 1)) {
|
if (_rbuf_int_overlap_partially(ptr, offset, offset + frag_size - 1)) {
|
||||||
DEBUG("6lo rfrag: overlapping intervals, discarding datagram\n");
|
DEBUG("6lo rfrag: overlapping intervals, discarding datagram\n");
|
||||||
gnrc_pktbuf_release(entry->super.pkt);
|
gnrc_pktbuf_release(entry->super.pkt);
|
||||||
_rbuf_rem(entry);
|
rbuf_rm(entry);
|
||||||
|
|
||||||
/* "A fresh reassembly may be commenced with the most recently
|
/* "A fresh reassembly may be commenced with the most recently
|
||||||
* received link fragment"
|
* received link fragment"
|
||||||
@ -158,32 +156,7 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
frag_size - data_offset);
|
frag_size - data_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry->super.current_size == entry->super.pkt->size) {
|
gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(&entry->super, netif_hdr);
|
||||||
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(entry->super.src,
|
|
||||||
entry->super.src_len,
|
|
||||||
entry->super.dst,
|
|
||||||
entry->super.dst_len);
|
|
||||||
|
|
||||||
if (netif == NULL) {
|
|
||||||
DEBUG("6lo rbuf: error allocating netif header\n");
|
|
||||||
gnrc_pktbuf_release(entry->super.pkt);
|
|
||||||
_rbuf_rem(entry);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy the transmit information of the latest fragment into the newly
|
|
||||||
* created header to have some link_layer information. The link_layer
|
|
||||||
* info of the previous fragments is discarded.
|
|
||||||
*/
|
|
||||||
gnrc_netif_hdr_t *new_netif_hdr = netif->data;
|
|
||||||
new_netif_hdr->if_pid = netif_hdr->if_pid;
|
|
||||||
new_netif_hdr->flags = netif_hdr->flags;
|
|
||||||
new_netif_hdr->lqi = netif_hdr->lqi;
|
|
||||||
new_netif_hdr->rssi = netif_hdr->rssi;
|
|
||||||
LL_APPEND(entry->super.pkt, netif);
|
|
||||||
gnrc_sixlowpan_dispatch_recv(entry->super.pkt, NULL, 0);
|
|
||||||
_rbuf_rem(entry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool _rbuf_int_overlap_partially(rbuf_int_t *i, uint16_t start, uint16_t end)
|
static inline bool _rbuf_int_overlap_partially(rbuf_int_t *i, uint16_t start, uint16_t end)
|
||||||
@ -204,7 +177,7 @@ static rbuf_int_t *_rbuf_int_get_free(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _rbuf_rem(rbuf_t *entry)
|
void rbuf_rm(rbuf_t *entry)
|
||||||
{
|
{
|
||||||
while (entry->ints != NULL) {
|
while (entry->ints != NULL) {
|
||||||
rbuf_int_t *next = entry->ints->next;
|
rbuf_int_t *next = entry->ints->next;
|
||||||
@ -267,7 +240,7 @@ void rbuf_gc(void)
|
|||||||
(unsigned)rbuf[i].super.pkt->size, rbuf[i].super.tag);
|
(unsigned)rbuf[i].super.pkt->size, rbuf[i].super.tag);
|
||||||
|
|
||||||
gnrc_pktbuf_release(rbuf[i].super.pkt);
|
gnrc_pktbuf_release(rbuf[i].super.pkt);
|
||||||
_rbuf_rem(&(rbuf[i]));
|
rbuf_rm(&(rbuf[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,7 +297,7 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
|
|||||||
assert(oldest->super.pkt != NULL);
|
assert(oldest->super.pkt != NULL);
|
||||||
DEBUG("6lo rfrag: reassembly buffer full, remove oldest entry\n");
|
DEBUG("6lo rfrag: reassembly buffer full, remove oldest entry\n");
|
||||||
gnrc_pktbuf_release(oldest->super.pkt);
|
gnrc_pktbuf_release(oldest->super.pkt);
|
||||||
_rbuf_rem(oldest);
|
rbuf_rm(oldest);
|
||||||
res = oldest;
|
res = oldest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -89,6 +89,8 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *frag,
|
|||||||
*/
|
*/
|
||||||
void rbuf_gc(void);
|
void rbuf_gc(void);
|
||||||
|
|
||||||
|
void rbuf_rm(rbuf_t *rbuf);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -377,7 +377,7 @@ static void *_event_loop(void *args)
|
|||||||
break;
|
break;
|
||||||
case GNRC_SIXLOWPAN_MSG_FRAG_GC_RBUF:
|
case GNRC_SIXLOWPAN_MSG_FRAG_GC_RBUF:
|
||||||
DEBUG("6lo: garbage collect reassembly buffer event received\n");
|
DEBUG("6lo: garbage collect reassembly buffer event received\n");
|
||||||
gnrc_sixlowpan_frag_gc_rbuf();
|
gnrc_sixlowpan_frag_rbuf_gc();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user