Skip to content

Commit

Permalink
gnrc_sixlowpan_iphc: refactor reception for RIOT-OS#8511
Browse files Browse the repository at this point in the history
This refactors reception/decoding part of `gnrc_sixlowpan_iphc` to the
more layered approach modeled in RIOT-OS#8511. Since the reception part is
already complicated enough I decided to divide send and receive up into
separate changes.
  • Loading branch information
miri64 committed Jul 25, 2018
1 parent 7fef5e0 commit 69d9ecc
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 140 deletions.
24 changes: 9 additions & 15 deletions sys/include/net/gnrc/sixlowpan/iphc.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,17 @@ extern "C" {
/**
* @brief Decompresses a received 6LoWPAN IPHC frame.
*
* @pre (dec_hdr != NULL) && (*dec_hdr != NULL) && ((*dec_hdr)->size >= sizeof(gnrc_ipv6_hdr_t))
*
* @param[out] dec_hdr A pre-allocated IPv6 header. Will not be inserted into
* @p pkt. May change due to next headers being added in NHC.
* @param[in] pkt A received 6LoWPAN IPHC frame. IPHC dispatch will not
* be marked.
* @param[in] datagram_size Size of the full uncompressed IPv6 datagram. May be 0, if @p pkt
* contains the full (unfragmented) IPv6 datagram.
* @param[in] offset Offset of the IPHC dispatch in 6LoWPaN frame.
* @param[in, out] nh_len Pointer to next header length
* @pre (pkt != NULL)
*
* @return length of the HC dispatches + inline values on success.
* @return 0 on error.
* @param[in] pkt A received 6LoWPAN IPHC frame. The first snip is to
* be expected to start with the IPHC dispatch.
* @param[in,out] ctx Context for the packet. May be NULL. If not NULL it
* is expected to be of type
* @ref gnrc_sixlowpan_rbuf_t. This function might
* change the content of that.
* @param[in] page Current 6Lo dispatch parsing page.
*/
size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,
size_t datagram_size, size_t offset,
size_t *nh_len);
void gnrc_sixlowpan_iphc_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page);

/**
* @brief Compresses a 6LoWPAN for IPHC.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,6 @@ void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
}

rbuf_add(hdr, pkt, offset, page);

gnrc_pktbuf_release(pkt);
}

void gnrc_sixlowpan_frag_rbuf_gc(void)
Expand Down
49 changes: 22 additions & 27 deletions sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
size_t offset, unsigned page)
{
rbuf_t *entry;
/* cppcheck-suppress variableScope
* (reason: cppcheck is clearly wrong here) */
unsigned int data_offset = 0;
sixlowpan_frag_t *frag = pkt->data;
rbuf_int_t *ptr;
uint8_t *data = ((uint8_t *)pkt->data) + sizeof(sixlowpan_frag_t);
Expand All @@ -96,27 +93,6 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
if (data[0] == SIXLOWPAN_UNCOMP) {
frag_size--;
}
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
else if (sixlowpan_iphc_is(data)) {
size_t iphc_len, nh_len = 0;
iphc_len = gnrc_sixlowpan_iphc_decode(&entry->super.pkt, pkt,
entry->super.pkt->size,
sizeof(sixlowpan_frag_t),
&nh_len);
if (iphc_len == 0) {
DEBUG("6lo rfrag: could not decode IPHC dispatch\n");
gnrc_pktbuf_release(entry->super.pkt);
rbuf_rm(entry);
return;
}
data += iphc_len; /* take remaining data as data */
frag_size -= iphc_len; /* and reduce frag size by IPHC dispatch length */
/* but add IPv6 header + next header lengths */
frag_size += sizeof(ipv6_hdr_t) + nh_len;
/* start copying after IPv6 header and next headers */
data_offset += sizeof(ipv6_hdr_t) + nh_len;
}
#endif
}
else {
frag_size = pkt->size - sizeof(sixlowpan_frag_n_t);
Expand Down Expand Up @@ -153,11 +129,30 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
if (_rbuf_update_ints(entry, offset, frag_size)) {
DEBUG("6lo rbuf: add fragment data\n");
entry->super.current_size += (uint16_t)frag_size;
memcpy(((uint8_t *)entry->super.pkt->data) + offset + data_offset, data,
frag_size - data_offset);
if (offset == 0) {
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
if (sixlowpan_iphc_is(data)) {
gnrc_pktsnip_t *frag_hdr = gnrc_pktbuf_mark(pkt,
sizeof(sixlowpan_frag_t), GNRC_NETTYPE_SIXLOWPAN);
if (frag_hdr == NULL) {
gnrc_pktbuf_release(entry->super.pkt);
rbuf_rm(entry);
return;
}
gnrc_sixlowpan_iphc_recv(pkt, &entry->super, 0);
return;
}
else
#endif
if (data[0] == SIXLOWPAN_UNCOMP) {
data++;
}
}
memcpy(((uint8_t *)entry->super.pkt->data) + offset, data,
frag_size);
}

gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(&entry->super, netif_hdr);
gnrc_pktbuf_release(pkt);
}

static inline bool _rbuf_int_overlap_partially(rbuf_int_t *i, uint16_t start, uint16_t end)
Expand Down
29 changes: 3 additions & 26 deletions sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,32 +211,9 @@ static void _receive(gnrc_pktsnip_t *pkt)
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
else if (sixlowpan_iphc_is(dispatch)) {
size_t dispatch_size, nh_len;
gnrc_pktsnip_t *sixlowpan;
gnrc_pktsnip_t *dec_hdr = gnrc_pktbuf_add(NULL, NULL, sizeof(ipv6_hdr_t),
GNRC_NETTYPE_IPV6);
if ((dec_hdr == NULL) ||
(dispatch_size = gnrc_sixlowpan_iphc_decode(&dec_hdr, pkt, 0, 0,
&nh_len)) == 0) {
DEBUG("6lo: error on IPHC decoding\n");
if (dec_hdr != NULL) {
gnrc_pktbuf_release(dec_hdr);
}
gnrc_pktbuf_release(pkt);
return;
}
sixlowpan = gnrc_pktbuf_mark(pkt, dispatch_size, GNRC_NETTYPE_SIXLOWPAN);
if (sixlowpan == NULL) {
DEBUG("6lo: error on marking IPHC dispatch\n");
gnrc_pktbuf_release(dec_hdr);
gnrc_pktbuf_release(pkt);
return;
}

/* Remove IPHC dispatches */
/* Insert decoded header instead */
pkt = gnrc_pktbuf_replace_snip(pkt, sixlowpan, dec_hdr);
payload->type = GNRC_NETTYPE_UNDEF;
DEBUG("6lo: received 6LoWPAN IPHC comressed datagram\n");
gnrc_sixlowpan_iphc_recv(pkt, NULL, 0);
return;
}
#endif
else {
Expand Down
Loading

0 comments on commit 69d9ecc

Please sign in to comment.