198 lines
7.4 KiB

\addtogroup uip
* \defgroup sicslowpan 6LoWPAN implementation
* @{
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 <em>Transmission of IPv6
Packets over IEEE 802.15.4 Networks</em>, draft-hui-6lowpan-interop-00
<em>Interoperability Test for 6LoWPAN</em>, and draft-hui-6lowpan-hc-01
<em>Compression format for IPv6 datagrams in 6lowpan Networks</em>.
\section drafts Specifications implemented
\note We currently only support 802.15.4 64-bit addresses.
\subsection rfc4944 RFC 4944
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
\subsection RFC 6282
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.
\section general Implementation overview
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.
\section implementation Implementation details
\subsection Addressing
<b>Link-layer addresses</b><br>
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
<b>Neighbor Discovery Link Layer Address options </b><br>
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.
<b>Address Autoconfiguration</b><br>
The address autoconfiguration mechanism also depends on the format of
the link-layer address. The dependency is reflected in the
#uip_ds6_set_addr_iid function in uip-ds6.c.
#if (UIP_LLADDR_LEN == 8)
memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
ipaddr->u8[8] ^= 0x02;
\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
function is set as the tcpip_output function.<br>
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_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.
\subsection frag Fragmentation
\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
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
\note Fragmentation support is enabled by setting the #SICSLOWPAN_CONF_FRAG
compilation option.
\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.
\note #MAC_MAX_PAYLOAD defines the maximum payload
length in a 802.15.4 frame. For now it is constant and equal to 102
bytes (the 802.15.4 frame can be maximum 127 bytes long, and
the header 25 bytes long).
\subsection hc Header Compression
<b>Compression schemes</b><br>
The #SICSLOWPAN_CONF_COMPRESSION compilation option defines the
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.<br>
If at compile time IPv6 "compression" is chosen, packets sent will never
be compressed, and compressed packets will not be processed at reception.<br>
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.<br>.
<b>Compression related functions</b><br>
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 IPHC, the decompression function
(uncompress_hdr_iphc) is called.<br>
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 IPHC support is enabled, we call the
corresponding compression function (compress_hdr_iphc)
to compress the packet as much as possible.
<b>IPHC comments</b><br>
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 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 implemented.<br>
Until then, if you want to test global address compression, you need
to configure the global contexts manually.
/** @} */
/** @} */