|
|
|
@ -16,10 +16,7 @@
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
|
|
#include "rbuf.h"
|
|
|
|
|
#include "net/ng_netapi.h"
|
|
|
|
|
#include "net/ng_netif.h"
|
|
|
|
|
#include "net/ng_netif/hdr.h"
|
|
|
|
|
#include "net/ng_pktbuf.h"
|
|
|
|
|
#include "net/ng_netbase.h"
|
|
|
|
|
#include "net/ng_ipv6/netif.h"
|
|
|
|
|
#include "net/ng_sixlowpan.h"
|
|
|
|
|
#include "net/ng_sixlowpan/frag.h"
|
|
|
|
@ -67,7 +64,6 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
|
|
|
|
rbuf_t *entry;
|
|
|
|
|
rbuf_int_t *ptr;
|
|
|
|
|
uint8_t *data = ((uint8_t *)frag) + sizeof(ng_sixlowpan_frag_t);
|
|
|
|
|
uint16_t dg_frag_size = frag_size; /* may differ on first fragment */
|
|
|
|
|
|
|
|
|
|
_rbuf_gc();
|
|
|
|
|
entry = _rbuf_get(ng_netif_hdr_get_src_addr(netif_hdr), netif_hdr->src_l2addr_len,
|
|
|
|
@ -83,10 +79,12 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
|
|
|
|
ptr = entry->ints;
|
|
|
|
|
|
|
|
|
|
/* dispatches in the first fragment are ignored */
|
|
|
|
|
if (offset != 0) {
|
|
|
|
|
switch (((uint8_t *)(entry->pkt->data))[0]) {
|
|
|
|
|
if (offset == 0) {
|
|
|
|
|
switch (data[0]) {
|
|
|
|
|
case NG_SIXLOWPAN_UNCOMPRESSED:
|
|
|
|
|
offset++;
|
|
|
|
|
data++; /* skip 6LoWPAN dispatch */
|
|
|
|
|
frag_size--;
|
|
|
|
|
entry->compressed = 0; /* datagram is not compressed */
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
@ -94,19 +92,9 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data++; /* also don't take offset field */
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
switch (data[0]) {
|
|
|
|
|
case NG_SIXLOWPAN_UNCOMPRESSED:
|
|
|
|
|
dg_frag_size--;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data++; /* FRAGN header is one byte longer (offset) */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((offset + frag_size) > entry->pkt->size) {
|
|
|
|
@ -117,7 +105,7 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (ptr != NULL) {
|
|
|
|
|
if (_rbuf_int_in(ptr, offset, offset + dg_frag_size - 1)) {
|
|
|
|
|
if (_rbuf_int_in(ptr, offset, offset + frag_size - 1)) {
|
|
|
|
|
DEBUG("6lo rfrag: overlapping or same intervals, discarding datagram\n");
|
|
|
|
|
ng_pktbuf_release(entry->pkt);
|
|
|
|
|
_rbuf_rem(entry);
|
|
|
|
@ -127,31 +115,13 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
|
|
|
|
ptr = ptr->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_rbuf_update_ints(entry, offset, dg_frag_size)) {
|
|
|
|
|
if (dg_frag_size < frag_size) {
|
|
|
|
|
/* some dispatches do not count to datagram size and we need
|
|
|
|
|
* more space because of that */
|
|
|
|
|
if (ng_pktbuf_realloc_data(entry->pkt, entry->pkt->size +
|
|
|
|
|
(frag_size - dg_frag_size)) < 0) {
|
|
|
|
|
DEBUG("6lo rbuf: could not reallocate packet data.\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* move already inserted fragments (frag_size - dg_frag_size) to the right */
|
|
|
|
|
if (entry->cur_size > 0) {
|
|
|
|
|
for (int i = entry->pkt->size - (frag_size - dg_frag_size); i > 0; i--) {
|
|
|
|
|
uint8_t *d = ((uint8_t *)(entry->pkt->data)) + i;
|
|
|
|
|
*d = *(d - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_rbuf_update_ints(entry, offset, frag_size)) {
|
|
|
|
|
DEBUG("6lo rbuf: add fragment data\n");
|
|
|
|
|
entry->cur_size += (uint16_t)dg_frag_size;
|
|
|
|
|
entry->cur_size += (uint16_t)frag_size;
|
|
|
|
|
memcpy(((uint8_t *)entry->pkt->data) + offset, data, frag_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (entry->cur_size == entry->datagram_size) {
|
|
|
|
|
if (entry->cur_size == entry->pkt->size) {
|
|
|
|
|
kernel_pid_t iface = netif_hdr->if_pid;
|
|
|
|
|
ng_pktsnip_t *netif = ng_netif_hdr_build(entry->src, entry->src_len,
|
|
|
|
|
entry->dst, entry->dst_len);
|
|
|
|
@ -159,6 +129,7 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
|
|
|
|
if (netif == NULL) {
|
|
|
|
|
DEBUG("6lo rbuf: error allocating netif header\n");
|
|
|
|
|
ng_pktbuf_release(entry->pkt);
|
|
|
|
|
_rbuf_rem(entry);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -166,8 +137,18 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
|
|
|
|
netif_hdr->if_pid = iface;
|
|
|
|
|
LL_APPEND(entry->pkt, netif);
|
|
|
|
|
|
|
|
|
|
DEBUG("6lo rbuf: datagram complete, send to self\n");
|
|
|
|
|
ng_netapi_receive(thread_getpid(), entry->pkt);
|
|
|
|
|
if (entry->compressed) {
|
|
|
|
|
DEBUG("6lo rbuf: datagram complete, send to self for decompression\n");
|
|
|
|
|
ng_netapi_receive(thread_getpid(), entry->pkt);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
DEBUG("6lo rbuf: datagram complete, send to IPv6 listeners\n");
|
|
|
|
|
if (!ng_netapi_dispatch_receive(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL,
|
|
|
|
|
entry->pkt)) {
|
|
|
|
|
DEBUG("6lo rbuf: No receivers for this packet found\n");
|
|
|
|
|
ng_pktbuf_release(entry->pkt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_rbuf_rem(entry);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -222,9 +203,9 @@ static bool _rbuf_update_ints(rbuf_t *entry, uint16_t offset, size_t frag_size)
|
|
|
|
|
DEBUG("6lo rfrag: add interval (%" PRIu16 ", %" PRIu16 ") to entry (%s, ",
|
|
|
|
|
new->start, new->end, ng_netif_addr_to_str(l2addr_str,
|
|
|
|
|
sizeof(l2addr_str), entry->src, entry->src_len));
|
|
|
|
|
DEBUG("%s, %u, %" PRIu16 ")\n", ng_netif_addr_to_str(l2addr_str,
|
|
|
|
|
sizeof(l2addr_str), entry->dst, entry->dst_len), entry->datagram_size,
|
|
|
|
|
entry->tag);
|
|
|
|
|
DEBUG("%s, %u, %u)\n", ng_netif_addr_to_str(l2addr_str,
|
|
|
|
|
sizeof(l2addr_str), entry->dst, entry->dst_len),
|
|
|
|
|
(unsigned)entry->pkt->size, entry->tag);
|
|
|
|
|
|
|
|
|
|
LL_PREPEND(entry->ints, new);
|
|
|
|
|
|
|
|
|
@ -247,10 +228,10 @@ static void _rbuf_gc(void)
|
|
|
|
|
((now.seconds - rbuf[i].arrival) > RBUF_TIMEOUT)) {
|
|
|
|
|
DEBUG("6lo rfrag: entry (%s, ", ng_netif_addr_to_str(l2addr_str,
|
|
|
|
|
sizeof(l2addr_str), rbuf[i].src, rbuf[i].src_len));
|
|
|
|
|
DEBUG("%s, %u, %" PRIu16 ") timed out\n",
|
|
|
|
|
DEBUG("%s, %u, %u) timed out\n",
|
|
|
|
|
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), rbuf[i].dst,
|
|
|
|
|
rbuf[i].dst_len),
|
|
|
|
|
rbuf[i].datagram_size, rbuf[i].tag);
|
|
|
|
|
(unsigned)rbuf[i].pkt->size, rbuf[i].tag);
|
|
|
|
|
|
|
|
|
|
ng_pktbuf_release(rbuf[i].pkt);
|
|
|
|
|
_rbuf_rem(&(rbuf[i]));
|
|
|
|
@ -278,7 +259,7 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < RBUF_SIZE; i++) {
|
|
|
|
|
/* check first if entry already available */
|
|
|
|
|
if ((rbuf[i].pkt != NULL) && (rbuf[i].datagram_size == size) &&
|
|
|
|
|
if ((rbuf[i].pkt != NULL) && (rbuf[i].pkt->size == size) &&
|
|
|
|
|
(rbuf[i].tag == tag) && (rbuf[i].src_len == src_len) &&
|
|
|
|
|
(rbuf[i].dst_len == dst_len) &&
|
|
|
|
|
(memcmp(rbuf[i].src, src, src_len) == 0) &&
|
|
|
|
@ -286,10 +267,10 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
|
|
|
|
|
DEBUG("6lo rfrag: entry %p (%s, ", (void *)(&rbuf[i]),
|
|
|
|
|
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str),
|
|
|
|
|
rbuf[i].src, rbuf[i].src_len));
|
|
|
|
|
DEBUG("%s, %u, %" PRIu16 ") found\n",
|
|
|
|
|
DEBUG("%s, %u, %u) found\n",
|
|
|
|
|
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str),
|
|
|
|
|
rbuf[i].dst, rbuf[i].dst_len),
|
|
|
|
|
rbuf[i].datagram_size, rbuf[i].tag);
|
|
|
|
|
(unsigned)rbuf[i].pkt->size, rbuf[i].tag);
|
|
|
|
|
rbuf[i].arrival = now.seconds;
|
|
|
|
|
return &(rbuf[i]);
|
|
|
|
|
}
|
|
|
|
@ -315,15 +296,16 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
|
|
|
|
|
res->src_len = src_len;
|
|
|
|
|
res->dst_len = dst_len;
|
|
|
|
|
res->tag = tag;
|
|
|
|
|
res->datagram_size = size;
|
|
|
|
|
res->cur_size = 0;
|
|
|
|
|
res->compressed = 1;
|
|
|
|
|
|
|
|
|
|
DEBUG("6lo rfrag: entry %p (%s, ", (void *)res,
|
|
|
|
|
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), res->src,
|
|
|
|
|
res->src_len));
|
|
|
|
|
DEBUG("%s, %u, %" PRIu16 ") created\n",
|
|
|
|
|
DEBUG("%s, %u, %u) created\n",
|
|
|
|
|
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), res->dst,
|
|
|
|
|
res->dst_len), res->datagram_size, res->tag);
|
|
|
|
|
res->dst_len), (unsigned)res->pkt->size,
|
|
|
|
|
res->tag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|