Contiki 2.6
|
6lowpan is a Working Group in IETF which defines the use of IPv6 on IEEE 802.15.4 links. More...
Data Structures | |
struct | sicslowpan_addr_context |
The header for fragments. More... | |
struct | sicslowpan_nh_compressor |
The structure of a next header compressor. More... | |
Files | |
file | sicslowpan.c |
6lowpan implementation (RFC4944 and draft-ietf-6lowpan-hc-06) | |
file | sicslowpan.h |
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01) | |
Defines | |
#define | DEBUG 0 |
FOR HC-06 COMPLIANCE TODO: -Add compression options to UDP, currently only supports both ports compressed or both ports elided. | |
#define | MAC_MAX_PAYLOAD 102 |
Size of the 802.15.4 payload (127byte - 25 for MAC header) | |
#define | COMPRESSION_THRESHOLD 0 |
Some MAC layers need a minimum payload, which is configurable through the SICSLOWPAN_CONF_MIN_MAC_PAYLOAD option. | |
#define | sicslowpan_buf uip_buf |
The buffer used for the 6lowpan processing is uip_buf. | |
Pointers in the rime buffer | |
#define | RIME_FRAG_PTR (rime_ptr) |
#define | RIME_FRAG_DISPATCH_SIZE 0 |
#define | RIME_FRAG_TAG 2 |
#define | RIME_FRAG_OFFSET 4 |
#define | RIME_IPHC_BUF ((uint8_t *)(rime_ptr + rime_hdr_len)) |
#define | RIME_HC1_PTR (rime_ptr + rime_hdr_len) |
#define | RIME_HC1_DISPATCH 0 |
#define | RIME_HC1_ENCODING 1 |
#define | RIME_HC1_TTL 2 |
#define | RIME_HC1_HC_UDP_PTR (rime_ptr + rime_hdr_len) |
#define | RIME_HC1_HC_UDP_DISPATCH 0 |
#define | RIME_HC1_HC_UDP_HC1_ENCODING 1 |
#define | RIME_HC1_HC_UDP_UDP_ENCODING 2 |
#define | RIME_HC1_HC_UDP_TTL 3 |
#define | RIME_HC1_HC_UDP_PORTS 4 |
#define | RIME_HC1_HC_UDP_CHKSUM 5 |
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]) |
#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]) |
#define | UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLIPH_LEN]) |
#define | UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN]) |
HC06 specific variables | |
const uint8_t | unc_llconf [] = {0x0f,0x28,0x22,0x20} |
const uint8_t | unc_ctxconf [] = {0x00,0x88,0x82,0x80} |
const uint8_t | unc_mxconf [] = {0x0f, 0x25, 0x23, 0x21} |
const uint8_t | llprefix [] = {0xfe, 0x80} |
General sicslowpan defines | |
#define | SICSLOWPAN_UDP_4_BIT_PORT_MIN 0xF0B0 |
#define | SICSLOWPAN_UDP_4_BIT_PORT_MAX 0xF0BF |
#define | SICSLOWPAN_UDP_8_BIT_PORT_MIN 0xF000 |
#define | SICSLOWPAN_UDP_8_BIT_PORT_MAX 0xF0FF |
6lowpan compressions | |
#define | SICSLOWPAN_COMPRESSION_IPV6 0 |
#define | SICSLOWPAN_COMPRESSION_HC1 1 |
#define | SICSLOWPAN_COMPRESSION_HC06 2 |
6lowpan dispatches | |
#define | SICSLOWPAN_DISPATCH_IPV6 0x41 |
#define | SICSLOWPAN_DISPATCH_HC1 0x42 |
#define | SICSLOWPAN_DISPATCH_IPHC 0x60 |
#define | SICSLOWPAN_DISPATCH_FRAG1 0xc0 |
#define | SICSLOWPAN_DISPATCH_FRAGN 0xe0 |
HC1 encoding | |
#define | SICSLOWPAN_HC1_NH_UDP 0x02 |
#define | SICSLOWPAN_HC1_NH_TCP 0x06 |
#define | SICSLOWPAN_HC1_NH_ICMP6 0x04 |
HC_UDP encoding (works together with HC1) | |
#define | SICSLOWPAN_HC_UDP_ALL_C 0xE0 |
IPHC encoding | |
#define | SICSLOWPAN_IPHC_FL_C 0x10 |
#define | SICSLOWPAN_IPHC_TC_C 0x08 |
#define | SICSLOWPAN_IPHC_NH_C 0x04 |
#define | SICSLOWPAN_IPHC_TTL_1 0x01 |
#define | SICSLOWPAN_IPHC_TTL_64 0x02 |
#define | SICSLOWPAN_IPHC_TTL_255 0x03 |
#define | SICSLOWPAN_IPHC_TTL_I 0x00 |
#define | SICSLOWPAN_IPHC_CID 0x80 |
#define | SICSLOWPAN_IPHC_SAC 0x40 |
#define | SICSLOWPAN_IPHC_SAM_00 0x00 |
#define | SICSLOWPAN_IPHC_SAM_01 0x10 |
#define | SICSLOWPAN_IPHC_SAM_10 0x20 |
#define | SICSLOWPAN_IPHC_SAM_11 0x30 |
#define | SICSLOWPAN_IPHC_SAM_BIT 4 |
#define | SICSLOWPAN_IPHC_M 0x08 |
#define | SICSLOWPAN_IPHC_DAC 0x04 |
#define | SICSLOWPAN_IPHC_DAM_00 0x00 |
#define | SICSLOWPAN_IPHC_DAM_01 0x01 |
#define | SICSLOWPAN_IPHC_DAM_10 0x02 |
#define | SICSLOWPAN_IPHC_DAM_11 0x03 |
#define | SICSLOWPAN_IPHC_DAM_BIT 0 |
#define | SICSLOWPAN_IPHC_ADDR_CONTEXT_LL 0 |
#define | SICSLOWPAN_IPHC_MCAST_RANGE 0xA0 |
LOWPAN_UDP encoding (works together with IPHC) | |
#define | SICSLOWPAN_NHC_UDP_MASK 0xF8 |
#define | SICSLOWPAN_NHC_UDP_ID 0xF0 |
#define | SICSLOWPAN_NHC_UDP_CHECKSUMC 0x04 |
#define | SICSLOWPAN_NHC_UDP_CHECKSUMI 0x00 |
#define | SICSLOWPAN_NHC_UDP_CS_P_00 0xF0 |
#define | SICSLOWPAN_NHC_UDP_CS_P_01 0xF1 |
#define | SICSLOWPAN_NHC_UDP_CS_P_10 0xF2 |
#define | SICSLOWPAN_NHC_UDP_CS_P_11 0xF3 |
The 6lowpan "headers" length | |
#define | SICSLOWPAN_IPV6_HDR_LEN 1 |
#define | SICSLOWPAN_HC1_HDR_LEN 3 |
#define | SICSLOWPAN_HC1_HC_UDP_HDR_LEN 7 |
#define | SICSLOWPAN_FRAG1_HDR_LEN 4 |
#define | SICSLOWPAN_FRAGN_HDR_LEN 5 |
Address compressibility test functions | |
#define | sicslowpan_is_iid_16_bit_compressable(a) |
check whether we can compress the IID in address 'a' to 16 bits. | |
#define | sicslowpan_is_mcast_addr_decompressable(a) |
check whether the 9-bit group-id of the compressed multicast address is known. | |
#define | sicslowpan_is_mcast_addr_compressable(a) |
check whether the 112-bit group-id of the multicast address is mappable to a 9-bit group-id It is true if the group is the all nodes or all routers group. | |
#define | sicslowpan_is_mcast_addr_compressable48(a) |
#define | sicslowpan_is_mcast_addr_compressable32(a) |
#define | sicslowpan_is_mcast_addr_compressable8(a) |
6lowpan is a Working Group in IETF which defines the use of IPv6 on IEEE 802.15.4 links.
Our implementation is based on RFC4944 Transmission of IPv6 Packets over IEEE 802.15.4 Networks, draft-hui-6lowpan-interop-00 Interoperability Test for 6LoWPAN, and draft-hui-6lowpan-hc-01 Compression format for IPv6 datagrams in 6lowpan Networks.
RFC4944 defines address configuration mechanisms based on 802.15.4 16-bit and 64-bit addresses, fragmentation of IPv6 packets below IP layer, IPv6 and UDP header compression, a mesh header to enable link-layer forwarding in a mesh under topology, and a broadcast header to enable broadcast in a mesh under topology.
We implement addressing, fragmentation, and header compression. We support the header compression scenarios defined in draft-hui-6lowpan-interop-00. This draft defines an interoperability scenario which was used between ArchRock and Sensinode implementations.
We do not implement mesh under related features, as we target route over techniques.
draft-hui-6lowpan-hc-01 defines a stateful header compression mechanism which should soon 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.
6lowpan does not run as a separate process. It is called by the MAC process when a 6lowpan packet is received, and by the tcpip process when an IPv6 packet needs to be sent.
It is initialized from the MAC process, which calls sicslowpan_init (giving as argument a pointer to the mac_driver structure).
The main 6lowpan functions are implemented in the sicslowpan.h and sicslowpan.c files. They are used to format packets between the 802.15.4 and the IPv6 layers.
6lowpan also creates a few IPv6 and link-layer dependencies which are detailed in the next section.
Link-layer addresses
The format of a 802.15.4 address is defined in uip.h.
/** \brief 64 bit 802.15.4 address */ struct uip_802154_shortaddr { uint8_t addr[2]; }; /** \brief 16 bit 802.15.4 address */ struct uip_802154_longaddr { uint8_t addr[8]; }; /** \brief 802.15.4 address */ typedef struct uip_802154_longaddr uip_lladdr_t; #define UIP_802154_SHORTADDR_LEN 2 #define UIP_802154_LONGADDR_LEN 8 #define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN
Neighbor Discovery Link Layer Address options
The format of ND link-layer address options depends on the length of the link-layer addresses. 802.15.4 specificities regarding link-layer address options are implemented in uip-nd6.h.
#define UIP_ND6_OPT_SHORT_LLAO_LEN 8 #define UIP_ND6_OPT_LONG_LLAO_LEN 16 #define UIP_ND6_OPT_LLAO_LEN UIP_ND6_OPT_LONG_LLAO_LEN
Address Autoconfiguration
The address autoconfiguration mechanism also depends on the format of the link-layer address. The dependency is reflected in the #uip_netif_addr_autoconf_set function in #uip-netif.c.
#if (UIP_LLADDR_LEN == 8)
memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
ipaddr->u8[8] ^= 0x02;
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 destination link-layer addresses as two rime addresses.
packetbuf_copyfrom(&rx_frame.payload, rx_frame.payload_length); 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);
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.
Compression schemes
The SICSLOWPAN_CONF_COMPRESSION compilation option defines the compression scheme supported. We support HC1, HC01, and IPv6 compression. HC1 and IPv6 compression are defined in RFC4944, HC01 in draft-hui-6lowpan-hc. 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 HC01 are 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 HC01 supports are mutually exclusive. HC01 should soon deprecate HC1.
Compression related functions
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 HC01, the corresponding decompression function (#uncompress_hdr_hc1 or #uncompress_hdr_hc01) 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 HC01 support is enabled, we call the corresponding compression function (#compress_hdr_hc1 or #compress_hdr_hc01) 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 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 context. Other contexts have to be distributed within the LoWPAN dynamically, by means of ND extensions yet to be defined.
Until then, if you want to test global address compression, you need to configure the global contexts manually.
#define COMPRESSION_THRESHOLD 0 |
Some MAC layers need a minimum payload, which is configurable through the SICSLOWPAN_CONF_MIN_MAC_PAYLOAD option.
Definition at line 176 of file sicslowpan.c.
#define DEBUG 0 |
FOR HC-06 COMPLIANCE TODO: -Add compression options to UDP, currently only supports both ports compressed or both ports elided.
-Verify TC/FL compression works
-Add stateless multicast option
Definition at line 72 of file sicslowpan.c.
#define sicslowpan_buf uip_buf |
The buffer used for the 6lowpan processing is uip_buf.
We do not use any additional buffer.
Definition at line 260 of file sicslowpan.c.
#define sicslowpan_is_iid_16_bit_compressable | ( | a | ) |
((((a)->u16[4]) == 0) && \ (((a)->u8[10]) == 0)&& \ (((a)->u8[11]) == 0xff)&& \ (((a)->u8[12]) == 0xfe)&& \ (((a)->u8[13]) == 0))
check whether we can compress the IID in address 'a' to 16 bits.
This is used for unicast addresses only, and is true if the address is on the format <PREFIX>::0000:00ff:fe00:XXXX NOTE: we currently assume 64-bits prefixes
Definition at line 239 of file sicslowpan.h.
#define sicslowpan_is_mcast_addr_decompressable | ( | a | ) |
(((*a & 0x01) == 0) && \ ((*(a + 1) == 0x01) || (*(a + 1) == 0x02)))
check whether the 9-bit group-id of the compressed multicast address is known.
It is true if the 9-bit group is the all nodes or all routers group.
a | is typed uint8_t * |
Definition at line 253 of file sicslowpan.h.