6lowpan: added support for paging dispatch, and placeholders for 6lorh

This commit is contained in:
Simon Duquennoy 2017-07-05 15:30:45 +02:00
parent 0f5a87645d
commit 3acec4a849
3 changed files with 124 additions and 64 deletions

View File

@ -83,13 +83,11 @@
#define LOG_MODULE "6LoWPAN" #define LOG_MODULE "6LoWPAN"
#define LOG_LEVEL SICSLOWPAN_LOG_LEVEL #define LOG_LEVEL SICSLOWPAN_LOG_LEVEL
#ifndef SICSLOWPAN_COMPRESSION
#ifdef SICSLOWPAN_CONF_COMPRESSION #ifdef SICSLOWPAN_CONF_COMPRESSION
#define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION #define SICSLOWPAN_COMPRESSION SICSLOWPAN_CONF_COMPRESSION
#else #else /* SICSLOWPAN_CONF_COMPRESSION */
#define SICSLOWPAN_COMPRESSION SICSLOWPAN_COMPRESSION_IPV6 #define SICSLOWPAN_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
#endif /* SICSLOWPAN_CONF_COMPRESSION */ #endif /* SICSLOWPAN_CONF_COMPRESSION */
#endif /* SICSLOWPAN_COMPRESSION */
#define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1])) #define GET16(ptr,index) (((uint16_t)((ptr)[index] << 8)) | ((ptr)[(index) + 1]))
#define SET16(ptr,index,value) do { \ #define SET16(ptr,index,value) do { \
@ -108,18 +106,18 @@
/* define the buffer as a byte array */ /* define the buffer as a byte array */
#define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len)) #define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
#define PACKETBUF_HC1_PTR (packetbuf_ptr + packetbuf_hdr_len) #define PACKETBUF_6LO_PTR (packetbuf_ptr + packetbuf_hdr_len)
#define PACKETBUF_HC1_DISPATCH 0 /* 8 bit */ #define PACKETBUF_6LO_DISPATCH 0 /* 8 bit */
#define PACKETBUF_HC1_ENCODING 1 /* 8 bit */ #define PACKETBUF_6LO_ENCODING 1 /* 8 bit */
#define PACKETBUF_HC1_TTL 2 /* 8 bit */ #define PACKETBUF_6LO_TTL 2 /* 8 bit */
#define PACKETBUF_HC1_HC_UDP_PTR (packetbuf_ptr + packetbuf_hdr_len) #define PACKETBUF_6LO_HC_UDP_PTR (packetbuf_ptr + packetbuf_hdr_len)
#define PACKETBUF_HC1_HC_UDP_DISPATCH 0 /* 8 bit */ #define PACKETBUF_6LO_HC_UDP_DISPATCH 0 /* 8 bit */
#define PACKETBUF_HC1_HC_UDP_HC1_ENCODING 1 /* 8 bit */ #define PACKETBUF_6LO_HC_UDP_HC1_ENCODING 1 /* 8 bit */
#define PACKETBUF_HC1_HC_UDP_UDP_ENCODING 2 /* 8 bit */ #define PACKETBUF_6LO_HC_UDP_UDP_ENCODING 2 /* 8 bit */
#define PACKETBUF_HC1_HC_UDP_TTL 3 /* 8 bit */ #define PACKETBUF_6LO_HC_UDP_TTL 3 /* 8 bit */
#define PACKETBUF_HC1_HC_UDP_PORTS 4 /* 8 bit */ #define PACKETBUF_6LO_HC_UDP_PORTS 4 /* 8 bit */
#define PACKETBUF_HC1_HC_UDP_CHKSUM 5 /* 16 bit */ #define PACKETBUF_6LO_HC_UDP_CHKSUM 5 /* 16 bit */
/** \name Pointers in the sicslowpan and uip buffer /** \name Pointers in the sicslowpan and uip buffer
* @{ * @{
@ -216,6 +214,11 @@ static int packetbuf_payload_len;
*/ */
static uint8_t uncomp_hdr_len; static uint8_t uncomp_hdr_len;
/**
* The current page (RFC 4944)
*/
static uint8_t curr_page;
/** /**
* the result of the last transmitted fragment * the result of the last transmitted fragment
*/ */
@ -499,8 +502,8 @@ set_packet_attrs(void)
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 #if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_HC06
/** \name HC06 specific variables /** \name variables specific to HC06 and more recent versions
* @{ * @{
*/ */
@ -696,7 +699,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
} }
#endif /* LOG_DBG_ENABLED */ #endif /* LOG_DBG_ENABLED */
hc06_ptr = packetbuf_ptr + 2; hc06_ptr = PACKETBUF_IPHC_BUF + 2;
/* /*
* As we copy some bit-length fields, in the IPHC encoding bytes, * As we copy some bit-length fields, in the IPHC encoding bytes,
* we sometimes use |= * we sometimes use |=
@ -998,13 +1001,13 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
next_hdr = NULL; next_hdr = NULL;
break; break;
default: default:
LOG_INFO("Error - could not handle compression of header"); LOG_ERR("IPHC: could not handle compression of header");
} }
} }
if(next_hdr != NULL) { if(next_hdr != NULL) {
/* Last header could not be compressed - we assume that this is then OK!*/ /* Last header could not be compressed - we assume that this is then OK!*/
/* as the last EXT_HDR should be "uncompressed" and have the next there */ /* as the last EXT_HDR should be "uncompressed" and have the next there */
LOG_INFO("Last header could not be compressed: %d\n", *next_hdr); LOG_INFO("IPHC: last header could is not compressed: %d\n", *next_hdr);
} }
/* before the packetbuf_hdr_len operation */ /* before the packetbuf_hdr_len operation */
PACKETBUF_IPHC_BUF[0] = iphc0; PACKETBUF_IPHC_BUF[0] = iphc0;
@ -1197,7 +1200,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
/* The next header is compressed, NHC is following */ /* The next header is compressed, NHC is following */
last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto; last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf); ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
while(nhc && (*hc06_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) { while(nhc && (*hc06_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
uint8_t eid = (*hc06_ptr & 0x0e) >> 1; uint8_t eid = (*hc06_ptr & 0x0e) >> 1;
/* next header compression flag */ /* next header compression flag */
@ -1341,8 +1344,54 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
} }
} }
/** @} */ /** @} */
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ #endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_HC06 */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_PAGE1
/*--------------------------------------------------------------------*/
/**
* \brief Adds Paging dispatch byte
*/
static void
add_paging_dispatch(uint8_t page)
{
/* Add paging dispatch to Page 1 */
PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
packetbuf_hdr_len++;
}
/*--------------------------------------------------------------------*/
/**
* \brief Adds 6lorh headers before IPHC
*/
static void
add_6lorh_hdr(void)
{
/* 6LoRH is not implemented yet */
}
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_PAGE1 */
/*--------------------------------------------------------------------*/
/**
* \brief Digest 6lorh headers before IPHC
*/
static void
digest_paging_dispatch(void)
{
/* Is this a paging dispatch? */
if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
/* Parse page number */
curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
packetbuf_hdr_len++;
}
}
/*--------------------------------------------------------------------*/
/**
* \brief Digest 6lorh headers before IPHC
*/
static void
digest_6lorh_hdr(void)
{
/* 6LoRH is not implemented yet */
}
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \name IPv6 dispatch "compression" function /** \name IPv6 dispatch "compression" function
* @{ */ * @{ */
@ -1359,6 +1408,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* \endverbatim * \endverbatim
*/ */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
static void static void
compress_hdr_ipv6(linkaddr_t *link_destaddr) compress_hdr_ipv6(linkaddr_t *link_destaddr)
{ {
@ -1369,6 +1419,7 @@ compress_hdr_ipv6(linkaddr_t *link_destaddr)
uncomp_hdr_len += UIP_IPH_LEN; uncomp_hdr_len += UIP_IPH_LEN;
return; return;
} }
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */
/** @} */ /** @} */
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
@ -1479,17 +1530,21 @@ output(const uip_lladdr_t *localdest)
LOG_INFO("output: sending packet len %d\n", uip_len); LOG_INFO("output: sending packet len %d\n", uip_len);
if(uip_len >= COMPRESSION_THRESHOLD) { /* Try to compress the headers */
/* Try to compress the headers */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
compress_hdr_ipv6(&dest); compress_hdr_ipv6(&dest);
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */ #endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6 */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 #if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_PAGE1
compress_hdr_iphc(&dest); /* Add 6LoRH headers before IPHC. Only needed on routed traffic
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ (non link-local). */
} else { if(!uip_is_addr_linklocal(&UIP_IP_BUF->destipaddr)) {
compress_hdr_ipv6(&dest); add_paging_dispatch(1);
add_6lorh_hdr();
} }
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_PAGE1 */
#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_HC06
compress_hdr_iphc(&dest);
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_HC06 */
LOG_INFO("output: header of len %d\n", packetbuf_hdr_len); LOG_INFO("output: header of len %d\n", packetbuf_hdr_len);
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC. /* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC.
@ -1545,8 +1600,6 @@ output(const uip_lladdr_t *localdest)
* FRAG1 dispatch + header * FRAG1 dispatch + header
* Note that the length is in units of 8 bytes * Note that the length is in units of 8 bytes
*/ */
/* PACKETBUF_FRAG_BUF->dispatch_size = */
/* uip_htons((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len); */
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE, SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len)); ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len));
frag_tag = my_tag++; frag_tag = my_tag++;
@ -1695,18 +1748,15 @@ input(void)
* Since we don't support the mesh and broadcast header, the first header * Since we don't support the mesh and broadcast header, the first header
* we look for is the fragmentation header * we look for is the fragmentation header
*/ */
switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0xf800) >> 8) { switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
case SICSLOWPAN_DISPATCH_FRAG1: case SICSLOWPAN_DISPATCH_FRAG1:
LOG_INFO("input: FRAG1 "); LOG_INFO("input: FRAG1 ");
frag_offset = 0; frag_offset = 0;
/* frag_size = (uip_ntohs(PACKETBUF_FRAG_BUF->dispatch_size) & 0x07ff); */
frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff; frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
/* frag_tag = uip_ntohs(PACKETBUF_FRAG_BUF->tag); */
frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG); frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
LOG_INFO("size %d, tag %d, offset %d)\n", LOG_INFO("size %d, tag %d, offset %d)\n",
frag_size, frag_tag, frag_offset); frag_size, frag_tag, frag_offset);
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
/* printf("frag1 %d %d\n", reass_tag, frag_tag);*/
first_fragment = 1; first_fragment = 1;
is_fragment = 1; is_fragment = 1;
@ -1765,32 +1815,36 @@ input(void)
} }
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
/* Process next dispatch and headers */ /* First, process 6LoRH headers */
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 curr_page = 0;
if((PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH] & 0xe0) == SICSLOWPAN_DISPATCH_IPHC) { digest_paging_dispatch();
LOG_INFO("input: IPHC\n"); if(curr_page == 1) {
uncompress_hdr_iphc(buffer, frag_size); LOG_INFO("input: page 1, 6LoRH\n");
} else digest_6lorh_hdr();
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_HC06 */ } else if (curr_page > 1) {
switch(PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]) { LOG_ERR("input: page %u not supported\n", curr_page);
case SICSLOWPAN_DISPATCH_IPV6: return;
LOG_INFO("input: IPV6\n");
packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
/* Put uncompressed IP header in sicslowpan_buf. */
memcpy(buffer, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN);
/* Update uncomp_hdr_len and packetbuf_hdr_len. */
packetbuf_hdr_len += UIP_IPH_LEN;
uncomp_hdr_len += UIP_IPH_LEN;
break;
default:
/* unknown header */
LOG_ERR("input: unknown dispatch: %u\n",
PACKETBUF_HC1_PTR[PACKETBUF_HC1_DISPATCH]);
return;
} }
/* Process next dispatch and headers */
if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
LOG_INFO("input: IPHC\n");
uncompress_hdr_iphc(buffer, frag_size);
} else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
LOG_INFO("input: IPV6\n");
packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
/* Put uncompressed IP header in sicslowpan_buf. */
memcpy(buffer, packetbuf_ptr + packetbuf_hdr_len, UIP_IPH_LEN);
/* Update uncomp_hdr_len and packetbuf_hdr_len. */
packetbuf_hdr_len += UIP_IPH_LEN;
uncomp_hdr_len += UIP_IPH_LEN;
} else {
LOG_ERR("input: unknown dispatch: 0x%02x\n",
PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH]);
return;
}
#if SICSLOWPAN_CONF_FRAG #if SICSLOWPAN_CONF_FRAG
copypayload: copypayload:

