Skip to content

Commit

Permalink
gnrc_sixlowpan_iphc: refactor according to RIOT-OS#8511
Browse files Browse the repository at this point in the history
  • Loading branch information
miri64 committed Mar 9, 2018
1 parent 1fdbce5 commit f864668
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 67 deletions.
40 changes: 17 additions & 23 deletions sys/include/net/gnrc/sixlowpan/iphc.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,36 +30,30 @@ extern "C" {
#endif

/**
* @brief Decompresses a received 6LoWPAN IPHC frame.
* @brief Decompresses a received 6Lo IPHC frame and delegates the
* uncompressed packet to the next 6Lo sub-layer.
*
* @pre (dec_hdr != NULL) && (*dec_hdr != NULL) && ((*dec_hdr)->size >= sizeof(gnrc_ipv6_hdr_t))
* @pre (pkt != NULL)
*
* @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
*
* @return length of the HC dispatches + inline values on success.
* @return 0 on error.
* @param[in] pkt A received 6Lo IPHC frame.
* @param[in] context Context for the packet. May be `NULL`. If not `NULL` it
* *must* point to an instance of a reassembly buffer.
* @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_decode(gnrc_pktsnip_t *pkt, void *context,
unsigned page);

/**
* @brief Compresses a 6LoWPAN for IPHC.
*
* @param[in,out] pkt A 6LoWPAN frame with an uncompressed IPv6 header to
* send. Will be translated to an 6LoWPAN IPHC frame.
* @brief Compresses a 6LoWPAN for IPHC and delegates the compressed packet
* to the next 6Lo sub-layer.
*
* @return true, on success
* @return false, on error.
* @param[in] pkt A 6LoWPAN frame with an uncompressed IPv6 header to
* send.
* @param[in] context Context for the packet. May be `NULL`.
* @param[in] page Current 6Lo dispatch parsing page.
*/
bool gnrc_sixlowpan_iphc_encode(gnrc_pktsnip_t *pkt);
void gnrc_sixlowpan_iphc_encode(gnrc_pktsnip_t *pkt, void *context,
unsigned page);

#ifdef __cplusplus
}
Expand Down
31 changes: 3 additions & 28 deletions sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ static void _receive(gnrc_pktsnip_t *pkt)

pkt = gnrc_pktbuf_remove_snip(pkt, sixlowpan);
payload->type = GNRC_NETTYPE_IPV6;
gnrc_sixlowpan_dispatch_recv(pkt, NULL, 0);
}
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
else if (sixlowpan_frag_is((sixlowpan_frag_t *)dispatch)) {
Expand All @@ -170,32 +171,7 @@ 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;
gnrc_sixlowpan_iphc_decode(pkt, NULL, 0);
}
#endif
else {
Expand All @@ -204,7 +180,6 @@ static void _receive(gnrc_pktsnip_t *pkt)
gnrc_pktbuf_release(pkt);
return;
}
gnrc_sixlowpan_dispatch_recv(pkt, NULL, 0);
}

static inline bool _add_uncompr_disp(gnrc_pktsnip_t *pkt)
Expand Down Expand Up @@ -266,7 +241,7 @@ static void _send(gnrc_pktsnip_t *pkt)

#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
if (iface->flags & GNRC_NETIF_FLAGS_6LO_HC) {
if (!gnrc_sixlowpan_iphc_encode(pkt2)) {
if (!gnrc_sixlowpan_iphc_encode(pkt2, NULL, 0)) {
DEBUG("6lo: error on IPHC encoding\n");
gnrc_pktbuf_release(pkt2);
return;
Expand Down
56 changes: 40 additions & 16 deletions sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,42 +481,65 @@ size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,

default:
DEBUG("6lo iphc: unspecified or reserved M, DAC, DAM combination\n");
return 0;
gnrc_pktsnip_release(ipv6);
gnrc_pktsnip_release(pkt);
return;

}

/* set IPv6 header payload length field to the length of whatever is left
* after removing the 6LoWPAN header */
if (datagram_size == 0) {
/* if no reassembly buffer entry is provided */
if (layer_context == NULL) {
/* set IPv6 header payload length field to the length of whatever is left
* after removing the 6LoWPAN header */
ipv6_hdr->len = byteorder_htons((uint16_t)(pkt->size - payload_offset));
}
else {
ipv6_hdr->len = byteorder_htons((uint16_t)(datagram_size - sizeof(ipv6_hdr_t)));
rbuf_t *rbuf_entry = layer_context;
ipv6_hdr->len = byteorder_htons((uint16_t)(rbuf_entry->pkt->size -
sizeof(ipv6_hdr_t)));
}

#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
if (iphc_hdr[IPHC1_IDX] & SIXLOWPAN_IPHC1_NH) {
switch (iphc_hdr[payload_offset] & NHC_ID_MASK) {
case NHC_UDP_ID:
payload_offset = iphc_nhc_udp_decode(pkt, dec_hdr, datagram_size,
payload_offset + offset);

if (payload_offset != 0) {
payload_offset -= offset;
}
// TODO: transform datagram_size to rbuf, add of UDP snip?
payload_offset = iphc_nhc_udp_decode(pkt, &ipv6, datagram_size,
payload_offset);

*nh_len += sizeof(udp_hdr_t);
hdr_len += sizeof(udp_hdr_t);
break;

default:
break;
}
}
#else
(void)nh_len;
#endif

return payload_offset;
if (layered_context == NULL) {
sixlowpan = gnrc_pktbuf_mark(pkt, payload_offset, GNRC_NETTYPE_SIXLOWPAN);
if (sixlowpan == NULL) {
DEBUG("6lo iphc: error marking IPHC dispatch\n");
gnrc_pktbuf_release(ipv6);
gnrc_pktbuf_release(pkt);
return;
}
/* Remove IPHC dispatches */
/* Insert decoded header instead */
pkt = gnrc_pktbuf_replace_snip(pkt, sixlowpan, ipv6);
pkt->type = GNRC_NETTYPE_UNDEF;
}
else {
rbuf_t *rbuf_entry = layered_context;
uint8_t *data_out = entry->pkt->data;
uint8_t *data_in = pkt->data;

/* was fragmented => copy rest of fragment into reassem bly buffer */
memcpy(data_out + sizeof(ipv6_hdr_t) + hdr_len, data_in + payload_offset,
pkt->size - payload_offset);
pkt = rbuf_entry->pkt;
}
gnrc_sixlowpan_dispatch_recv(pkt, layer_context, page);
}

#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
Expand Down Expand Up @@ -581,7 +604,8 @@ static inline size_t iphc_nhc_udp_encode(gnrc_pktsnip_t *udp, ipv6_hdr_t *ipv6_h
}
#endif

bool gnrc_sixlowpan_iphc_encode(gnrc_pktsnip_t *pkt)
void gnrc_sixlowpan_iphc_encode(gnrc_pktsnip_t *pkt, void *context,
unsigned page)
{
gnrc_netif_hdr_t *netif_hdr = pkt->data;
ipv6_hdr_t *ipv6_hdr = pkt->next->data;
Expand Down

0 comments on commit f864668

Please sign in to comment.