dd {
margin-bottom: 0.5em }
-/* Uncomment (& remove this text!) to get bold-faced definition list terms
-dt {
- font-weight: bold }
-*/
-
div.abstract {
margin: 2em 5em }
<td>David Moss, Jonathan Hui, Philip Levis, and Jung Il Choi</td></tr>
<tr class="field"><th class="docinfo-name">Draft-Created:</th><td class="field-body">5-Mar-2007</td>
</tr>
-<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.1</td>
+<tr class="field"><th class="docinfo-name">Draft-Version:</th><td class="field-body">1.5</td>
</tr>
-<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2007-03-23</td>
+<tr class="field"><th class="docinfo-name">Draft-Modified:</th><td class="field-body">2007-06-14</td>
</tr>
<tr class="field"><th class="docinfo-name">Draft-Discuss:</th><td class="field-body">TinyOS Developer List <tinyos-devel at mail.millennium.berkeley.edu></td>
</tr>
details of the CC2420 stack will be discussed. Readers will be better
informed about existing features, possible improvements, and limitations
of the CC2420 radio stack. Furthermore, lessons learned from
-the construction of the CC2420 radio stack can help guide development
+the construction of the stack can help guide development
of future TinyOS radio stacks.</p>
</div>
<div class="section">
<h1><a id="introduction" name="introduction">1. Introduction</a></h1>
-<p>The TI/Chipcon CC2420 radio is a complex device, requiring a rather
-complex software radio stack implementation. Although much of the
-functionality is available within the radio chip itself, there are
-still many factors to consider when implementing a flexible,
+<p>The TI/Chipcon CC2420 radio is a complex device, taking care of
+many of the low-level details of transmitting and receiving packets
+through hardware. Specifying the proper behavior of that hardware
+requires a well defined radio stack implementation. Although much
+of the functionality is available within the radio chip itself, there
+are still many factors to consider when implementing a flexible,
general radio stack.</p>
<p>The software radio stack that drives the CC2420 radio consists of
many layers that sit between the application and hardware. The highest
// Send Layers
AM.SubSend -> UniqueSendC;
-UniqueSendC.SubSend -> TransportC;
-TransportC.SubSend -> LplC.Send;
-LplC.SubSend -> CC2420DispatchC.Send;
-CC2420DispatchC.SubSend -> CsmaC;
+UniqueSendC.SubSend -> LinkC;
+LinkC.SubSend -> LplC.Send;
+LplC.SubSend -> TinyosNetworkC.Send;
+TinyosNetworkC.SubSend -> CsmaC;
// Receive Layers
AM.SubReceive -> LplC;
-LplC.SubReceive -> UniqueReceiveC;
-UniqueReceiveC.SubReceive -> CC2420DispatchC.Receive;
-CC2420DispatchC.SubReceive -> CsmaC;
+LplC.SubReceive -> UniqueReceiveC.Receive;
+UniqueReceiveC.SubReceive -> TinyosNetworkC.Receive;
+TinyosNetworkC.SubReceive -> CsmaC;
</pre>
<p>If another layer were to be added, CC2420ActiveMessageC would need
to be modified to wire it into the correct location.</p>
</div>
<div class="section">
<h2><a id="layer-descriptions" name="layer-descriptions">2.1 Layer Descriptions</a></h2>
-<p>The main layers we see in this version of the stack are:</p>
-<ul class="simple">
-<li>ActiveMessageP: This is the highest layer in the stack, responsible
+<p>The layers found within this radio stack are in the following order:</p>
+<ul>
+<li><p class="first">ActiveMessageP: This is the highest layer in the stack, responsible
for filling in details in the packet header and providing information
about the packet to the application level <a class="footnote-reference" href="#id12" id="id2" name="id2">[2]</a>. Because the CC2420 radio
chip itself uses 802.15.4 headers in hardware <a class="footnote-reference" href="#id11" id="id3" name="id3">[1]</a>, it is not possible
-for the layer to rearrange header bytes.</li>
-<li>UniqueSend: This layer generates a unique data sequence
-number (DSN) byte for the packet header. This byte is generated once
-per outgoing packet. A receiver can detect duplicate packets by comparing
+for the layer to rearrange header bytes.</p>
+</li>
+<li><p class="first">UniqueSend: This layer generates a unique Data Sequence
+Number (DSN) byte for the packet header. This byte is incremented once
+per outgoing packet, starting with a pseudo-randomly generated number.
+A receiver can detect duplicate packets by comparing
the source and DSN byte of a received packet with previous packets.
-DSN is defined in the 802.15.4 specification <a class="footnote-reference" href="#id13" id="id4" name="id4">[3]</a>.</li>
-<li>MessageTransportP: This layer provides the MessageTransport
-interface, and is responsible for retrying a packet transmission if no
-acknowledgement was heard from the receiver. MessageTransport is
+DSN is defined in the 802.15.4 specification <a class="footnote-reference" href="#id13" id="id4" name="id4">[3]</a>.</p>
+</li>
+<li><p class="first">PacketLink: This layer provides automatic retransmission functionality
+and is responsible for retrying a packet transmission if no
+acknowledgement was heard from the receiver. PacketLink is
activated on a per-message basis, meaning the outgoing packet will
-not use MessageTransport unless it is configured ahead of time to do so.
-MessageTransport is most reliable when software acknowledgements are enabled,
-as opposed to hardware auto acknowledgements.</li>
-<li>LowPowerListeningP <a class="footnote-reference" href="#id14" id="id5" name="id5">[4]</a>: This layer provides the asynchronous low
-power listening functionality of the radio. It is broken up into
-two parts: CC2420LowPowerListeningP and CC2420DutyCycleP. The
-DutyCycleP component is responsible for turning the radio on
-and off and performing detections. After a detection occurs,
-DutyCycleP is hands off responsibility to LowPowerListeningP to turn
-the radio off and continue duty cycling when convenient. Low power listening
-transmissions are activated on a per-message basis, and the layer
-will retransmit the full outbound packet over and over until either a
-response from the receiver is heard or the transmit time expires.</li>
-<li>UniqueReceive: This layer maintains a history of the source address
+not use PacketLink unless it is configured ahead of time to do so.
+PacketLink is most reliable when software acknowledgements are enabled
+as opposed to hardware auto acknowledgements.</p>
+</li>
+<li><p class="first">CC2420AckLplP / CC2420NoAckLplP <a class="footnote-reference" href="#id14" id="id5" name="id5">[4]</a>: These layers provide
+asynchronous low power listening implementations. Supporting both of them
+is CC2420DutyCycleP. The DutyCycleP component is responsible for
+turning the radio on and off and performing receive checks.
+After a detection occurs, DutyCycleP is hands off responsibility to
+LowPowerListeningP to perform some transaction and turn the radio off
+when convenient. Low power listening transmissions are activated on
+a per-message basis, and the layer will continuously retransmit the full outbound
+packet until either a response from the receiver is heard or the
+transmit time expires.</p>
+<p>The AckLplP implementation supports acknowledgement gaps during the
+low power listening packetized preamble, which allows
+transmitters to stop early but penalizes receive check lengths.
+AckLplP low power listening is optimal for high transmission, long
+receive check interval networks.</p>
+<p>The NoAckLplP implementation does not support acknowledgements during
+the packetized preamble. It continuously modulates the channel,
+allowing the receiver to perform the smallest possible receive check.
+NoAckLpl low power listening is effective for low transmission, short
+receive check interval networks.</p>
+</li>
+<li><p class="first">UniqueReceive: This layer maintains a history of the source address
and DSN byte of the past few packets it has received, and helps
-filter out duplicate received packets.</li>
-<li>DispatchC: This layer allows the TinyOS 2.x radio stack to interoperate
-with other non-TinyOS networks. The 6LowPAN specifications include
-a network identifier byte after the standard 802.15.4 header <a class="footnote-reference" href="#id15" id="id6" name="id6">[5]</a>.
-If interoperability frames are used, the dispatch layer provides
-functionality for setting the network byte on outgoing packets
-and filtering non-TinyOS incoming packets.</li>
-<li>CsmaC: This layer is responsible for defining 802.15.4 FCF
+filter out duplicate received packets.</p>
+</li>
+<li><p class="first">TinyosNetworkC: This layer allows the TinyOS 2.x radio stack to
+interoperate with other non-TinyOS networks. Proposed 6LowPAN
+specifications include a network identifier byte after the
+standard 802.15.4 header <a class="footnote-reference" href="#id15" id="id6" name="id6">[5]</a>. If interoperability frames are
+used, the dispatch layer provides functionality for setting
+the network byte on outgoing packets and filtering non-TinyOS
+incoming packets.</p>
+</li>
+<li><p class="first">CsmaC: This layer is responsible for defining 802.15.4 FCF
byte information in the outbound packet, providing default
backoff times when the radio detects a channel in use, and
-defining the power-up/power-down procedure for the radio.</li>
-<li>TransmitP/ReceiveP: These layers are responsible for interacting
-directly with the radio through the SPI bus, interrupts, and GPIO lines.</li>
+defining the power-up/power-down procedure for the radio.</p>
+</li>
+<li><p class="first">TransmitP/ReceiveP: These layers are responsible for interacting
+directly with the radio through the SPI bus, interrupts, and GPIO lines.</p>
+</li>
</ul>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Application Layer</td>
+</tr>
+</tbody>
+</table>
+<blockquote>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Active Message Layer</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Unique Send Layer</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Optional Packet Link Layer</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Optional Low Power Listening Implementations</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Unique Receive Filtering Layer</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Optional 6LowPAN TinyOS Network Layer</td>
+</tr>
+</tbody>
+</table>
+<table border="1" class="docutils">
+<colgroup>
+<col width="47%" />
+<col width="53%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">Carrier Sense Multiple Access (CSMA)</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<p>+----------+----------+ +----------+----------+
+| ReceiveP | | TransmitP |
++----------+----------+ +----------+----------+</p>
+<table border="1" class="docutils">
+<colgroup>
+<col width="48%" />
+<col width="52%" />
+</colgroup>
+<tbody valign="top">
+<tr><td colspan="2">SPI bus, GPIO, Interrupts, Timer Capture</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
</div>
</div>
<div class="section">
nxle_uint16_t destpan;
nxle_uint16_t dest;
nxle_uint16_t src;
- nxle_uint8_t network;
+ nxle_uint8_t network; // optionally included with 6LowPAN layer
nxle_uint8_t type;
} cc2420_header_t;
</pre>
<p>All fields up to 'network' are 802.15.4 specified fields, and are
used in the CC2420 hardware itself. The 'network' field is a 6LowPAN
-interoperability specification <a class="footnote-reference" href="#id15" id="id7" name="id7">[5]</a>. The 'type' field is a
+interoperability specification <a class="footnote-reference" href="#id15" id="id7" name="id7">[5]</a> only to be included when the
+6LowPAN TinyosNetwork layer is included. The 'type' field is a
TinyOS specific field.</p>
<p>The TinyOS T-Frame packet does not include the 'network' field, nor
the functionality found in the Dispatch layer to set and check
<p>No software footer is defined for the CC2420 radio. A 2-byte
CRC byte is auto-appended to each outbound packet by the CC2420 radio
hardware itself.</p>
-<p>The CC2420 hardware has three RAM buffers: TXFIFO, RXFIFO, and a
-security RAM buffer. The TXFIFO and RXFIFO are both 128 bytes,
-while the security RAM buffer is 112 bytes. Therefore, the maximum size
-of a packet is 128 bytes including its headers and CRC. Increasing
-the packet size will increase data throughput and RAM consumption
+<p>The maximum size of a packet is 128 bytes including its headers and
+CRC, which matches the 802.15.4 specifications. Increasing the
+packet size will increase data throughput and RAM consumption
in the TinyOS application, but will also increase the probability
that interference will cause the packet to be destroyed and need
-to be retransmitted, which wastes energy. The TOSH_DATA_LENGTH
-preprocessor variable can be altered to increase the size
-of the message_t payload at compile time <a class="footnote-reference" href="#id12" id="id8" name="id8">[2]</a>.</p>
+to be retransmitted. The TOSH_DATA_LENGTH preprocessor variable can
+be altered to increase the size of the message_t payload at
+compile time <a class="footnote-reference" href="#id12" id="id8" name="id8">[2]</a>.</p>
</div>
<div class="section">
<h1><a id="csma-ca" name="csma-ca">4. CSMA/CA</a></h1>
again. The CC2420 chip itself provides a strobe command to transmit
the packet if the channel is currently clear.</p>
<p>To specify whether or not to transmit with clear channel assessment,
-the CC2420TransmitP component provides two commands:</p>
-<pre class="literal-block">
-async command error_t Send.sendCCA( message_t* p_msg )
-async command error_t Send.send( message_t* p_msg )
-</pre>
-<p>It is up to the CC2420CsmaP component to select the correct method of
-transmission. Sending a packet without CCA will transmit it as quickly
-as possible, but interference from other transmitters will prevent
-it from being delivered in many cases. Transmitting without CCA will
-also effectively jam other DSSS transmitters on the same channel.</p>
-<p>Future implementations should allow the application layer to specify
-the use of CCA on a per-packet basis, similar to how the application
-layer has the option to specify the backoff period for an outgoing
-message.</p>
+the CC2420TransmitP requests CCA backoff input through the RadioBackoff
+interface on a per-message basis. By default, each packet will be
+transmitted with CCA enabled.</p>
+<p>If layers above the CSMA layer wish to disable the clear channel
+assessments before transmission, they must intercept the
+RadioBackoff.requestCca(...) event for that message and call back
+using RadioBackoff.setCca(FALSE).</p>
</div>
<div class="section">
<h2><a id="radio-backoff" name="radio-backoff">4.2 Radio Backoff</a></h2>
and UniqueReceive interfaces, dropped acknowledgements are more desirable
than false acknowledgements. Received packets are always acknowledged
before being filtered as a duplicate.</p>
-<p>Use the PacketAcknowledgements or MessageTransport interfaces
+<p>Use the PacketAcknowledgements or PacketLink interfaces
to determine if a packet was successfully acknowledged.</p>
</div>
<div class="section">
<p>The 802.15.4 specification identifies a Data Sequence Number (DSN)
byte in the message header to filter out duplicate packets <a class="footnote-reference" href="#id13" id="id9" name="id9">[3]</a>.</p>
<p>The UniqueSend interface at the top of the CC2420 radio stack is
-responsible for setting the DSN byte. It is set exactly one time
-per outgoing message. Even if lower levels such as MessageTransport
-or LowPowerListening retransmit the packet, the DSN byte stays the
-same.</p>
+responsible for setting the DSN byte. Upon boot, an initial DSN
+byte is generated using a pseudo-random number generator with a
+maximum of 8-bits (256) values. This number is incremented on
+each outgoing packet transmission. Even if lower levels such as
+PacketLink or LowPowerListening retransmit the packet, the DSN byte
+stays the same for that packet.</p>
<p>The UniqueReceive interface at the bottom of the CC2420 radio stack
is responsible for filtering out duplicate messages based on
source address and DSN. The UniqueReceive interface is not meant
-to stop sophisticated replay attacks.</p>
+to stop sophisticated replay attacks. '</p>
+<p>As packets are received, DSN and source address information is placed
+into elements of an array. Each subsequent message from previously
+logged addresses overwrite information in the element allocated to
+that source address. This prevents UniqueReceive's history from
+losing DSN byte information from sources that are not able to access
+the channel as often. If the number of elements in the history array
+runs out, UniqueReceive uses a best effort method to avoid replacing
+recently updated DSN/Source information entries.</p>
</div>
</div>
<div class="section">
-<h1><a id="message-transport-implementation" name="message-transport-implementation">6. Message Transport Implementation</a></h1>
-<p>Message transport is a layer added to the CC2420 radio stack to help unicast
+<h1><a id="packetlink-implementation" name="packetlink-implementation">6. PacketLink Implementation</a></h1>
+<p>PacketLink is a layer added to the CC2420 radio stack to help unicast
packets get delivered successfully. In previous version of TinyOS radio
stacks, it was left up to the application layer to retry a message
transmission if the application determined the message was not properly
-received. The Message Transport layer helps to remove the reliable delivery
+received. The PacketLink layer helps to remove the reliable delivery
responsibility and functional baggage from application layers.</p>
<div class="section">
-<h2><a id="compiling-in-the-message-transport-layer" name="compiling-in-the-message-transport-layer">6.1 Compiling in the Message Transport layer</a></h2>
-<p>Because the Message Transport layer uses up extra memory footprint,
+<h2><a id="compiling-in-the-packetlink-layer" name="compiling-in-the-packetlink-layer">6.1 Compiling in the PacketLink layer</a></h2>
+<p>Because the PacketLink layer uses up extra memory footprint,
it is not compiled in by default. Developers can simply define
-the preprocessor variable MESSAGE_TRANSPORT to compile the functionality
-of the Message Transport layer in with the CC2420 stack.</p>
+the preprocessor variable PACKET_LINK to compile the functionality
+of the PacketLink layer in with the CC2420 stack.</p>
</div>
<div class="section">
<h2><a id="implementation-and-usage" name="implementation-and-usage">6.2 Implementation and Usage</a></h2>
-<p>To send a message using Message Transport, the MessageTransport
+<p>To send a message using PacketLink, the PacketLink
interface must be called ahead of time to specify two fields in the outbound
message's metadata::</p>
<pre class="literal-block">
the amount of delay in milliseconds between each retry. The combination
of these two commands can set a packet to retry as many times as needed
for as long as necessary.</p>
-<p>Because Message Transport relies on acknowledgements, false
-acknowledgements from the receiver will cause Message Transport to fail.</p>
+<p>Because PacketLink relies on acknowledgements, false acknowledgements
+from the receiver will cause PacketLink to fail. If using software
+acknowledgements, false acknowledgements can still occur as a result
+of the limited DSN space, other 802.15.4 radios in the area with
+the same destination address, etc.</p>
</div>
</div>
<div class="section">
keep its radio on.</p>
<p>Typically, the transmission of a single packet takes on the following
form over time:</p>
+<blockquote>
<table border="1" class="docutils">
<colgroup>
-<col width="22%" />
-<col width="62%" />
-<col width="16%" />
+<col width="42%" />
+<col width="21%" />
+<col width="38%" />
</colgroup>
<tbody valign="top">
<tr><td>LPL Backoff</td>
-<td>Packet Transmission</td>
+<td>Packet Tx</td>
<td>Ack Wait</td>
</tr>
</tbody>
</table>
+</blockquote>
<p>To decrease the amount of time required for a receive check, the channel
must be modulated by the transmitter as continuously as possible.
The only period where the channel is modulated is during the
<h2><a id="minimizing-power-consumption" name="minimizing-power-consumption">7.2 Minimizing Power Consumption</a></h2>
<p>There are several methods the CC2420 radio stack uses to minimize
power consumption:</p>
+<ol class="arabic simple">
+<li>Invalid Packet Shutdown</li>
+</ol>
<blockquote>
-<p>1. <em>Invalid Packet Shutdown:</em>
Typically, packets are filtered out by address at the radio hardware
level. When a receiver wakes up and does not receive any
packets into the low power listening layer of the radio stack, it
the low power listening implementation will shut down the radio if
three packets are receive that do not belong to the node. This helps
prevent against denial of sleep attacks or the typical transmission
-behavior found in an ad-hoc network with many nodes.</p>
-<p>2. <em>Early Transmission Completion:</em>
+behavior found in an ad-hoc network with many nodes.</blockquote>
+<ol class="arabic simple" start="2">
+<li>Early Transmission Completion</li>
+</ol>
+<blockquote>
A transmitter typically sends a packet for twice the amount of time
as the receiver's receive check period. This increases the probability
that the receiver will detect the packet. However, if the transmitter receives
will stop transmitting to save energy. This is an improvement
over previous low power listening implementations, which transmitted
for the full period of time regardless of whether the receiver has
-already woken up and received the packet.</p>
-<p>3. <em>Auto Shutdown:</em>
+already woken up and received the packet.</blockquote>
+<ol class="arabic simple" start="3">
+<li>Auto Shutdown</li>
+</ol>
+<blockquote>
If the radio does not send or receive messages for some period of
time while low power listening is enabled, the radio will automatically
-turn off and begin duty cycling at its specified duty cycle period.</p>
-<p>4. <em>CCA Sampling Strategy:</em>
+turn off and begin duty cycling at its specified duty cycle period.</blockquote>
+<ol class="arabic simple" start="4">
+<li>CCA Sampling Strategy</li>
+</ol>
+<blockquote>
The actual receive check is performed in a loop inside a function,
not a spinning task. This allows the sampling to be performed
continuously, with the goal of turning the radio off as quickly as
-possible without interruption.</p>
-</blockquote>
+possible without interruption.</blockquote>
</div>
</div>
<div class="section">
is the place to add access to it.</p>
<p>Configuring the CC2420 requires the developer to access the CC2420Config
interface provided by CC2420ControlC. First call the CC2420Config commands to
-change the desired settings of the radio. Next, call CC2420Config.sync()
-to commit these changes to the radio chip. If the radio is currently
-off, the changes will be committed at the time it is turned on.</p>
+change the desired settings of the radio. If the radio happens to
+be off, the changes will be committed at the time it is turned on.
+Alternatively, calling sync() will commit the changes to the CC2420.</p>
<p>RSSI can be sampled directly by calling the ReadRssi interface provided
by CC2420ControlC. See page 50 of the CC2420 datasheet for information
on how to convert RSSI to LQI and why it may not be such a good idea <a class="footnote-reference" href="#id11" id="id10" name="id10">[1]</a>.</p>
</div>
<div class="section">
<h2><a id="neighbor-tables" name="neighbor-tables">10.4 Neighbor Tables</a></h2>
-<p>Moteiv's Boomerange Sensornet Protocol (SP) implementation is a very
+<p>Moteiv's Boomerange Sensornet Protocol (SP) implementation is a
good model to follow for radio stack architecture. One of the nice features
of SP is the design and implementation of the neighbor table. By
providing and sharing neighbor table information across the entire
Many of the layers in the CC2420 stack can be implemented independant
of the hardware underneath if the radio stack architecture was redesigned
and reimplemented. The low power listening receive check strategy may need a
-hardware-dependant implementation, but other layers like MessageTransport,
+hardware-dependant implementation, but other layers like PacketLink,
UniqueSend, UniqueReceive, ActiveMessage, Dispatch, etc. do not require
a CC2420 underneath to operate properly. The ultimate TinyOS radio
stack would be one that forms an abstraction between radio-dependant
<div class="section">
<h2><a id="extendable-metadata" name="extendable-metadata">10.6 Extendable Metadata</a></h2>
<p>Layers added into the radio stack may require extra bytes of metadata.
-The MessageTransport layer, for example, requires two extra fields
+The PacketLink layer, for example, requires two extra fields
in each message's metadata to hold the message's max retries and
delay between retries. The low power listening layer requires
an extra field to specify the destination's duty cycle period for