View File

@ -68,9 +68,11 @@
* \name 6lowpan compressions * \name 6lowpan compressions
* @{ * @{
*/ */
#define SICSLOWPAN_COMPRESSION_IPV6 0 #define SICSLOWPAN_COMPRESSION_IPV6 0 /* No compression */
#define SICSLOWPAN_COMPRESSION_HC1 1 /* No longer supported: #define SICSLOWPAN_CONF_COMPRESSION_HC1 1*/
#define SICSLOWPAN_COMPRESSION_HC06 2 #define SICSLOWPAN_COMPRESSION_HC06 2 /* RFC 6282 */
#define SICSLOWPAN_COMPRESSION_PAGE1 3 /* RFC 8025 for paging dispatch,
* draft-ietf-6lo-routin-dispatch-05 for 6LoRH */
/** @} */ /** @} */
/** /**
@ -80,8 +82,12 @@
#define SICSLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */ #define SICSLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */
#define SICSLOWPAN_DISPATCH_HC1 0x42 /* 01000010 = 66 */ #define SICSLOWPAN_DISPATCH_HC1 0x42 /* 01000010 = 66 */
#define SICSLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */ #define SICSLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */
#define SICSLOWPAN_DISPATCH_IPHC_MASK 0xe0
#define SICSLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */ #define SICSLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */
#define SICSLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */ #define SICSLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */
#define SICSLOWPAN_DISPATCH_FRAG_MASK 0xf8
#define SICSLOWPAN_DISPATCH_PAGING 0xf0 /* 1111xxxx */
#define SICSLOWPAN_DISPATCH_PAGING_MASK 0xf0
/** @} */ /** @} */
/** \name HC1 encoding /** \name HC1 encoding

View File

@ -360,7 +360,7 @@
#ifdef RPL_CONF_DEFAULT_INSTANCE #ifdef RPL_CONF_DEFAULT_INSTANCE
#define RPL_DEFAULT_INSTANCE RPL_CONF_DEFAULT_INSTANCE #define RPL_DEFAULT_INSTANCE RPL_CONF_DEFAULT_INSTANCE
#else #else
#define RPL_DEFAULT_INSTANCE 0x1e #define RPL_DEFAULT_INSTANCE 0 /* Default of 0 for compression */
#endif /* RPL_CONF_DEFAULT_INSTANCE */ #endif /* RPL_CONF_DEFAULT_INSTANCE */
/* Set to have the root advertise a grounded DAG */ /* Set to have the root advertise a grounded DAG */