The memo documents the interfaces used by packet protocol components in
TinyOS 2.x as well as the structure and implementation of ActiveMessageC,
the basic data-link HIL component. It also documents the virtualized
-active message interfaces AMSender and AMReceiver.
+active message interfaces AMSenderC and AMReceiverC.
1. Introduction
============================================================================
*Packet* interfaces are for accessing message fields and payloads.
*Send* interfaces are for transmitting packets, and are
distinguished by their addressing scheme.
-Finally, the *Receive* interface is for handling packet reception events.
+The *Receive* interface is for handling packet reception events.
+Finally, depending on whether the protocol has a dispatch identifier
+field, the Receive and Send interfaces may be parameterized in order
+to support multiple higher-level clients.
2.1 Packet interfaces
--------------------------------------------------------------------
sending, and so is never called in common use cases. Instead,
it is a way for queues and other packet buffering components
to store the full state of a packet without requiring additional
-memory allocation.
+memory allocation.
The distinction between ``payloadLength`` and ``maxPayloadLength``
comes from whether the packet is being received or sent. In the receive
The command address() returns the local AM address of the
node. AMPacket provides accessors for its two fields, destination and
-type. It does not provide commands to set these fields, as they are
-set in the sending call path (see Section 2.3). The ``setDestination``
-and ``setType`` commands fulfill a similar purpose to
-``Packet.setLength``.
+type. It also provides commands to set these fields, for the same
+reason that Packet allows a caller to set the payload length.
+Packet interfaces SHOULD provide accessors
+and mutators for all of their fields to enable queues and other
+buffering to store values in a packet buffer. Typically, a component
+stores these values in the packet buffer itself (where the field is),
+but when necessary it may use the metadata region of message_t or other
+locations.
2.2 Sending interfaces
--------------------------------------------------------------------
NULL). Their inclusion is so that components do not have to wire to
both Packet and the sending interface for basic use cases.
+When called with a length that is too long for the underlying
+maximum transfer unit (MTU), the send command MUST return ESIZE.
+
+The ``Send`` and ``AMSend`` interfaces have an explicit queue of
+depth one. A call to ``send`` on either of these interfaces MUST
+return EBUSY if a prior call to ``send`` returned SUCCESS but no
+``sendDone`` event has been signaled yet. More explicitly::
+
+ if (call Send.send(...) == SUCCESS &&
+ call Send.send(...) == SUCCESS) {
+ // This block is unreachable.
+ }
+
+Systems that need send queues have two options. They can
+use a QueueC (found in tos/system) to store pending packet pointers
+and serialize them onto sending interface, or they can introduce
+a new sending interface that supports multiple pending transmissions.
+
+The cancel command allows a sender to cancel the current transmission.
+A call to cancel when there is no pending sendDone event MUST return FAIL.
+If there is a pending sendDone event and the cancel returns SUCCESS, then
+the packet layer MUST NOT transmit the packet and MUST signal sendDone
+with ECANCEL as its error code. If there is a pending sendDone event
+and cancel returns FAIL, then sendDone SHOULD occur as if the cancel
+was not called.
+
2.3 Receive interface
--------------------------------------------------------------------
A *user* of the Receive interface has three basic options when it
handles a receive event:
-1) Return ``msg`` without touching it.
-2) Copy some data out of ``payload`` and return ``msg``.
-3) Store ``msg`` in its local frame and return a different ``message_t*`` for the lower layer to use.
+ 1) Return ``msg`` without touching it.
+ 2) Copy some data out of ``payload`` and return ``msg``.
+ 3) Store ``msg`` in its local frame and return a different ``message_t*`` for the lower layer to use.
These are simple code examples of the three cases::
}
//Case 3
- message_t* ptr;
+ message_t buf;
+ message_t* ptr = &buf;
message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) {
message_t* tmp = ptr;
ptr = msg;
--------------------------------------------------------------------
A packet protocol MAY have a dispatch identifier. This generally manifests
-as the protocol component provided parameterized interfaces (rather than
-a single interface instances). A dispatch identifier allows multiple
+as the protocol component providing parameterized interfaces (rather than
+a single interface instance). A dispatch identifier allows multiple
services to use a protocol independently. If a protocol provides a
dispatch mechanism, then each dispatch identifier SHOULD correspond to
a single packet format: if an identifier corresponds to multiple packet
a certain am_id_t MUST NOT instantiate another AMSnoopingReceiverC,
AMSnooperC, or AMReceiverC with the same am_id_t.
-4.5 AMSender
+4.5 AMSenderC
--------------------------------------------------------------------
AMSenderC has the following signature::
packets receives a reasonable approximation of an equal share of the
available transmission bandwidth.
-4.6 Power Management
+5. Power Management and Local Address
+============================================================================
+
+In addition to standard datapath interfaces for sending and
+receiving packets, an active message layer also has control interfaces.
+
+
+5.1 Power Management
--------------------------------------------------------------------
The communication virtualizations do not support power management.
techniques, such as TDMA scheduling or low power listening, when
"on."
+5.2 Local Active Message Address
+--------------------------------------------------------------------
+
+An application can change ActiveMessageC's local AM address
+at runtime. This will change which packets a node receives and
+the source address it embeds in packets. To change the local AM
+address at runtime, a component can wire to the component
+``ActiveMessageAddressC``. This component only changes the
+AM address of the default radio stack (AMSenderC, etc.); if
+a radio has multiple stacks those may have other components
+for changing their addresses in a stack-specific fashion.
+
5. HAL Requirements
============================================================================
can be passed to another data link layer (e.g., the UART) without
shifting the data payload. This means that the ``message_header_t`` must
include all data needed for AM fields, which might introduce headers
-in addition to those of the data link. For example, this is the
-structure of the CC2420 header::
+in addition to those of the data link. For example, this is an example
+structure for a CC2420 (802.15.4) header::
typedef nx_struct cc2420_header_t {
nx_uint8_t length;