mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-09-01 17:29:13 +00:00
198 lines
7.4 KiB
Plaintext
198 lines
7.4 KiB
Plaintext
/**
|
|
\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>.
|
|
|
|
<HR>
|
|
|
|
\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
|
|
techniques.
|
|
|
|
\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.
|
|
|
|
<HR>
|
|
|
|
\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.
|
|
|
|
<HR>
|
|
|
|
\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.
|
|
\code
|
|
/** \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
|
|
\endcode
|
|
|
|
<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.
|
|
\code
|
|
#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
|
|
\endcode
|
|
|
|
<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.
|
|
\code
|
|
#if (UIP_LLADDR_LEN == 8)
|
|
memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
|
|
ipaddr->u8[8] ^= 0x02;
|
|
\endcode
|
|
|
|
\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.
|
|
\code
|
|
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);
|
|
\endcode
|
|
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
|
|
#SICSLOWPAN_REASS_MAXAGE = 20s.
|
|
|
|
\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.
|
|
|
|
<HR>
|
|
|
|
*/
|
|
/** @} */
|
|
/** @} */
|