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:
Martine Lenders 2018-06-28 23:10:48 +02:00
parent 16e1f972ab
commit 64fed621d2
5 changed files with 84 additions and 37 deletions

View File

@ -31,6 +31,7 @@
#include "byteorder.h"
#include "kernel_types.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/netif/hdr.h"
#include "net/ieee802154.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.
*/
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
}

View File

@ -320,9 +320,48 @@ void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
gnrc_pktbuf_release(pkt);
}
void gnrc_sixlowpan_frag_gc_rbuf(void)
void gnrc_sixlowpan_frag_rbuf_gc(void)
{
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);
}
}
/** @} */

View File

@ -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);
/* gets a free entry from interval buffer */
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 */
static bool _rbuf_update_ints(rbuf_t *entry, uint16_t offset, size_t frag_size);
/* 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) {
DEBUG("6lo rfrag: could not decode IPHC dispatch\n");
gnrc_pktbuf_release(entry->super.pkt);
_rbuf_rem(entry);
rbuf_rm(entry);
return;
}
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) {
DEBUG("6lo rfrag: fragment too big for resulting datagram, discarding datagram\n");
gnrc_pktbuf_release(entry->super.pkt);
_rbuf_rem(entry);
rbuf_rm(entry);
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)) {
DEBUG("6lo rfrag: overlapping intervals, discarding datagram\n");
gnrc_pktbuf_release(entry->super.pkt);
_rbuf_rem(entry);
rbuf_rm(entry);
/* "A fresh reassembly may be commenced with the most recently
* received link fragment"
@ -158,32 +156,7 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
frag_size - data_offset);
}
if (entry->super.current_size == entry->super.pkt->size) {
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);
}
gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(&entry->super, netif_hdr);
}
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;
}
static void _rbuf_rem(rbuf_t *entry)
void rbuf_rm(rbuf_t *entry)
{
while (entry->ints != NULL) {
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);
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);
DEBUG("6lo rfrag: reassembly buffer full, remove oldest entry\n");
gnrc_pktbuf_release(oldest->super.pkt);
_rbuf_rem(oldest);
rbuf_rm(oldest);
res = oldest;
}

View File

@ -89,6 +89,8 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *frag,
*/
void rbuf_gc(void);
void rbuf_rm(rbuf_t *rbuf);
#ifdef __cplusplus
}
#endif

View File

@ -377,7 +377,7 @@ static void *_event_loop(void *args)
break;
case GNRC_SIXLOWPAN_MSG_FRAG_GC_RBUF:
DEBUG("6lo: garbage collect reassembly buffer event received\n");
gnrc_sixlowpan_frag_gc_rbuf();
gnrc_sixlowpan_frag_rbuf_gc();
break;
#endif