X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=doc%2Ftxt%2Ftep116.txt;h=50cfdcbd02c542d7d5a55ab79c66529774811073;hb=6f095cc416fe0a3ca3912e743603531430e1b55f;hp=6f0a6d1fd991397b45c086b6809abcc8b371482c;hpb=7b7d7ab1d1da6c7af305976f825bd69e649fb564;p=tinyos-2.x.git diff --git a/doc/txt/tep116.txt b/doc/txt/tep116.txt index 6f0a6d1f..50cfdcbd 100644 --- a/doc/txt/tep116.txt +++ b/doc/txt/tep116.txt @@ -5,15 +5,10 @@ Packet Protocols :TEP: 116 :Group: Core Working Group :Type: Documentary -:Status: Draft -:TinyOS-Version: 2.x +:Status: Final +:TinyOS-Version: > 2.1 :Author: Philip Levis -:Draft-Created: 10-Dec-2004 -:Draft-Version: $Revision$ -:Draft-Modified: $Date$ -:Draft-Discuss: TinyOS Developer List - .. Note:: This memo documents a part of TinyOS for the TinyOS Community, and @@ -122,39 +117,56 @@ The Packet interface defines this mechanism:: command uint8_t payloadLength(message_t* msg); command void setPayLoadLength(message_t* msg, uint8_t len); command uint8_t maxPayloadLength(); - command void* getPayload(message_t* msg, uint8_t* len); + command void* getPayload(message_t* msg, uint8_t len); } A component can obtain a pointer to its data region within a packet by -calling ``getPayload()`` the optional ``len`` argument is for also -obtaining the size of the data region. A provider of a Packet -interface MUST check if ``len`` is NULL and ignore it if it is. A -component can also obtain the size of the data region with a call to -``payloadLength``. - -A component can set the payload length with -``setPayLoadLength.`` As Send interfaces always include a length -parameter in their send call, this command is not required for -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. +calling ``getPayload()``. A call to this command includes the length +the caller requires. The command ``maxPayloadLength`` returns the +maximum length the payload can be: if the ``len`` parameter to +``getPayload`` is greater than the value ``maxPayloadLength`` would +return, ``getPayload`` MUST return NULL. + + +A component can set the payload length with ``setPayLoadLength.`` A +component can obtain the size of the data region of packet in use with +a call to ``payloadLength``. As Send interfaces always include a +length parameter in their send call, ``setPayLoadLength`` is not +required for 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. The distinction between ``payloadLength`` and ``maxPayloadLength`` -comes from whether the packet is being received or sent. In the receive -case, determining the size of the existing data payload is needed; -in the send case, a component needs to know how much data it can put -in the packet. - -The Packet interface assumes that headers have a fixed size. -It is difficult to return a pointer into the data region when its -position will only be known once the header values are bound. - -Generally, an incoming call to the Packet interface of a protocol -has an accompanying outgoing call to the Packet interface of the -component below it. The one exception to this is the data link -layer. For example, if there is a network that introduces -16-bit sequence numbers to packets, it might look like this:: +comes from whether the packet is being received or sent. In the +receive case, determining the size of the existing data payload is +needed; in the send case, a component needs to know how much data it +can put in the packet. By definition, the return value of +``payloadLength`` must be less than or equal to the return value of +``maxPayloadLength``. + +The Packet interface assumes that headers have a fixed size. It is +difficult to return a pointer into the data region when its position +will only be known once the header values are bound. + +The ``clear`` command clears out all headers, footers, and metadata +for lower layers. For example, calling ``clear`` on a routing +component, such as CollectionSenderC[4]_, will clear out the +collection headers and footers. Furthermore, CollectionSenderC will +recursively call ``clear`` on the layer below it, clearing out the +link layer headers and footers. Calling ``clear`` is typically +necessary when moving a packet across two link layers. Otherwise, the +destination link layer may incorrectly interpret metadata from the +source link layer, and, for example, transmit the packet on the wrong +RF channel. Because ``clear`` prepares a packet for a particular link +layer, in this example correct code would call the command on the +destination link layer, not the source link layer. + +Typically, an incoming call to the Packet interface of a protocol has +an accompanying outgoing call to the Packet interface of the component +below it. The one exception to this is the data link layer. For +example, if there is a network that introduces 16-bit sequence numbers +to packets, it might look like this:: generic module SequenceNumber { provides interface Packet; @@ -170,9 +182,11 @@ layer. For example, if there is a network that introduces }; command void Packet.clear(message_t* msg) { - uint8_t len; - void* payload = call SubPacket.getPayload(msg, &len); - memset(payload, len, 0); + void* payload = call SubPacket.getPayload(msg, call SubPacket.maxPayloadLength()); + call SubPacket.clear(); + if (payload != NULL) { + memset(payload, sizeof(seq_header_t), 0); + } } command uint8_t Packet.payloadLength(message_t* msg) { @@ -187,12 +201,12 @@ layer. For example, if there is a network that introduces return SubPacket.maxPayloadLength(msg) - SEQNO_OFFSET; } - command void* Packet.getPayload(message_t* msg, uint8_t* len) { - uint8_t* payload = call SubPacket.getPayload(msg, len); - if (len != NULL) { - *len -= SEQNO_OFFSET; + command void* Packet.getPayload(message_t* msg, uint8_t len) { + uint8_t* payload = call SubPacket.getPayload(msg, len + SEQNO_OFFSET); + if (payload != NULL) { + payload += SEQNO_OFFSET; } - return payload + SEQNO_OFFSET; + return payload; } } @@ -227,19 +241,26 @@ has this signature:: command bool isForMe(message_t* amsg); command am_id_t type(message_t* amsg); command void setType(message_t* amsg, am_id_t t); + command am_group_t group(message_t* amsg); + command void setGroup(message_t* amsg, am_group_t grp); + command am_group_t localGroup(); } The command address() returns the local AM address of the -node. AMPacket provides accessors for its two fields, destination and -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. +node. AMPacket provides accessors for its four fields, destination, +source, type and group. 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. + +The group field refers to the AM group, a logical network identifier. +Link layers will typically only signal reception for packets whose AM +group matches the node's, which ``localGroup`` returns. 2.2 Sending interfaces -------------------------------------------------------------------- @@ -257,7 +278,7 @@ basic, address-free Send interface:: event void sendDone(message_t* msg, error_t error); command uint8_t maxPayloadLength(); - command void* getPayload(message_t* msg); + command void* getPayload(message_t* msg, uint8_t len); } while this is the AMSend interface:: @@ -268,16 +289,14 @@ while this is the AMSend interface:: event void sendDone(message_t* msg, error_t error); command uint8_t maxPayloadLength(); - command void* getPayload(message_t* msg); + command void* getPayload(message_t* msg, uint8_t len); } Sending interfaces MUST include these four commands and one event. The duplication of some of the commands in Packet is solely for ease of use: ``maxPayloadLength`` and ``getPayload`` MUST behave -identically as ``Packet.maxPayloadLength`` and ``Packet.getPayload``, -with the exception that the latter has no length parameter (it should -behave as if the length parameter of the ``Packet`` call were -NULL). Their inclusion is so that components do not have to wire to +identically as ``Packet.maxPayloadLength`` and ``Packet.getPayload.`` +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 @@ -299,12 +318,12 @@ 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. +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 MUST occur as if +the cancel was not called. 2.3 Receive interface -------------------------------------------------------------------- @@ -313,32 +332,29 @@ Receive is the interface for receiving packets. It has this signature:: interface Receive { event message_t* receive(message_t* msg, void* payload, uint8_t len); - command void* getPayload(message_t* msg, uint8_t* len); - command uint8_t payloadLength(message_t* msg); } -A call to ``Receive.getPayload()`` MUST behave identically to a call -to ``Packet.getPayload()``. The ``receive()`` event's ``payload`` -parameter MUST be identical to what a call to ``getPayload()`` would -return, and the ``len`` parameter MUST be identical to the length that -a call to ``getPayload`` would return. These parameters are for +The ``receive()`` event's ``payload`` parameter MUST be identical to +what a call to the corresponding ``Packet.getPayload()`` would return, +and the ``len`` parameter MUST be identical to the length that a call +to ``Packet.getPayload`` would return. These parameters are for convenience, as they are commonly used by receive handlers, and their -presence removes the need for a call to ``getPayload()``, while -``getPayload()`` is a convenience so a component does not have to wire -to ``Packet.`` The command ``payloadLength`` has a similar motivation -and the same semantics as its twin in ``Packet``. - -Receive has a *buffer-swap* policy. The handler of the event MUST return -a pointer to a valid message buffer for the signaler to use. This -approach enforces an equilibrium between upper and lower packet -layers. If an upper layer cannot handle packets as quickly as they -are arriving, it still has to return a valid buffer to the lower +presence removes the need for a call to ``getPayload()``. Unlike Send, +Receive does not have a convenience ``getPayload`` call, because doing +so prevents fan-in. As Receive has only a single event, users of +Receive can be wired multiple times. + +Receive has a *buffer-swap* policy. The handler of the event MUST +return a pointer to a valid message buffer for the signaler to +use. This approach enforces an equilibrium between upper and lower +packet layers. If an upper layer cannot handle packets as quickly as +they are arriving, it still has to return a valid buffer to the lower layer. This buffer could be the ``msg`` parameter passed to it: it just returns the buffer it was given without looking at it. Following -this policy means that a data-rate mismatch in an upper-level component -will be isolated to that component. It will drop packets, but it will -not prevent other components from receiving packets. If an upper -layer did not have to return a buffer immediately, then when an +this policy means that a data-rate mismatch in an upper-level +component will be isolated to that component. It will drop packets, +but it will not prevent other components from receiving packets. If an +upper layer did not have to return a buffer immediately, then when an upper layer cannot handle packets quickly enough it will end up holding all of them, starving lower layers and possibly preventing packet reception. @@ -681,6 +697,3 @@ which exports the interfaces of ``CC2420ActiveMessageC``. .. [4] TEP 113: Serial Communication. - - -