mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
gnrc_sixlowpan_frag_rb: add handling for RFRAG packets
This commit is contained in:
parent
d393008b9f
commit
ec436e99d9
@ -29,6 +29,7 @@
|
|||||||
#include "net/gnrc/sixlowpan/frag/minfwd.h"
|
#include "net/gnrc/sixlowpan/frag/minfwd.h"
|
||||||
#include "net/gnrc/sixlowpan/frag/vrb.h"
|
#include "net/gnrc/sixlowpan/frag/vrb.h"
|
||||||
#include "net/sixlowpan.h"
|
#include "net/sixlowpan.h"
|
||||||
|
#include "net/sixlowpan/sfr.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "xtimer.h"
|
#include "xtimer.h"
|
||||||
#include "utlist.h"
|
#include "utlist.h"
|
||||||
@ -205,9 +206,18 @@ static gnrc_sixlowpan_frag_rb_t *_rbuf_get_by_tag(const gnrc_netif_hdr_t *netif_
|
|||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static bool _valid_offset(gnrc_pktsnip_t *pkt, size_t offset)
|
static bool _valid_offset(gnrc_pktsnip_t *pkt, size_t offset)
|
||||||
{
|
{
|
||||||
return (sixlowpan_frag_1_is(pkt->data) && (offset == 0)) ||
|
return (
|
||||||
(sixlowpan_frag_n_is(pkt->data) &&
|
IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG) &&
|
||||||
(offset == sixlowpan_frag_offset(pkt->data)));
|
((sixlowpan_frag_1_is(pkt->data) && (offset == 0)) ||
|
||||||
|
(sixlowpan_frag_n_is(pkt->data) &&
|
||||||
|
(offset == sixlowpan_frag_offset(pkt->data))))
|
||||||
|
) || (
|
||||||
|
IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR) &&
|
||||||
|
/* offset == 0 is an abort condition that should not be handed to the
|
||||||
|
* reassembly buffer */
|
||||||
|
sixlowpan_sfr_rfrag_is(pkt->data) &&
|
||||||
|
(sixlowpan_sfr_rfrag_get_offset(pkt->data) != 0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -239,6 +249,25 @@ static size_t _6lo_frag_size(gnrc_pktsnip_t *pkt, size_t offset, uint8_t *data)
|
|||||||
return frag_size;
|
return frag_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t _6lo_sfr_datagram_size(gnrc_pktsnip_t *pkt, size_t offset)
|
||||||
|
{
|
||||||
|
/* offset doubles as datagram size in RFRAG header when sequence number is 0
|
||||||
|
* see https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-08#section-5.1 */
|
||||||
|
return (offset == 0) ? sixlowpan_sfr_rfrag_get_offset(pkt->data) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t *_6lo_sfr_payload(gnrc_pktsnip_t *pkt)
|
||||||
|
{
|
||||||
|
return ((uint8_t *)pkt->data) + sizeof(sixlowpan_sfr_rfrag_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t _6lo_sfr_frag_size(gnrc_pktsnip_t *pkt)
|
||||||
|
{
|
||||||
|
/* TODO: if necessary check MAC layer here,
|
||||||
|
* see https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-08#section-5.1 */
|
||||||
|
return sixlowpan_sfr_rfrag_get_frag_size(pkt->data);
|
||||||
|
}
|
||||||
|
|
||||||
static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
||||||
size_t offset, unsigned page)
|
size_t offset, unsigned page)
|
||||||
{
|
{
|
||||||
@ -249,18 +278,37 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
} entry;
|
} entry;
|
||||||
const uint8_t *src = gnrc_netif_hdr_get_src_addr(netif_hdr);
|
const uint8_t *src = gnrc_netif_hdr_get_src_addr(netif_hdr);
|
||||||
const uint8_t *dst = gnrc_netif_hdr_get_dst_addr(netif_hdr);
|
const uint8_t *dst = gnrc_netif_hdr_get_dst_addr(netif_hdr);
|
||||||
uint8_t *data;
|
uint8_t *data = NULL;
|
||||||
size_t frag_size;
|
size_t frag_size = 0; /* assign 0, otherwise cppcheck complains ;-) */
|
||||||
int res;
|
int res;
|
||||||
uint16_t datagram_size;
|
uint16_t datagram_size;
|
||||||
uint16_t datagram_tag;
|
uint16_t datagram_tag;
|
||||||
|
|
||||||
/* check if provided offset is the same as in fragment */
|
/* check if provided offset is the same as in fragment */
|
||||||
assert(_valid_offset(pkt, offset));
|
assert(_valid_offset(pkt, offset));
|
||||||
data = _6lo_frag_payload(pkt);
|
if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG) && sixlowpan_frag_is(pkt->data)) {
|
||||||
frag_size = _6lo_frag_size(pkt, offset, data);
|
data = _6lo_frag_payload(pkt);
|
||||||
datagram_size = sixlowpan_frag_datagram_size(pkt->data);
|
frag_size = _6lo_frag_size(pkt, offset, data);
|
||||||
datagram_tag = sixlowpan_frag_datagram_tag(pkt->data);
|
datagram_size = sixlowpan_frag_datagram_size(pkt->data);
|
||||||
|
datagram_tag = sixlowpan_frag_datagram_tag(pkt->data);
|
||||||
|
}
|
||||||
|
else if (IS_USED(MODULE_GNRC_SIXLOWPAN_FRAG_SFR) &&
|
||||||
|
sixlowpan_sfr_rfrag_is(pkt->data)) {
|
||||||
|
sixlowpan_sfr_rfrag_t *rfrag = pkt->data;;
|
||||||
|
|
||||||
|
data = _6lo_sfr_payload(pkt);
|
||||||
|
frag_size = _6lo_sfr_frag_size(pkt);
|
||||||
|
/* offset doubles as datagram size in RFRAG header when sequence number
|
||||||
|
* is 0 */
|
||||||
|
datagram_size = _6lo_sfr_datagram_size(pkt, offset);
|
||||||
|
datagram_tag = rfrag->base.tag;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* either one of the if branches above was taken */
|
||||||
|
assert(data != NULL);
|
||||||
|
gnrc_pktbuf_release(pkt);
|
||||||
|
return RBUF_ADD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
gnrc_sixlowpan_frag_rb_gc();
|
gnrc_sixlowpan_frag_rb_gc();
|
||||||
/* only check VRB for subsequent frags, first frags create and not get VRB
|
/* only check VRB for subsequent frags, first frags create and not get VRB
|
||||||
|
Loading…
Reference in New Issue
Block a user