From d0448df3b8e2f315c90aeb33379804915f877023 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 14 Sep 2015 15:55:26 +0200 Subject: [PATCH 1/4] added support for multiple reassemblies --- core/net/ipv6/sicslowpan.c | 600 +++++++++++++++++++++++-------------- 1 file changed, 371 insertions(+), 229 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index 3cec1a534..f6af5d46f 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -79,15 +79,9 @@ uint8_t p; #include #define PRINTFI(...) PRINTF(__VA_ARGS__) #define PRINTFO(...) PRINTF(__VA_ARGS__) -#define PRINTPACKETBUF() PRINTF("packetbuf buffer: "); for(p = 0; p < packetbuf_datalen(); p++){PRINTF("%.2X", *(packetbuf_ptr + p));} PRINTF("\n") -#define PRINTUIPBUF() PRINTF("UIP buffer: "); for(p = 0; p < uip_len; p++){PRINTF("%.2X", uip_buf[p]);}PRINTF("\n") -#define PRINTSICSLOWPANBUF() PRINTF("SICSLOWPAN buffer: "); for(p = 0; p < sicslowpan_len; p++){PRINTF("%.2X", sicslowpan_buf[p]);}PRINTF("\n") #else #define PRINTFI(...) #define PRINTFO(...) -#define PRINTPACKETBUF() -#define PRINTUIPBUF() -#define PRINTSICSLOWPANBUF() #endif /* DEBUG == 1*/ #if UIP_LOGGING @@ -145,8 +139,10 @@ void uip_log(char *msg); /** \name Pointers in the sicslowpan and uip buffer * @{ */ -#define SICSLOWPAN_IP_BUF ((struct uip_ip_hdr *)&sicslowpan_buf[UIP_LLH_LEN]) -#define SICSLOWPAN_UDP_BUF ((struct uip_udp_hdr *)&sicslowpan_buf[UIP_LLIPH_LEN]) + +/* NOTE: In the multiple-reassembly context there is only room for the header / first fragment */ +#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf) +#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN]) #define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) #define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN]) @@ -165,9 +161,8 @@ void uip_log(char *msg); #endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */ -/** \brief Some MAC layers need a minimum payload, which is - configurable through the SICSLOWPAN_CONF_MIN_MAC_PAYLOAD - option. */ +/** \brief Some MAC layers need a minimum payload, which is configurable + through the SICSLOWPAN_CONF_COMPRESSION_THRESHOLD option. */ #ifdef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD #define COMPRESSION_THRESHOLD SICSLOWPAN_CONF_COMPRESSION_THRESHOLD #else @@ -216,50 +211,232 @@ static uint8_t uncomp_hdr_len; static int last_tx_status; /** @} */ -#if SICSLOWPAN_CONF_FRAG -/** \name Fragmentation related variables - * @{ - */ +static uint16_t my_tag; -static uint16_t sicslowpan_len; +static int last_rssi; -/** - * The buffer used for the 6lowpan reassembly. - * This buffer contains only the IPv6 packet (no MAC header, 6lowpan, etc). - * It has a fix size as we do not use dynamic memory allocation. - */ -static uip_buf_t sicslowpan_aligned_buf; -#define sicslowpan_buf (sicslowpan_aligned_buf.u8) +/* ----------------------------------------------------------------- */ +/* Support for reassembling multiple packets */ +/* ----------------------------------------------------------------- */ +/* The fragmentation buffer are also possible to use for other + * temporary memory allocation. In that case the number of available + * buffers will be lower for a short time. + **/ /** The total length of the IPv6 packet in the sicslowpan_buf. */ -/** - * length of the ip packet already sent / received. - * It includes IP and transport headers. - */ -static uint16_t processed_ip_in_len; +/* This needs to be defined in NBR / Nodes depending on available RAM */ +/* and expected reassembly requirements */ +#ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS +#define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS +#else +#define SICSLOWPAN_FRAGMENT_BUFFERS 12 +#endif -/** Datagram tag to be put in the fragments I send. */ -static uint16_t my_tag; +/* REASS_CONTEXTS corresponds to the number of simultaneous + * reassemblies that can be made. NOTE: the first buffer for each + * reassembly is stored in the context since it can be larger than the + * rest of the fragments due to header compression. + **/ +#ifdef SICSLOWPAN_CONF_REASS_CONTEXTS +#define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS +#else +#define SICSLOWPAN_REASS_CONTEXTS 2 +#endif -/** When reassembling, the tag in the fragments being merged. */ -static uint16_t reass_tag; +/* The size of each fragment (IP payload) for the 6lowpan fragmentation */ +#ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE +#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE +#else +#define SICSLOWPAN_FRAGMENT_SIZE 110 +#endif -/** When reassembling, the source address of the fragments being merged */ -linkaddr_t frag_sender; +/* Assuming that the worst growth for uncompression is 38 bytes */ +#define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38) -/** Reassembly %process %timer. */ -static struct timer reass_timer; +/* all information needed for reassembly */ +struct sicslowpan_frag_info { + /** When reassembling, the source address of the fragments being merged */ + linkaddr_t sender; + /** The destination address of the fragments being merged */ + linkaddr_t receiver; + /** When reassembling, the tag in the fragments being merged. */ + uint16_t tag; + /** Total length of the fragmented packet */ + uint16_t len; + /** Current length of reassembled fragments */ + uint16_t reassembled_len; + /** Reassembly %process %timer. */ + struct timer reass_timer; -/** @} */ -#else /* SICSLOWPAN_CONF_FRAG */ -/** The buffer used for the 6lowpan processing is uip_buf. - We do not use any additional buffer.*/ -#define sicslowpan_buf uip_buf -#define sicslowpan_len uip_len -#endif /* SICSLOWPAN_CONF_FRAG */ + /** Fragment size of first fragment */ + uint16_t first_frag_len; + /** First fragment - needs a larger buffer since the size is uncompressed size + and we need to know total size to know when we have received last fragment. */ + uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE]; +}; -static int last_rssi; +static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS]; + +struct sicslowpan_frag_buf { + /* the index of the frag_info */ + uint8_t index; + /* Fragment offset */ + uint8_t offset; + /* Length of this fragment (if zero this buffer is not allocated) */ + uint8_t len; + uint8_t data[SICSLOWPAN_FRAGMENT_SIZE]; +}; + +static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS]; + +/*---------------------------------------------------------------------------*/ +static int +clear_fragments(uint8_t frag_info_index) +{ + int i, clear_count; + clear_count = 0; + frag_info[frag_info_index].len = 0; + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) { + /* deallocate the buffer */ + frag_buf[i].len = 0; + clear_count++; + } + } + return clear_count; +} +/*---------------------------------------------------------------------------*/ +static int +timeout_fragments(int not_context) +{ + int i; + int count = 0; + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + if(frag_info[i].len > 0 && i != not_context && + timer_expired(&frag_info[i].reass_timer)) { + /* This context can be freed */ + count += clear_fragments(i); + } + } + return count; +} +/*---------------------------------------------------------------------------*/ +static int +store_fragment(uint8_t index, uint8_t offset) +{ + int i; + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + if(frag_buf[i].len == 0) { + /* copy over the data from packetbuf into the fragment buffer and store offset and len */ + frag_buf[i].offset = offset; /* frag offset */ + frag_buf[i].len = packetbuf_datalen() - packetbuf_hdr_len; + frag_buf[i].index = index; + memcpy(frag_buf[i].data, packetbuf_ptr + packetbuf_hdr_len, + packetbuf_datalen() - packetbuf_hdr_len); + + PRINTF("Fragsize: %d\n", frag_buf[i].len); + /* return the length of the stored fragment */ + return frag_buf[i].len; + } + } + /* failed */ + return -1; +} +/*---------------------------------------------------------------------------*/ +/* add a new fragment to the buffer */ +static int8_t +add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset) +{ + int i; + int len; + int8_t found = -1; + + if(offset == 0) { + /* This is a first fragment - check if we can add this */ + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + /* clear all fragment info with expired timer to free all fragment buffers */ + if(frag_info[i].len > 0 && timer_expired(&frag_info[i].reass_timer)) { + clear_fragments(i); + } + + /* We use len as indication on used or not used */ + if(found < 0 && frag_info[i].len == 0) { + /* We remember the first free fragment info but must continue + the loop to free any other expired fragment buffers. */ + found = i; + } + } + + if(found < 0) { + PRINTF("*** Failed to store new fragment session - tag: %d\n", tag); + return -1; + } + + /* Found a free fragment info to store data in */ + frag_info[found].len = frag_size; + frag_info[found].tag = tag; + linkaddr_copy(&frag_info[found].sender, + packetbuf_addr(PACKETBUF_ADDR_SENDER)); + timer_set(&frag_info[found].reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16); + /* first fragment can not be stored immediately but is moved into + the buffer while uncompressing */ + return found; + } + + /* This is a N-fragment - should find the info */ + for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) { + if(frag_info[i].tag == tag && frag_info[i].len > 0 && + linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) { + /* Tag and Sender match - this must be the correct info to store in */ + found = i; + break; + } + } + + if(found < 0) { + /* no entry found for storing the new fragment */ + PRINTF("*** Failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset); + return -1; + } + + /* i is the index of the reassembly context */ + len = store_fragment(i, offset); + if(len < 0 && timeout_fragments(i) > 0) { + len = store_fragment(i, offset); + } + if(len > 0) { + frag_info[i].reassembled_len += len; + return i; + } else { + /* should we also clear all fragments since we failed to store this fragment? */ + PRINTF("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag); + return -1; + } +} +/*---------------------------------------------------------------------------*/ +/* Copy all the fragments that are associated with a specific context into uip */ +static void +copy_frags2uip(int context) +{ + int i; + + /* Copy from the fragment context info buffer first */ + memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag, + frag_info[context].first_frag_len); + for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) { + /* And also copy all matching fragments */ + if(frag_buf[i].len > 0 && frag_buf[i].index == context) { + memcpy((uint8_t *)UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3), + (uint8_t *)frag_buf[i].data, frag_buf[i].len); + } + } + /* deallocate all the fragments for this context */ + clear_fragments(context); +} + + +/* -------------------------------------------------------------------------- */ /*-------------------------------------------------------------------------*/ /* Rime Sniffer support for one single listener to enable powertrace of IP */ @@ -327,7 +504,7 @@ static struct sicslowpan_addr_context *context; /** pointer to the byte where to write next inline field. */ static uint8_t *hc06_ptr; -/* Uncompression of linklocal */ +/* ession of linklocal */ /* 0 -> 16 bytes from packet */ /* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */ /* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */ @@ -357,7 +534,7 @@ const uint8_t llprefix[] = {0xfe, 0x80}; static const uint8_t ttl_values[] = {0, 1, 64, 255}; /*--------------------------------------------------------------------*/ -/** \name HC06 related functions +/** \name IPHC related functions * @{ */ /*--------------------------------------------------------------------*/ /** \brief find the context corresponding to prefix ipaddr */ @@ -463,8 +640,8 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], * uip_buf buffer. * * - * HC-06 (draft-ietf-6lowpan-hc, version 6)\n - * http://tools.ietf.org/html/draft-ietf-6lowpan-hc-06 + * IPHC (RFC 6282)\n + * http://tools.ietf.org/html/ * * \note We do not support ISA100_UDP header compression * @@ -490,7 +667,7 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], * dest */ static void -compress_hdr_hc06(linkaddr_t *link_destaddr) +compress_hdr_iphc(linkaddr_t *link_destaddr) { uint8_t tmp, iphc0, iphc1; #if DEBUG @@ -541,7 +718,8 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) * depends on the presence of version and flow label */ - /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ + /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ + tmp = (UIP_IP_BUF->vtc << 4) | (UIP_IP_BUF->tcflow >> 4); tmp = ((tmp & 0x03) << 6) | (tmp >> 2); @@ -585,11 +763,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) iphc0 |= SICSLOWPAN_IPHC_NH_C; } #endif /*UIP_CONF_UDP*/ -#ifdef SICSLOWPAN_NH_COMPRESSOR - if(SICSLOWPAN_NH_COMPRESSOR.is_compressable(UIP_IP_BUF->proto)) { - iphc0 |= SICSLOWPAN_IPHC_NH_C; - } -#endif + if ((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { *hc06_ptr = UIP_IP_BUF->proto; hc06_ptr += 1; @@ -769,11 +943,11 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) /*--------------------------------------------------------------------*/ /** - * \brief Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put + * \brief Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put * them in sicslowpan_buf * * This function is called by the input function when the dispatch is - * HC06. + * IPHC. * We %process the packet in the packetbuf buffer, uncompress the header * fields, and copy the result in the sicslowpan buffer. * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len @@ -784,7 +958,7 @@ compress_hdr_hc06(linkaddr_t *link_destaddr) * fragment. */ static void -uncompress_hdr_hc06(uint16_t ip_len) +uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len) { uint8_t tmp, iphc0, iphc1; /* at least two byte will be used for the encoding */ @@ -804,22 +978,22 @@ uncompress_hdr_hc06(uint16_t ip_len) /* Flow label are carried inline */ if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { /* Traffic class is carried inline */ - memcpy(&SICSLOWPAN_IP_BUF->tcflow, hc06_ptr + 1, 3); + memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow, hc06_ptr + 1, 3); tmp = *hc06_ptr; hc06_ptr += 4; - /* hc06 format of tc is ECN | DSCP , original is DSCP | ECN */ + /* IPHC format of tc is ECN | DSCP , original is DSCP | ECN */ /* set version, pick highest DSCP bits and set in vtc */ - SICSLOWPAN_IP_BUF->vtc = 0x60 | ((tmp >> 2) & 0x0f); + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f); /* ECN rolled down two steps + lowest DSCP bits at top two bits */ - SICSLOWPAN_IP_BUF->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) | - (SICSLOWPAN_IP_BUF->tcflow & 0x0f); + SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) | + (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f); } else { /* Traffic class is compressed (set version and no TC)*/ - SICSLOWPAN_IP_BUF->vtc = 0x60; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; /* highest flow label bits + ECN bits */ - SICSLOWPAN_IP_BUF->tcflow = (*hc06_ptr & 0x0F) | - ((*hc06_ptr >> 2) & 0x30); - memcpy(&SICSLOWPAN_IP_BUF->flow, hc06_ptr + 1, 2); + SICSLOWPAN_IP_BUF(buf)->tcflow = (*hc06_ptr & 0x0F) | + ((*hc06_ptr >> 2) & 0x30); + memcpy(&SICSLOWPAN_IP_BUF(buf)->flow, hc06_ptr + 1, 2); hc06_ptr += 3; } } else { @@ -827,31 +1001,31 @@ uncompress_hdr_hc06(uint16_t ip_len) /* Version and flow label are compressed */ if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) { /* Traffic class is inline */ - SICSLOWPAN_IP_BUF->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f); - SICSLOWPAN_IP_BUF->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30); - SICSLOWPAN_IP_BUF->flow = 0; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*hc06_ptr >> 2) & 0x0f); + SICSLOWPAN_IP_BUF(buf)->tcflow = ((*hc06_ptr << 6) & 0xC0) | ((*hc06_ptr >> 2) & 0x30); + SICSLOWPAN_IP_BUF(buf)->flow = 0; hc06_ptr += 1; } else { /* Traffic class is compressed */ - SICSLOWPAN_IP_BUF->vtc = 0x60; - SICSLOWPAN_IP_BUF->tcflow = 0; - SICSLOWPAN_IP_BUF->flow = 0; + SICSLOWPAN_IP_BUF(buf)->vtc = 0x60; + SICSLOWPAN_IP_BUF(buf)->tcflow = 0; + SICSLOWPAN_IP_BUF(buf)->flow = 0; } } /* Next Header */ if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) { /* Next header is carried inline */ - SICSLOWPAN_IP_BUF->proto = *hc06_ptr; - PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF->proto); + SICSLOWPAN_IP_BUF(buf)->proto = *hc06_ptr; + PRINTF("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto); hc06_ptr += 1; } /* Hop limit */ if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) { - SICSLOWPAN_IP_BUF->ttl = ttl_values[iphc0 & 0x03]; + SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03]; } else { - SICSLOWPAN_IP_BUF->ttl = *hc06_ptr; + SICSLOWPAN_IP_BUF(buf)->ttl = *hc06_ptr; hc06_ptr += 1; } @@ -872,12 +1046,12 @@ uncompress_hdr_hc06(uint16_t ip_len) } } /* if tmp == 0 we do not have a context and therefore no prefix */ - uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, tmp != 0 ? context->prefix : NULL, unc_ctxconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); } else { /* no compression and link local */ - uncompress_addr(&SICSLOWPAN_IP_BUF->srcipaddr, llprefix, unc_llconf[tmp], + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix, unc_llconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); } @@ -902,7 +1076,7 @@ uncompress_hdr_hc06(uint16_t ip_len) hc06_ptr++; } - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, prefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix, unc_mxconf[tmp], NULL); } } else { @@ -917,12 +1091,12 @@ uncompress_hdr_hc06(uint16_t ip_len) PRINTF("sicslowpan uncompress_hdr: error context not found\n"); return; } - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, context->prefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix, unc_ctxconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } else { /* not context based => link local M = 0, DAC = 0 - same as SAC */ - uncompress_addr(&SICSLOWPAN_IP_BUF->destipaddr, llprefix, + uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix, unc_llconf[tmp], (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); } @@ -934,59 +1108,60 @@ uncompress_hdr_hc06(uint16_t ip_len) /* The next header is compressed, NHC is following */ if((*hc06_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) { uint8_t checksum_compressed; - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; + SICSLOWPAN_IP_BUF(buf)->proto = UIP_PROTO_UDP; checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC; PRINTF("IPHC: Incoming header value: %i\n", *hc06_ptr); switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) { case SICSLOWPAN_NHC_UDP_CS_P_00: - /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ - memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); - memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 3, 2); - PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 5; - break; + /* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */ + memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 3, 2); + PRINTF("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 5; + break; case SICSLOWPAN_NHC_UDP_CS_P_01: /* 1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit inline */ - PRINTF("IPHC: Decompressing destination\n"); - memcpy(&SICSLOWPAN_UDP_BUF->srcport, hc06_ptr + 1, 2); - SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3))); - PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 4; - break; + PRINTF("IPHC: Decompressing destination\n"); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->srcport, hc06_ptr + 1, 2); + SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3))); + PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 4; + break; case SICSLOWPAN_NHC_UDP_CS_P_10: /* 1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit inline*/ - PRINTF("IPHC: Decompressing source\n"); - SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + - (*(hc06_ptr + 1))); - memcpy(&SICSLOWPAN_UDP_BUF->destport, hc06_ptr + 2, 2); - PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 4; - break; + PRINTF("IPHC: Decompressing source\n"); + SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + + (*(hc06_ptr + 1))); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->destport, hc06_ptr + 2, 2); + PRINTF("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 4; + break; case SICSLOWPAN_NHC_UDP_CS_P_11: - /* 1 byte for NHC, 1 byte for ports */ - SICSLOWPAN_UDP_BUF->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + - (*(hc06_ptr + 1) >> 4)); - SICSLOWPAN_UDP_BUF->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + - ((*(hc06_ptr + 1)) & 0x0F)); - PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n", - UIP_HTONS(SICSLOWPAN_UDP_BUF->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF->destport)); - hc06_ptr += 2; - break; + /* 1 byte for NHC, 1 byte for ports */ + SICSLOWPAN_UDP_BUF(buf)->srcport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + (*(hc06_ptr + 1) >> 4)); + SICSLOWPAN_UDP_BUF(buf)->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN + + ((*(hc06_ptr + 1)) & 0x0F)); + PRINTF("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n", + UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->srcport), UIP_HTONS(SICSLOWPAN_UDP_BUF(buf)->destport)); + hc06_ptr += 2; + break; default: PRINTF("sicslowpan uncompress_hdr: error unsupported UDP compression\n"); return; } if(!checksum_compressed) { /* has_checksum, default */ - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc06_ptr, 2); - hc06_ptr += 2; - PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n"); + memcpy(&SICSLOWPAN_UDP_BUF(buf)->udpchksum, hc06_ptr, 2); + hc06_ptr += 2; + PRINTF("IPHC: sicslowpan uncompress_hdr: checksum included\n"); } else { PRINTF("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n"); } @@ -1005,17 +1180,17 @@ uncompress_hdr_hc06(uint16_t ip_len) if(ip_len == 0) { int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN; /* This is not a fragmented packet */ - SICSLOWPAN_IP_BUF->len[0] = len >> 8; - SICSLOWPAN_IP_BUF->len[1] = len & 0x00FF; + SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8; + SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF; } else { /* This is a 1st fragment */ - SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8; - SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; + SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8; + SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; } /* length field in UDP header */ - if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) { - memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2); + if(SICSLOWPAN_IP_BUF(buf)->proto == UIP_PROTO_UDP) { + memcpy(&SICSLOWPAN_UDP_BUF(buf)->udplen, &SICSLOWPAN_IP_BUF(buf)->len[0], 2); } return; @@ -1360,7 +1535,6 @@ static uint8_t output(const uip_lladdr_t *localdest) { int framer_hdrlen; - int max_payload; /* The MAC address of the destination of the packet */ linkaddr_t dest; @@ -1426,7 +1600,7 @@ output(const uip_lladdr_t *localdest) compress_hdr_ipv6(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 - compress_hdr_hc06(&dest); + compress_hdr_iphc(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ } else { compress_hdr_ipv6(&dest); @@ -1442,21 +1616,23 @@ output(const uip_lladdr_t *localdest) framer_hdrlen = NETSTACK_FRAMER.length(); if(framer_hdrlen < 0) { /* Framing failed, we assume the maximum header length */ - framer_hdrlen = 21; + framer_hdrlen = 23; } #else /* USE_FRAMER_HDRLEN */ - framer_hdrlen = 21; + framer_hdrlen = 23; #endif /* USE_FRAMER_HDRLEN */ max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; - if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) { + if((int)uip_len - (int)uncomp_hdr_len > (int)max_payload - (int)packetbuf_hdr_len) { #if SICSLOWPAN_CONF_FRAG struct queuebuf *q; + uint16_t frag_tag; + /* * The outbound IPv6 packet is too large to fit into a single 15.4 * packet, so we fragment it into multiple packets and send them. * The first fragment contains frag1 dispatch, then - * IPv6/HC1/HC06/HC_UDP dispatchs/headers. + * IPv6/IPHC/HC_UDP dispatchs/headers. * The following fragments contain only the fragn dispatch. */ int estimated_fragments = ((int)uip_len) / (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1; @@ -1472,7 +1648,10 @@ output(const uip_lladdr_t *localdest) /* Create 1st Fragment */ PRINTFO("sicslowpan output: 1rst fragment "); - /* move HC1/HC06/IPv6 header */ + /* Reset last tx status to ok in case the fragment transmissions are deferred */ + last_tx_status = MAC_TX_OK; + + /* move IPHC/IPv6 header */ memmove(packetbuf_ptr + SICSLOWPAN_FRAG1_HDR_LEN, packetbuf_ptr, packetbuf_hdr_len); /* @@ -1483,14 +1662,13 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len)); -/* PACKETBUF_FRAG_BUF->tag = uip_htons(my_tag); */ - SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, my_tag); - my_tag++; + frag_tag = my_tag++; + SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag); /* Copy payload and send */ packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; - packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; - PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, my_tag); + packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; + PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len); packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len); @@ -1525,7 +1703,7 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len)); - packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; + packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; while(processed_ip_out_len < uip_len) { PRINTFO("sicslowpan output: fragment "); PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3; @@ -1536,7 +1714,7 @@ output(const uip_lladdr_t *localdest) packetbuf_payload_len = uip_len - processed_ip_out_len; } PRINTFO("(offset %d, len %d, tag %d)\n", - processed_ip_out_len >> 3, packetbuf_payload_len, my_tag); + processed_ip_out_len >> 3, packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + processed_ip_out_len, packetbuf_payload_len); packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len); @@ -1594,8 +1772,12 @@ input(void) { /* size of the IP packet (read from fragment) */ uint16_t frag_size = 0; + int8_t frag_context = 0; /* offset of the fragment in the IP packet */ uint8_t frag_offset = 0; + uint8_t is_fragment = 0; + uint8_t *buffer; + #if SICSLOWPAN_CONF_FRAG uint8_t is_fragment = 0; /* tag of the fragment */ @@ -1610,15 +1792,15 @@ input(void) /* The MAC puts the 15.4 payload inside the packetbuf data buffer */ packetbuf_ptr = packetbuf_dataptr(); + /* This is default uip_buf since we assume that this is not fragmented */ + buffer = (uint8_t *)UIP_IP_BUF; + /* Save the RSSI of the incoming packet in case the upper layer will want to query us for it later. */ last_rssi = (signed short)packetbuf_attr(PACKETBUF_ATTR_RSSI); + #if SICSLOWPAN_CONF_FRAG - /* if reassembly timed out, cancel it */ - if(timer_expired(&reass_timer)) { - sicslowpan_len = 0; - processed_ip_in_len = 0; - } + /* * Since we don't support the mesh and broadcast header, the first header * we look for is the fragmentation header @@ -1637,6 +1819,14 @@ input(void) /* printf("frag1 %d %d\n", reass_tag, frag_tag);*/ first_fragment = 1; is_fragment = 1; + + /* Add the fragment to the fragmentation context */ + frag_context = add_fragment(frag_tag, frag_size, frag_offset); + + if(frag_context == -1) return; + + buffer = frag_info[frag_context].first_frag; + break; case SICSLOWPAN_DISPATCH_FRAGN: /* @@ -1656,7 +1846,16 @@ input(void) PRINTFI("last_fragment?: processed_ip_in_len %d packetbuf_payload_len %d frag_size %d\n", processed_ip_in_len, packetbuf_datalen() - packetbuf_hdr_len, frag_size); - if(processed_ip_in_len + packetbuf_datalen() - packetbuf_hdr_len >= frag_size) { + /* Add the fragment to the fragmentation context (this will also copy the payload) */ + frag_context = add_fragment(frag_tag, frag_size, frag_offset); + + if(frag_context == -1) return; + + /* Ok - add_fragment will store the fragment automatically - so we should not store more */ + buffer = NULL; + + // if(processed_ip_in_len + packetbuf_datalen() - packetbuf_hdr_len >= frag_size) { + if(frag_info[frag_context].reassembled_len >= frag_size) { last_fragment = 1; } is_fragment = 1; @@ -1665,65 +1864,7 @@ input(void) break; } - /* We are currently reassembling a packet, but have just received the first - * fragment of another packet. We can either ignore it and hope to receive - * the rest of the under-reassembly packet fragments, or we can discard the - * previous packet altogether, and start reassembling the new packet. - * - * We discard the previous packet, and start reassembling the new packet. - * This lessens the negative impacts of too high SICSLOWPAN_REASS_MAXAGE. - */ -#define PRIORITIZE_NEW_PACKETS 1 -#if PRIORITIZE_NEW_PACKETS - - if(!is_fragment) { - /* Prioritize non-fragment packets too. */ - sicslowpan_len = 0; - processed_ip_in_len = 0; - } else if(processed_ip_in_len > 0 && first_fragment - && !linkaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) { - sicslowpan_len = 0; - processed_ip_in_len = 0; - } -#endif /* PRIORITIZE_NEW_PACKETS */ - - if(processed_ip_in_len > 0) { - /* reassembly is ongoing */ - /* printf("frag %d %d\n", reass_tag, frag_tag);*/ - if((frag_size > 0 && - (frag_size != sicslowpan_len || - reass_tag != frag_tag || - !linkaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)))) || - frag_size == 0) { - /* - * the packet is a fragment that does not belong to the packet - * being reassembled or the packet is not a fragment. - */ - PRINTFI("sicslowpan input: Dropping 6lowpan packet that is not a fragment of the packet currently being reassembled\n"); - return; - } - } else { - /* - * reassembly is off - * start it if we received a fragment - */ - if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) { - /* We are currently not reassembling a packet, but have received a packet fragment - * that is not the first one. */ - if(is_fragment && !first_fragment) { - return; - } - - sicslowpan_len = frag_size; - reass_tag = frag_tag; - timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND); - PRINTFI("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n", - sicslowpan_len, reass_tag); - linkaddr_copy(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER)); - } - } - - if(packetbuf_hdr_len == SICSLOWPAN_FRAGN_HDR_LEN) { + if(is_fragment && !first_fragment) { /* this is a FRAGN, skip the header compression dispatch section */ goto copypayload; } @@ -1733,7 +1874,7 @@ input(void) #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 if((PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] & 0xe0) == SICSLOWPAN_DISPATCH_IPHC) { PRINTFI("sicslowpan input: IPHC\n"); - uncompress_hdr_hc06(frag_size); + uncompress_hdr_iphc(buffer, frag_size); } else #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]) { @@ -1748,7 +1889,7 @@ input(void) packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; /* Put uncompressed IP header in sicslowpan_buf. */ - memcpy(SICSLOWPAN_IP_BUF, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN); + memcpy(buffer, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN); /* Update uncomp_hdr_len and packetbuf_hdr_len. */ packetbuf_hdr_len += UIP_IPH_LEN; @@ -1782,16 +1923,20 @@ input(void) { int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3) + packetbuf_payload_len; - if(req_size > sizeof(sicslowpan_buf)) { + if(req_size > sizeof(uip_buf)) { PRINTF( - "SICSLOWPAN: packet dropped, minimum required SICSLOWPAN_IP_BUF size: %d+%d+%d+%d=%d (current size: %d)\n", + "SICSLOWPAN: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n", UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3), - packetbuf_payload_len, req_size, sizeof(sicslowpan_buf)); + packetbuf_payload_len, req_size, sizeof(uip_buf)); return; } } - memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), packetbuf_ptr + packetbuf_hdr_len, packetbuf_payload_len); + /* copy the payload if buffer is non-null - which is only the case with first fragment + or packets that are non fragmented */ + if(buffer != NULL) { + memcpy((uint8_t *)buffer + uncomp_hdr_len, packetbuf_ptr + packetbuf_hdr_len, packetbuf_payload_len); + } /* update processed_ip_in_len if fragment, sicslowpan_len otherwise */ @@ -1799,44 +1944,40 @@ input(void) if(frag_size > 0) { /* Add the size of the header only for the first fragment. */ if(first_fragment != 0) { - processed_ip_in_len += uncomp_hdr_len; + frag_info[frag_context].reassembled_len = uncomp_hdr_len + packetbuf_payload_len; + frag_info[frag_context].first_frag_len = uncomp_hdr_len + packetbuf_payload_len;; } /* For the last fragment, we are OK if there is extrenous bytes at the end of the packet. */ if(last_fragment != 0) { - processed_ip_in_len = frag_size; - } else { - processed_ip_in_len += packetbuf_payload_len; + frag_info[frag_context].reassembled_len = frag_size; + /* copy to uip */ + copy_frags2uip(frag_context); } - PRINTF("processed_ip_in_len %d, packetbuf_payload_len %d\n", processed_ip_in_len, packetbuf_payload_len); - - } else { -#endif /* SICSLOWPAN_CONF_FRAG */ - sicslowpan_len = packetbuf_payload_len + uncomp_hdr_len; -#if SICSLOWPAN_CONF_FRAG } /* * If we have a full IP packet in sicslowpan_buf, deliver it to * the IP stack */ - PRINTF("sicslowpan_init processed_ip_in_len %d, sicslowpan_len %d\n", - processed_ip_in_len, sicslowpan_len); - if(processed_ip_in_len == 0 || (processed_ip_in_len == sicslowpan_len)) { + if(!is_fragment || last_fragment) { + /* packet is in uip already - just set length */ + if(is_fragment != 0 && last_fragment != 0) { + uip_len = frag_size; + } else { + uip_len = packetbuf_payload_len + uncomp_hdr_len; + } PRINTFI("sicslowpan input: IP packet ready (length %d)\n", - sicslowpan_len); - memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)SICSLOWPAN_IP_BUF, sicslowpan_len); - uip_len = sicslowpan_len; - sicslowpan_len = 0; - processed_ip_in_len = 0; + uip_len); + #endif /* SICSLOWPAN_CONF_FRAG */ #if DEBUG { uint16_t ndx; - PRINTF("after decompression %u:", SICSLOWPAN_IP_BUF->len[1]); - for (ndx = 0; ndx < SICSLOWPAN_IP_BUF->len[1] + 40; ndx++) { - uint8_t data = ((uint8_t *) (SICSLOWPAN_IP_BUF))[ndx]; + PRINTF("after decompression %u:", UIP_IP_BUF->len[1]); + for (ndx = 0; ndx < UIP_IP_BUF->len[1] + 40; ndx++) { + uint8_t data = ((uint8_t *) (UIP_IP_BUF))[ndx]; PRINTF("%02x", data); } PRINTF("\n"); @@ -1926,3 +2067,4 @@ const struct network_driver sicslowpan_driver = { }; /*--------------------------------------------------------------------*/ /** @} */ + From d4dc45e09697627f690e17505584dd4e87fcd816 Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Mon, 14 Sep 2015 17:34:08 +0200 Subject: [PATCH 2/4] updated sicslowpan documentation and platform configurations --- core/net/ipv6/sicslowpan.c | 10 +++--- doc/sicslowpan-doc.txt | 67 ++++++++++++++--------------------- platform/micaz/contiki-conf.h | 1 + 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index f6af5d46f..e7973d987 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -211,7 +211,6 @@ static uint8_t uncomp_hdr_len; static int last_tx_status; /** @} */ -static uint16_t my_tag; static int last_rssi; @@ -222,6 +221,8 @@ static int last_rssi; * temporary memory allocation. In that case the number of available * buffers will be lower for a short time. **/ +#if SICSLOWPAN_CONF_FRAG +static uint16_t my_tag; /** The total length of the IPv6 packet in the sicslowpan_buf. */ @@ -434,7 +435,7 @@ copy_frags2uip(int context) /* deallocate all the fragments for this context */ clear_fragments(context); } - +#endif /* SICSLOWPAN_CONF_FRAG */ /* -------------------------------------------------------------------------- */ @@ -1541,6 +1542,7 @@ output(const uip_lladdr_t *localdest) #if SICSLOWPAN_CONF_FRAG /* Number of bytes processed. */ +#if SICSLOWPAN_CONF_FRAG uint16_t processed_ip_out_len; #endif /* SICSLOWPAN_CONF_FRAG */ @@ -1772,14 +1774,14 @@ input(void) { /* size of the IP packet (read from fragment) */ uint16_t frag_size = 0; - int8_t frag_context = 0; /* offset of the fragment in the IP packet */ uint8_t frag_offset = 0; - uint8_t is_fragment = 0; uint8_t *buffer; #if SICSLOWPAN_CONF_FRAG uint8_t is_fragment = 0; + int8_t frag_context = 0; + /* tag of the fragment */ uint16_t frag_tag = 0; uint8_t first_fragment = 0, last_fragment = 0; diff --git a/doc/sicslowpan-doc.txt b/doc/sicslowpan-doc.txt index 7157be96e..37a9ea0c7 100644 --- a/doc/sicslowpan-doc.txt +++ b/doc/sicslowpan-doc.txt @@ -38,10 +38,10 @@ ArchRock and Sensinode implementations. We do not implement mesh under related features, as we target route over techniques. -\subsection hc01 draft-hui-6lowpan-hc-01 +\subsection RFC 6282 -draft-hui-6lowpan-hc-01 defines a stateful header compression mechanism -which should soon deprecate the stateless header compression mechanism +RFC6282 defines a stateful header compression mechanism +which deprecate the stateless header compression mechanism defined in RFC4944. It is much more powerfull and flexible, in particular it allows compression of some multicast addresses and of all global unicast addresses. @@ -110,8 +110,8 @@ the link-layer address. The dependency is reflected in the \subsection io Packet Input/Output -At initialization, the #input function in sicslowpan.c is set as the -function to be called by the MAC upon packet reception. The #output +At initialization, the input function in sicslowpan.c is set as the +function to be called by the MAC upon packet reception. The output function is set as the tcpip_output function.
At packet reception, the link-layer copies the 802.15.4 payload in the rime buffer, and sets its length. It also stores the source and @@ -122,19 +122,19 @@ packetbuf_set_datalen(rx_frame.payload_length); packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (const rimeaddr_t *)&rx_frame.dest_addr); packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (const rimeaddr_t *)&rx_frame.src_addr); \endcode -It then calls the sicslowpan #input function. Similarly, when the IPv6 layer +It then calls the sicslowpan input function. Similarly, when the IPv6 layer has a packet to send over the radio, it puts the packet in uip_buf, -sets uip_len and calls the sicslowpan #output function. +sets uip_len and calls the sicslowpan output function. \subsection frag Fragmentation -\li #output function: When an IP packet, after header compression, is +\li output function: When an IP packet, after header compression, is too big to fit in a 802.15.4 frame, it is fragmented in several packets which are sent successively over the radio. The packets are formatted as defined in RFC 4944. Only the first fragment contains the IP/UDP compressed or uncompressed header fields. -\li #input function: This function takes care of fragment +\li input function: This function takes care of fragment reassembly. We do not assume that the fragments are received in order. When reassembly of a packet is ongoing, we discard any non fragmented packet or fragment from another packet. Reassembly times out after @@ -143,8 +143,9 @@ packet or fragment from another packet. Reassembly times out after \note Fragmentation support is enabled by setting the #SICSLOWPAN_CONF_FRAG compilation option. -\note As we do not support complex buffer allocation mechanism, for now -we define a new 1280 bytes buffer (#sicslowpan_buf) to reassemble packets. +\note In order to make it possible to reassemble multiple packets at +the same time we have a mechanism for storing each fragment per sender +and tag until it is fully reassembled or the reassemly times out. At reception, once all the fragments are received, we copy the packet to #uip_buf, set #uip_len, and call #tcpip_input. @@ -157,49 +158,35 @@ the header 25 bytes long). Compression schemes
The #SICSLOWPAN_CONF_COMPRESSION compilation option defines the - compression scheme supported. We support HC1, HC06, and IPv6 compression. -HC1 and IPv6 compression are defined in RFC4944, HC06 in -draft-hui-6lowpan-hc-06. What we call IPv6 compression means sending packets +compression scheme supported. We support IPHC, and IPv6 compression. +IPv6 compression are defined in RFC4944, IPHC in RFC6282. +What we call IPv6 compression means sending packets with no compression, and adding the IPv6 dispatch before the IPv6 header.
If at compile time IPv6 "compression" is chosen, packets sent will never be compressed, and compressed packets will not be processed at reception.
-If at compile time either HC1 or HC06 are chosen, we will try to compress + +If at compile time IPHC is chosen, we will try to compress all fields at sending, and will accept packets compressed with the -chosen scheme, as well as uncompressed packets.
-Note that HC1 and HC06 supports are mutually exclusive. HC06 should soon -deprecate HC1. +chosen scheme, as well as uncompressed packets.
. Compression related functions
-When a packet is received, the #input function is called. Fragmentation +When a packet is received, the input function is called. Fragmentation issues are handled, then we check the dispatch byte: if it is IPv6, we -treat the packet inline. If it is HC1 or HC06, the corresponding -decompression function (#uncompress_hdr_hc1 or #uncompress_hdr_hc06) -is called.
+treat the packet inline. If it is IPHC, the decompression function +(uncompress_hdr_iphc) is called.
When a packet needs to be sent, we try to compress it. If only the IPv6 compression support is enabled, we just add the IPv6 dispatch before the -802.15.4 payload. If HC1 or HC06 support is enabled, we call the -corresponding compression function (#compress_hdr_hc1 or #compress_hdr_hc06) +802.15.4 payload. If IPHC support is enabled, we call the +corresponding compression function (compress_hdr_iphc) to compress the packet as much as possible. -HC1 comments
-In HC1, if the IPv6 flow label is not compressed, we would need to copy -the fields after the flow label starting in the middle of a byte (the -flow label is 20 bits long). To avoid this, we compress the packets only -if all fields can be compressed. If we cannot, we use the IPv6 dispatch -and send all headers fields inline. This behavior is the one defined in -draft-hui-6lowpan-interop-00.
-In the same way, if the packet is an UDP packet, we compress the UDP -header only if all fields can be compressed.
-Note that HC1 can only compress unicast link local addresses. For this -reason, we recommend using HC01. - -HC01 comments
-HC01 uses address contexts to enable compression of global unicast +IPHC comments
+IPHC uses address contexts to enable compression of global unicast addresses. All nodes must share context (namely the global prefixes in use) to compress and uncompress such addresses successfully. The context -number is defined by 2 bits. Context 00 is reserved for the link local +number is defined by 4 bits. Context 00 is reserved for the link local context. Other contexts have to be distributed within the LoWPAN -dynamically, by means of ND extensions yet to be defined.
+dynamically, by means of ND extensions yet to be implemented.
Until then, if you want to test global address compression, you need to configure the global contexts manually. diff --git a/platform/micaz/contiki-conf.h b/platform/micaz/contiki-conf.h index 099941d85..16e74567a 100644 --- a/platform/micaz/contiki-conf.h +++ b/platform/micaz/contiki-conf.h @@ -145,6 +145,7 @@ #define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 #ifndef SICSLOWPAN_CONF_FRAG #define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_FRAGMENT_BUFFERS 4 #define SICSLOWPAN_CONF_MAXAGE 8 #endif /* SICSLOWPAN_CONF_FRAG */ #define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 From 02e07607a705185d7c5f9592973d378c29353e8d Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 18 Sep 2015 09:25:42 +0200 Subject: [PATCH 3/4] removed old HC1 code since it is not expected to be used and removed NH_COMPRESSOR --- core/net/ipv6/sicslowpan.c | 273 ------------------------------------- 1 file changed, 273 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index e7973d987..6f23a77cd 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -172,10 +172,6 @@ void uip_log(char *msg); /** \name General variables * @{ */ -#ifdef SICSLOWPAN_NH_COMPRESSOR -/** A pointer to the additional compressor */ -extern struct sicslowpan_nh_compressor SICSLOWPAN_NH_COMPRESSOR; -#endif /** * A pointer to the packetbuf buffer. @@ -929,11 +925,6 @@ compress_hdr_iphc(linkaddr_t *link_destaddr) } #endif /*UIP_CONF_UDP*/ -#ifdef SICSLOWPAN_NH_COMPRESSOR - /* if nothing to compress just return zero */ - hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.compress(hc06_ptr, &uncomp_hdr_len); -#endif - /* before the packetbuf_hdr_len operation */ PACKETBUF_IPHC_BUF[0] = iphc0; PACKETBUF_IPHC_BUF[1] = iphc1; @@ -1168,11 +1159,6 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len) } uncomp_hdr_len += UIP_UDPH_LEN; } -#ifdef SICSLOWPAN_NH_COMPRESSOR - else { - hc06_ptr += SICSLOWPAN_NH_COMPRESSOR.uncompress(hc06_ptr, sicslowpan_buf, &uncomp_hdr_len); - } -#endif } packetbuf_hdr_len = hc06_ptr - packetbuf_ptr; @@ -1199,256 +1185,6 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len) /** @} */ #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ - -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 -/*--------------------------------------------------------------------*/ -/** \name HC1 compression and uncompression functions - * @{ */ -/*--------------------------------------------------------------------*/ -/** - * \brief Compress IP/UDP header using HC1 and HC_UDP - * - * This function is called by the 6lowpan code to create a compressed - * 6lowpan packet in the packetbuf buffer from a full IPv6 packet in the - * uip_buf buffer. - * - * - * If we can compress everything, we use HC1 dispatch, if not we use - * IPv6 dispatch.\n - * We can compress everything if: - * - IP version is - * - Flow label and traffic class are 0 - * - Both src and dest ip addresses are link local - * - Both src and dest interface ID are recoverable from lower layer - * header - * - Next header is either ICMP, UDP or TCP - * - * Moreover, if next header is UDP, we try to compress it using HC_UDP. - * This is feasible is both ports are between F0B0 and F0B0 + 15. - * - * - * Resulting header structure: - * - For ICMP, TCP, non compressed UDP\n - * HC1 encoding = 11111010 (UDP) 11111110 (TCP) 11111100 (ICMP)\n - * \verbatim - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | LoWPAN HC1 Dsp | HC1 encoding | IPv6 Hop limit| L4 hdr + data| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - * - * - For compressed UDP\n - * HC1 encoding = 11111011, HC_UDP encoding = 11100000\n - * \verbatim - * 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | LoWPAN HC1 Dsp| HC1 encoding | HC_UDP encod.| IPv6 Hop limit| - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | src p.| dst p.| UDP checksum | L4 data... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * \endverbatim - * - * \param link_destaddr L2 destination address, needed to compress the - * IP destination field - */ -static void -compress_hdr_hc1(linkaddr_t *link_destaddr) -{ - /* - * Check if all the assumptions for full compression - * are valid : - */ - if(UIP_IP_BUF->vtc != 0x60 || - UIP_IP_BUF->tcflow != 0 || - UIP_IP_BUF->flow != 0 || - !uip_is_addr_linklocal(&UIP_IP_BUF->srcipaddr) || - !uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) || - !uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr) || - !uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr, - (uip_lladdr_t *)link_destaddr) || - (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 && - UIP_IP_BUF->proto != UIP_PROTO_UDP && - UIP_IP_BUF->proto != UIP_PROTO_TCP)) - { - /* - * IPV6 DISPATCH - * Something cannot be compressed, use IPV6 DISPATCH, - * compress nothing, copy IPv6 header in packetbuf buffer - */ - *packetbuf_ptr = SICSLOWPAN_DISPATCH_IPV6; - packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; - memcpy(packetbuf_ptr + packetbuf_hdr_len, UIP_IP_BUF, UIP_IPH_LEN); - packetbuf_hdr_len += UIP_IPH_LEN; - uncomp_hdr_len += UIP_IPH_LEN; - } else { - /* - * HC1 DISPATCH - * maximum compresssion: - * All fields in the IP header but Hop Limit are elided - * If next header is UDP, we compress UDP header using HC2 - */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] = SICSLOWPAN_DISPATCH_HC1; - uncomp_hdr_len += UIP_IPH_LEN; - switch(UIP_IP_BUF->proto) { - case UIP_PROTO_ICMP6: - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFC; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#if UIP_CONF_TCP - case UIP_PROTO_TCP: - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFE; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#endif /* UIP_CONF_TCP */ -#if UIP_CONF_UDP - case UIP_PROTO_UDP: - /* - * try to compress UDP header (we do only full compression). - * This is feasible if both src and dest ports are between - * SICSLOWPAN_UDP_PORT_MIN and SICSLOWPAN_UDP_PORT_MIN + 15 - */ - PRINTF("local/remote port %u/%u\n",UIP_UDP_BUF->srcport,UIP_UDP_BUF->destport); - if(UIP_HTONS(UIP_UDP_BUF->srcport) >= SICSLOWPAN_UDP_PORT_MIN && - UIP_HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX && - UIP_HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN && - UIP_HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) { - /* HC1 encoding */ - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_HC1_ENCODING] = 0xFB; - - /* HC_UDP encoding, ttl, src and dest ports, checksum */ - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_UDP_ENCODING] = 0xE0; - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_TTL] = UIP_IP_BUF->ttl; - - PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] = - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->srcport) - - SICSLOWPAN_UDP_PORT_MIN) << 4) + - (uint8_t)((UIP_HTONS(UIP_UDP_BUF->destport) - SICSLOWPAN_UDP_PORT_MIN)); - memcpy(&PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_CHKSUM], &UIP_UDP_BUF->udpchksum, 2); - packetbuf_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN; - uncomp_hdr_len += UIP_UDPH_LEN; - } else { - /* HC1 encoding and ttl */ - PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] = 0xFA; - PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL] = UIP_IP_BUF->ttl; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - } - break; -#endif /*UIP_CONF_UDP*/ - } - } - return; -} - -/*--------------------------------------------------------------------*/ -/** - * \brief Uncompress HC1 (and HC_UDP) headers and put them in - * sicslowpan_buf - * - * This function is called by the input function when the dispatch is - * HC1. - * We %process the packet in the packetbuf buffer, uncompress the header - * fields, and copy the result in the sicslowpan buffer. - * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len - * are set to the appropriate values - * - * \param ip_len Equal to 0 if the packet is not a fragment (IP length - * is then inferred from the L2 length), non 0 if the packet is a 1st - * fragment. - */ -static void -uncompress_hdr_hc1(uint16_t ip_len) -{ - /* version, traffic class, flow label */ - SICSLOWPAN_IP_BUF->vtc = 0x60; - SICSLOWPAN_IP_BUF->tcflow = 0; - SICSLOWPAN_IP_BUF->flow = 0; - - /* src and dest ip addresses */ - uip_ip6addr(&SICSLOWPAN_IP_BUF->srcipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->srcipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); - uip_ip6addr(&SICSLOWPAN_IP_BUF->destipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); - uip_ds6_set_addr_iid(&SICSLOWPAN_IP_BUF->destipaddr, - (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); - - uncomp_hdr_len += UIP_IPH_LEN; - - /* Next header field */ - switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_ENCODING] & 0x06) { - case SICSLOWPAN_HC1_NH_ICMP6: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_ICMP6; - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL]; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#if UIP_CONF_TCP - case SICSLOWPAN_HC1_NH_TCP: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_TCP; - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_PTR[PACKETBUF_HC1_TTL]; - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - break; -#endif/* UIP_CONF_TCP */ -#if UIP_CONF_UDP - case SICSLOWPAN_HC1_NH_UDP: - SICSLOWPAN_IP_BUF->proto = UIP_PROTO_UDP; - if(PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_HC1_ENCODING] & 0x01) { - /* UDP header is compressed with HC_UDP */ - if(PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_UDP_ENCODING] != - SICSLOWPAN_HC_UDP_ALL_C) { - PRINTF("sicslowpan (uncompress_hdr), packet not supported"); - return; - } - /* IP TTL */ - SICSLOWPAN_IP_BUF->ttl = PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_TTL]; - /* UDP ports, len, checksum */ - SICSLOWPAN_UDP_BUF->srcport = - UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN + - (PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] >> 4)); - SICSLOWPAN_UDP_BUF->destport = - UIP_HTONS(SICSLOWPAN_UDP_PORT_MIN + - (PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_PORTS] & 0x0F)); - memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, &PACKETBUF_HC1_HC_UDP_PTR[PACKETBUF_HC1_HC_UDP_CHKSUM], 2); - uncomp_hdr_len += UIP_UDPH_LEN; - packetbuf_hdr_len += SICSLOWPAN_HC1_HC_UDP_HDR_LEN; - } else { - packetbuf_hdr_len += SICSLOWPAN_HC1_HDR_LEN; - } - break; -#endif/* UIP_CONF_UDP */ - default: - /* this shouldn't happen, drop */ - return; - } - - /* IP length field. */ - if(ip_len == 0) { - int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN; - /* This is not a fragmented packet */ - SICSLOWPAN_IP_BUF->len[0] = len >> 8; - SICSLOWPAN_IP_BUF->len[1] = len & 0x00FF; - } else { - /* This is a 1st fragment */ - SICSLOWPAN_IP_BUF->len[0] = (ip_len - UIP_IPH_LEN) >> 8; - SICSLOWPAN_IP_BUF->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF; - } - /* length field in UDP header */ - if(SICSLOWPAN_IP_BUF->proto == UIP_PROTO_UDP) { - memcpy(&SICSLOWPAN_UDP_BUF->udplen, &SICSLOWPAN_IP_BUF->len[0], 2); - } - return; -} -/** @} */ -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ - - - /*--------------------------------------------------------------------*/ /** \name IPv6 dispatch "compression" function * @{ */ @@ -1595,9 +1331,6 @@ output(const uip_lladdr_t *localdest) if(uip_len >= COMPRESSION_THRESHOLD) { /* Try to compress the headers */ -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 - compress_hdr_hc1(&dest); -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 compress_hdr_ipv6(&dest); #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */ @@ -1880,12 +1613,6 @@ input(void) } else #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]) { -#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 - case SICSLOWPAN_DISPATCH_HC1: - PRINTFI("sicslowpan input: HC1\n"); - uncompress_hdr_hc1(frag_size); - break; -#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC1 */ case SICSLOWPAN_DISPATCH_IPV6: PRINTFI("sicslowpan input: IPV6\n"); packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; From 6ef8f477643345d70c43ecdb30a62718ed41111d Mon Sep 17 00:00:00 2001 From: Joakim Eriksson Date: Fri, 18 Sep 2015 14:22:17 +0200 Subject: [PATCH 4/4] Style fixes, LLSEC.overhead and MAC_MAX_PAYLOAD --- core/net/ipv6/sicslowpan.c | 51 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/core/net/ipv6/sicslowpan.c b/core/net/ipv6/sicslowpan.c index 6f23a77cd..869379489 100644 --- a/core/net/ipv6/sicslowpan.c +++ b/core/net/ipv6/sicslowpan.c @@ -213,10 +213,7 @@ static int last_rssi; /* ----------------------------------------------------------------- */ /* Support for reassembling multiple packets */ /* ----------------------------------------------------------------- */ -/* The fragmentation buffer are also possible to use for other - * temporary memory allocation. In that case the number of available - * buffers will be lower for a short time. - **/ + #if SICSLOWPAN_CONF_FRAG static uint16_t my_tag; @@ -406,13 +403,15 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset) frag_info[i].reassembled_len += len; return i; } else { - /* should we also clear all fragments since we failed to store this fragment? */ + /* should we also clear all fragments since we failed to store + this fragment? */ PRINTF("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag); return -1; } } /*---------------------------------------------------------------------------*/ -/* Copy all the fragments that are associated with a specific context into uip */ +/* Copy all the fragments that are associated with a specific context + into uip */ static void copy_frags2uip(int context) { @@ -501,7 +500,7 @@ static struct sicslowpan_addr_context *context; /** pointer to the byte where to write next inline field. */ static uint8_t *hc06_ptr; -/* ession of linklocal */ +/* Uncompression of linklocal */ /* 0 -> 16 bytes from packet */ /* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */ /* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */ @@ -945,6 +944,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr) * At the end of the decompression, packetbuf_hdr_len and uncompressed_hdr_len * are set to the appropriate values * + * \param buf Pointer to the buffer to uncompress the packet into. * \param ip_len Equal to 0 if the packet is not a fragment (IP length * is then inferred from the L2 length), non 0 if the packet is a 1st * fragment. @@ -1272,13 +1272,13 @@ static uint8_t output(const uip_lladdr_t *localdest) { int framer_hdrlen; + int max_payload; /* The MAC address of the destination of the packet */ linkaddr_t dest; #if SICSLOWPAN_CONF_FRAG /* Number of bytes processed. */ -#if SICSLOWPAN_CONF_FRAG uint16_t processed_ip_out_len; #endif /* SICSLOWPAN_CONF_FRAG */ @@ -1351,14 +1351,14 @@ output(const uip_lladdr_t *localdest) framer_hdrlen = NETSTACK_FRAMER.length(); if(framer_hdrlen < 0) { /* Framing failed, we assume the maximum header length */ - framer_hdrlen = 23; + framer_hdrlen = 21; } #else /* USE_FRAMER_HDRLEN */ - framer_hdrlen = 23; + framer_hdrlen = 21; #endif /* USE_FRAMER_HDRLEN */ - max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; - if((int)uip_len - (int)uncomp_hdr_len > (int)max_payload - (int)packetbuf_hdr_len) { + max_payload = MAC_MAX_PAYLOAD - framer_hdrlen; + if((int)uip_len - (int)uncomp_hdr_len > max_payload - (int)packetbuf_hdr_len) { #if SICSLOWPAN_CONF_FRAG struct queuebuf *q; uint16_t frag_tag; @@ -1402,7 +1402,7 @@ output(const uip_lladdr_t *localdest) /* Copy payload and send */ packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; - packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; + packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; PRINTFO("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag); memcpy(packetbuf_ptr + packetbuf_hdr_len, (uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len); @@ -1438,7 +1438,7 @@ output(const uip_lladdr_t *localdest) /* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */ SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len)); - packetbuf_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - packetbuf_hdr_len) & 0xfffffff8; + packetbuf_payload_len = (max_payload - packetbuf_hdr_len) & 0xfffffff8; while(processed_ip_out_len < uip_len) { PRINTFO("sicslowpan output: fragment "); PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3; @@ -1558,7 +1558,9 @@ input(void) /* Add the fragment to the fragmentation context */ frag_context = add_fragment(frag_tag, frag_size, frag_offset); - if(frag_context == -1) return; + if(frag_context == -1) { + return; + } buffer = frag_info[frag_context].first_frag; @@ -1581,15 +1583,18 @@ input(void) PRINTFI("last_fragment?: processed_ip_in_len %d packetbuf_payload_len %d frag_size %d\n", processed_ip_in_len, packetbuf_datalen() - packetbuf_hdr_len, frag_size); - /* Add the fragment to the fragmentation context (this will also copy the payload) */ + /* Add the fragment to the fragmentation context (this will also + copy the payload) */ frag_context = add_fragment(frag_tag, frag_size, frag_offset); - if(frag_context == -1) return; + if(frag_context == -1) { + return; + } - /* Ok - add_fragment will store the fragment automatically - so we should not store more */ + /* Ok - add_fragment will store the fragment automatically - so + we should not store more */ buffer = NULL; - // if(processed_ip_in_len + packetbuf_datalen() - packetbuf_hdr_len >= frag_size) { if(frag_info[frag_context].reassembled_len >= frag_size) { last_fragment = 1; } @@ -1674,7 +1679,7 @@ input(void) /* Add the size of the header only for the first fragment. */ if(first_fragment != 0) { frag_info[frag_context].reassembled_len = uncomp_hdr_len + packetbuf_payload_len; - frag_info[frag_context].first_frag_len = uncomp_hdr_len + packetbuf_payload_len;; + frag_info[frag_context].first_frag_len = uncomp_hdr_len + packetbuf_payload_len; } /* For the last fragment, we are OK if there is extrenous bytes at the end of the packet. */ @@ -1696,11 +1701,12 @@ input(void) } else { uip_len = packetbuf_payload_len + uncomp_hdr_len; } +#else + uip_len = packetbuf_payload_len + uncomp_hdr_len; +#endif /* SICSLOWPAN_CONF_FRAG */ PRINTFI("sicslowpan input: IP packet ready (length %d)\n", uip_len); -#endif /* SICSLOWPAN_CONF_FRAG */ - #if DEBUG { uint16_t ndx; @@ -1736,6 +1742,7 @@ sicslowpan_init(void) * Set out output function as the function to be called from uIP to * send a packet. */ + tcpip_set_outputfunc(output); #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06