* Author: Miklos Maroti
*/
+#include <HplRF230.h>
+
configuration DefaultMacC
{
provides
interface Packet;
interface AMPacket;
interface PacketAcknowledgements;
+
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketTimeStamp<TRF230, uint16_t>;
+ interface PacketTimeSynch<TRF230, uint16_t>;
}
}
implementation
{
- components DefaultMacP, IEEE154PacketC, RadioAlarmC;
+ components DefaultMacP, DefaultPacketC, IEEE154PacketC, RadioAlarmC;
#ifdef RF230_DEBUG
components AssertC;
#endif
DefaultMacP.IEEE154Packet -> IEEE154PacketC;
+ DefaultMacP.Packet -> DefaultPacketC;
DefaultMacP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
+ Packet = DefaultPacketC;
+ AMPacket = DefaultPacketC;
+ PacketAcknowledgements = DefaultPacketC;
+ PacketLinkQuality = DefaultPacketC.PacketLinkQuality;
+ PacketTimeStamp = DefaultPacketC.PacketTimeStamp;
+ PacketTimeSynch = DefaultPacketC.PacketTimeSynch;
+
components ActiveMessageLayerC;
components MessageBufferLayerC;
components UniqueLayerC;
AMSend = ActiveMessageLayerC;
Receive = ActiveMessageLayerC.Receive;
Snoop = ActiveMessageLayerC.Snoop;
- Packet = DefaultMacP;
- AMPacket = IEEE154PacketC;
- PacketAcknowledgements = DefaultMacP;
ActiveMessageLayerC.Config -> DefaultMacP;
ActiveMessageLayerC.AMPacket -> IEEE154PacketC;
UniqueLayerC.Config -> DefaultMacP;
UniqueLayerC.SubSend -> MessageBufferLayerC;
- MessageBufferLayerC.Packet -> DefaultMacP;
+ MessageBufferLayerC.Packet -> DefaultPacketC;
MessageBufferLayerC.RadioSend -> TrafficMonitorLayerC;
MessageBufferLayerC.RadioReceive -> UniqueLayerC;
MessageBufferLayerC.RadioState -> TrafficMonitorLayerC;
CsmaLayerC.SubCCA -> RF230LayerC;
RF230LayerC.RF230Config -> DefaultMacP;
+ RF230LayerC.PacketLinkQuality -> DefaultPacketC.PacketLinkQuality;
+ RF230LayerC.PacketTransmitPower -> DefaultPacketC.PacketTransmitPower;
+ RF230LayerC.PacketTimeStamping -> DefaultPacketC.PacketTimeStamping;
+ RF230LayerC.PacketTimeSynchron -> DefaultPacketC.PacketTimeSynchron;
}
* Author: Miklos Maroti
*/
-#include <DefaultMac.h>
+#include <DefaultPacket.h>
#include <HplRF230.h>
#include <Tasklet.h>
interface SlottedCollisionConfig;
interface ActiveMessageConfig;
interface DummyConfig;
-
- interface PacketAcknowledgements;
- interface Packet;
}
uses
{
interface IEEE154Packet;
+ interface Packet;
interface RadioAlarm;
}
}
implementation
{
-/*----------------- Packet -----------------*/
-
- command void Packet.clear(message_t* msg)
- {
- call IEEE154Packet.createDataFrame(msg);
-
-#ifdef IEEE154_6LOWPAN
- call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID);
-#endif
- }
-
- command uint8_t Packet.payloadLength(message_t* msg)
- {
- return call IEEE154Packet.getLength(msg) - sizeof(ieee154_header_t) + 1 - sizeof(ieee154_footer_t);
- }
-
- command void Packet.setPayloadLength(message_t* msg, uint8_t len)
- {
- call IEEE154Packet.setLength(msg, len + sizeof(ieee154_header_t) - 1 + sizeof(ieee154_footer_t));
- }
-
- command uint8_t Packet.maxPayloadLength()
- {
- return TOSH_DATA_LENGTH;
- }
-
- command void* Packet.getPayload(message_t* msg, uint8_t len)
- {
- if( len > TOSH_DATA_LENGTH )
- return NULL;
-
- return msg->data;
- }
-
- command error_t ActiveMessageConfig.checkPacket(message_t* msg)
- {
- // the user forgot to call clear, we should return EINVAL
- if( ! call IEEE154Packet.isDataFrame(msg) )
- call Packet.clear(msg);
-
- return SUCCESS;
- }
-
/*----------------- RF230Config -----------------*/
async command uint8_t RF230Config.getLength(message_t* msg)
return ((uint8_t*)(call IEEE154Packet.getHeader(msg))) + 1;
}
- inline defaultmac_metadata_t* getMeta(message_t* msg)
+ inline defpacket_metadata_t* getMeta(message_t* msg)
{
- return (defaultmac_metadata_t*)(msg->metadata);
- }
-
- async command void RF230Config.setTimestamp(message_t* msg, uint16_t time)
- {
- getMeta(msg)->timestamp = time;
- }
-
- async command void RF230Config.setLinkQuality(message_t* msg, uint8_t lqi)
- {
- getMeta(msg)->lqi = lqi;
+ return (defpacket_metadata_t*)(msg->metadata);
}
async command uint8_t RF230Config.getHeaderLength()
async command uint8_t RF230Config.getMaxLength()
{
// note, that the ieee154_footer_t is not stored, but we should include it here
- return sizeof(defaultmac_header_t) - 1 + TOSH_DATA_LENGTH + sizeof(ieee154_footer_t);
- }
-
- async command uint8_t RF230Config.getTransmitPower(message_t* msg)
- {
- return RF230_DEF_RFPOWER;
+ return sizeof(defpacket_header_t) - 1 + TOSH_DATA_LENGTH + sizeof(ieee154_footer_t);
}
async command uint8_t RF230Config.getDefaultChannel()
async command void SoftwareAckConfig.setAckReceived(message_t* msg, bool acked)
{
if( acked )
- getMeta(msg)->flags |= DEFAULTMAC_WAS_ACKED;
+ getMeta(msg)->flags |= DEFPACKET_WAS_ACKED;
else
- getMeta(msg)->flags &= ~DEFAULTMAC_WAS_ACKED;
+ getMeta(msg)->flags &= ~DEFPACKET_WAS_ACKED;
}
async command uint16_t SoftwareAckConfig.getAckTimeout()
signal TrafficMonitorConfig.channelError();
}
-/*----------------- PacketAcknowledgements -----------------*/
-
- async command error_t PacketAcknowledgements.requestAck(message_t* msg)
- {
- call IEEE154Packet.setAckRequired(msg, TRUE);
-
- return SUCCESS;
- }
-
- async command error_t PacketAcknowledgements.noAck(message_t* msg)
- {
- call IEEE154Packet.setAckRequired(msg, FALSE);
-
- return SUCCESS;
- }
-
- async command bool PacketAcknowledgements.wasAcked(message_t* msg)
- {
- return getMeta(msg)->flags & DEFAULTMAC_WAS_ACKED;
- }
-
/*----------------- UniqueConfig -----------------*/
async command uint8_t UniqueConfig.getSequenceNumber(message_t* msg)
signal TrafficMonitorConfig.channelError();
}
+/*----------------- ActiveMessageConfig -----------------*/
+
+ command error_t ActiveMessageConfig.checkPacket(message_t* msg)
+ {
+ // the user forgot to call clear, we should return EINVAL
+ if( ! call IEEE154Packet.isDataFrame(msg) )
+ call Packet.clear(msg);
+
+ return SUCCESS;
+ }
+
/*----------------- CsmaConfig -----------------*/
async command bool CsmaConfig.requiresSoftwareCCA(message_t* msg)
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __DEFAULTPACKET_H__
+#define __DEFAULTPACKET_H__
+
+#include <IEEE154Packet.h>
+
+typedef ieee154_header_t defpacket_header_t;
+
+typedef nx_struct defpacket_metadata_t
+{
+ nx_uint8_t flags;
+ nx_uint8_t lqi;
+ nx_uint16_t timestamp;
+} defpacket_metadata_t;
+
+enum defpacket_metadata_flags
+{
+ DEFPACKET_WAS_ACKED = 0x01,
+ DEFPACKET_TIMESTAMP = 0x02,
+
+ DEFPACKET_CLEAR_METADATA = 0x00,
+};
+
+typedef nx_struct defpacket_footer_t
+{
+ nx_uint16_t timeoffset;
+} defpacket_footer_t;
+
+enum defpacket_footer_enum
+{
+ // just to signal missing time offsets
+ DEFPACKET_INVALID_TIMEOFFSET = 0x7317,
+};
+
+#endif//__DEFAULTPACKET_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <HplRF230.h>
+
+configuration DefaultPacketC
+{
+ provides
+ {
+ interface Packet;
+ interface AMPacket;
+ interface PacketAcknowledgements;
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint8_t> as PacketTransmitPower;
+ interface PacketField<uint16_t> as PacketTimeStamping;
+ interface PacketField<uint16_t> as PacketTimeSynchron;
+
+ interface PacketTimeStamp<TRF230, uint16_t>;
+ interface PacketTimeSynch<TRF230, uint16_t>;
+ }
+}
+
+implementation
+{
+ components DefaultPacketP, IEEE154PacketC;
+
+ DefaultPacketP.IEEE154Packet -> IEEE154PacketC;
+
+ Packet = DefaultPacketP;
+ AMPacket = IEEE154PacketC;
+ PacketAcknowledgements = DefaultPacketP;
+ PacketLinkQuality = DefaultPacketP.PacketLinkQuality;
+ PacketTransmitPower = DefaultPacketP.PacketTransmitPower;
+ PacketTimeStamping = DefaultPacketP.PacketTimeStamping;
+ PacketTimeSynchron = DefaultPacketP.PacketTimeSynchron;
+
+ PacketTimeStamp = DefaultPacketP.PacketTimeStamp;
+ PacketTimeSynch = DefaultPacketP.PacketTimeSynch;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <DefaultPacket.h>
+
+module DefaultPacketP
+{
+ provides
+ {
+ interface PacketAcknowledgements;
+ interface Packet;
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint8_t> as PacketTransmitPower;
+ interface PacketField<uint16_t> as PacketTimeStamping;
+ interface PacketField<uint16_t> as PacketTimeSynchron;
+
+ interface PacketTimeStamp<TRF230, uint16_t>;
+ interface PacketTimeSynch<TRF230, uint16_t>;
+ }
+
+ uses
+ {
+ interface IEEE154Packet;
+ }
+}
+
+implementation
+{
+/*----------------- Async Packet -----------------*/
+
+#define PACKET_OVERHEAD ((sizeof(ieee154_header_t) - 1) + sizeof(defpacket_footer_t) + sizeof(ieee154_footer_t))
+
+ // async Packet.payloadLength
+ inline uint8_t getPayloadLength(message_t* msg)
+ {
+ // sizeof(ieee154_header_t) - 1 : the ieee154 header minus the length field
+ // sizeof(defpacket_footer_t) : footer containing the embedded time offset
+ // sizeof(ieee154_footer_t) : the size of the CRC (not transmitted)
+
+ return call IEEE154Packet.getLength(msg) - PACKET_OVERHEAD;
+ }
+
+ // async Pakcet.maxPayloadLength
+ inline uint8_t getMaxPayloadLength()
+ {
+ return TOSH_DATA_LENGTH;
+ }
+
+/*----------------- Accessors -----------------*/
+
+ inline defpacket_metadata_t* getMeta(message_t* msg)
+ {
+ return (defpacket_metadata_t*)(msg->metadata);
+ }
+
+ inline defpacket_footer_t* getFooter(message_t* msg)
+ {
+ return (defpacket_footer_t*)(msg->data + getPayloadLength(msg));
+ }
+
+/*----------------- Packet -----------------*/
+
+ command void Packet.clear(message_t* msg)
+ {
+ call IEEE154Packet.createDataFrame(msg);
+
+#ifdef IEEE154_6LOWPAN
+ call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID);
+#endif
+
+ getMeta(msg)->flags = DEFPACKET_CLEAR_METADATA;
+ }
+
+ inline command void Packet.setPayloadLength(message_t* msg, uint8_t len)
+ {
+ call IEEE154Packet.setLength(msg, len + PACKET_OVERHEAD);
+ }
+
+ inline command uint8_t Packet.payloadLength(message_t* msg)
+ {
+ return getPayloadLength(msg);
+ }
+
+ inline command uint8_t Packet.maxPayloadLength()
+ {
+ return getMaxPayloadLength();
+ }
+
+ command void* Packet.getPayload(message_t* msg, uint8_t len)
+ {
+ if( len > TOSH_DATA_LENGTH )
+ return NULL;
+
+ return msg->data;
+ }
+
+/*----------------- PacketAcknowledgements -----------------*/
+
+ async command error_t PacketAcknowledgements.requestAck(message_t* msg)
+ {
+ call IEEE154Packet.setAckRequired(msg, TRUE);
+
+ return SUCCESS;
+ }
+
+ async command error_t PacketAcknowledgements.noAck(message_t* msg)
+ {
+ call IEEE154Packet.setAckRequired(msg, FALSE);
+
+ return SUCCESS;
+ }
+
+ async command bool PacketAcknowledgements.wasAcked(message_t* msg)
+ {
+ return getMeta(msg)->flags & DEFPACKET_WAS_ACKED;
+ }
+
+/*----------------- PacketLinkQuality -----------------*/
+
+ async command bool PacketLinkQuality.isSet(message_t* msg)
+ {
+ return TRUE;
+ }
+
+ async command uint8_t PacketLinkQuality.get(message_t* msg)
+ {
+ return getMeta(msg)->lqi;
+ }
+
+ async command void PacketLinkQuality.clear(message_t* msg)
+ {
+ }
+
+ async command void PacketLinkQuality.set(message_t* msg, uint8_t value)
+ {
+ getMeta(msg)->lqi = value;
+ }
+
+/*----------------- PacketTimeStamp -----------------*/
+
+ async command bool PacketTimeStamping.isSet(message_t* msg)
+ {
+ return getMeta(msg)->flags & DEFPACKET_TIMESTAMP;
+ }
+
+ async command uint16_t PacketTimeStamping.get(message_t* msg)
+ {
+ return getMeta(msg)->timestamp;
+ }
+
+ async command void PacketTimeStamping.clear(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~DEFPACKET_TIMESTAMP;
+ }
+
+ async command void PacketTimeStamping.set(message_t* msg, uint16_t value)
+ {
+ getMeta(msg)->flags |= DEFPACKET_TIMESTAMP;
+ getMeta(msg)->timestamp = value;
+ }
+
+ inline async command bool PacketTimeStamp.isSet(message_t* msg)
+ {
+ return call PacketTimeStamping.isSet(msg);
+ }
+
+ inline async command uint16_t PacketTimeStamp.get(message_t* msg)
+ {
+ return call PacketTimeStamping.get(msg);
+ }
+
+ inline async command void PacketTimeStamp.clear(message_t* msg)
+ {
+ call PacketTimeStamping.clear(msg);
+ }
+
+ inline async command void PacketTimeStamp.set(message_t* msg, uint16_t value)
+ {
+ call PacketTimeStamping.set(msg, value);
+ }
+
+/*----------------- PacketTimeSynch -----------------*/
+
+ async command bool PacketTimeSynchron.isSet(message_t* msg)
+ {
+ // just sanity check if the length is not initialized
+ if( getPayloadLength(msg) > getMaxPayloadLength() )
+ return FALSE;
+
+ return getFooter(msg)->timeoffset != DEFPACKET_INVALID_TIMEOFFSET;
+ }
+
+ async command uint16_t PacketTimeSynchron.get(message_t* msg)
+ {
+ return getFooter(msg)->timeoffset;
+ }
+
+ async command void PacketTimeSynchron.clear(message_t* msg)
+ {
+ // just sanity check if the length is not initialized
+ if( getPayloadLength(msg) <= getMaxPayloadLength() )
+ getFooter(msg)->timeoffset = DEFPACKET_INVALID_TIMEOFFSET;
+ }
+
+ async command void PacketTimeSynchron.set(message_t* msg, uint16_t value)
+ {
+ if( getPayloadLength(msg) > getMaxPayloadLength() )
+ return;
+
+ if( value == DEFPACKET_INVALID_TIMEOFFSET )
+ ++value;
+
+ getFooter(msg)->timeoffset = value;
+ }
+
+ inline async command bool PacketTimeSynch.isSet(message_t* msg)
+ {
+ return call PacketTimeSynchron.isSet(msg);
+ }
+
+ inline async command uint16_t PacketTimeSynch.get(message_t* msg)
+ {
+ return call PacketTimeSynchron.get(msg);
+ }
+
+ inline async command void PacketTimeSynch.clear(message_t* msg)
+ {
+ call PacketTimeSynchron.clear(msg);
+ }
+
+ inline async command void PacketTimeSynch.set(message_t* msg, uint16_t value)
+ {
+ call PacketTimeSynchron.set(msg, value);
+ }
+
+/*----------------- Global fields -----------------*/
+
+ uint8_t flags;
+ enum
+ {
+ FLAG_TXPOWER = 0x01,
+ };
+
+ uint8_t transmitPower;
+
+/*----------------- PacketTransmitPower -----------------*/
+
+ async command bool PacketTransmitPower.isSet(message_t* msg)
+ {
+ return flags & FLAG_TXPOWER;
+ }
+
+ async command uint8_t PacketTransmitPower.get(message_t* msg)
+ {
+ return transmitPower;
+ }
+
+ async command void PacketTransmitPower.clear(message_t* msg)
+ {
+ flags &= ~FLAG_TXPOWER;
+ }
+
+ async command void PacketTransmitPower.set(message_t* msg, uint8_t value)
+ {
+ flags |= FLAG_TXPOWER;
+ transmitPower = value;
+ }
+}
s = state;
+ // change the state before so we can be reentered rom the event
if( s == STATE_TURN_ON || s == STATE_TURN_OFF )
state = STATE_READY;
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface PacketField<value_type>
+{
+ /**
+ * Returns TRUE if the value is set for this message.
+ */
+ async command bool isSet(message_t* msg);
+
+ /**
+ * Returns the stored value of this field in the message. If the
+ * value is not set, then the returned value is undefined.
+ */
+ async command value_type get(message_t* msg);
+
+ /**
+ * Clears the isSet flag.
+ */
+ async command void clear(message_t* msg);
+
+ /**
+ * Sets the isSet false to TRUE and the time stamp value to the
+ * specified value.
+ */
+ async command void set(message_t* msg, value_type value);
+}
interface PacketTimeStamp<precision_tag, size_type>
{
/**
- * Returns TRUE if the time stamp stored in the message is valid. Under
- * special circumstances the radio chip might not be able to correctly
- * assign a precise time value to an incoming packet (e.g. under very
- * heavy traffic multiple interrupts can occur before they could be
- * serviced, and even if capture registers are used, it is not possible
- * to get the time stamp for the first or last unserviced event), in
- * which case the time stamp value should not be used.
+ * Returns TRUE if the time stamp stored in the metadata of the message
+ * is valid. Under special circumstances the radio chip might not be
+ * able to correctly assign a precise time value to an incoming packet
+ * (e.g. under very heavy traffic multiple interrupts can occur before
+ * they could be serviced, and even if capture registers are used, it
+ * is not possible to get the time stamp for the first or last unserviced
+ * event), in which case the time stamp value should not be used.
*/
async command bool isSet(message_t* msg);
interface PacketTimeSynch<precision_tag, size_type>
{
/**
- * This command should be called by the sender on packets used for sender-
- * receiver time synchronization. The eventTime parameter should be as
- * close to the current time as possible (precision and size of the stamp
- * permitting) to avoid large time synchronization errors resulting from
- * the time skew between the clocks of the sender and receiver. The
- * time difference between the sending time and eventTime is stored in
- * the message just before it is transmitted over the air.
- */
- async command void set(message_t* msg, size_type eventTime);
-
- /**
- * The recveive should call this method to ensure that the received time
- * stamp is correct (for the same reason as for PacketTimeStamp.isSet).
- * If this method returns TRUE, then the eventTime returned by the get
- * command is correct.
+ * The recveiver should call this method to ensure that the received
+ * message contains an embedded timestamp and that is correct (for the
+ * same reason as for PacketTimeStamp.isSet). If this method returns
+ * TRUE, then the eventTime returned by the get command is correct,
+ * and reflects the event time in the local clock of the receiver.
*/
async command bool isSet(message_t* msg);
* correct.
*/
async command size_type get(message_t* msg);
+
+ /**
+ * Clears the time stamp in the message.
+ */
+ async command void clear(message_t* msg);
+
+ /**
+ * This command should be called by the sender on packets used for sender-
+ * receiver time synchronization. The eventTime parameter should be as
+ * close to the current time as possible (precision and size of the stamp
+ * permitting) to avoid large time synchronization errors resulting from
+ * the time skew between the clocks of the sender and receiver. The
+ * time difference between the sending time and eventTime is stored in
+ * the message just before it is transmitted over the air.
+ */
+ async command void set(message_t* msg, size_type eventTime);
}
*/
async command uint8_t* getPayload(message_t* msg);
- /**
- * Sets the timestamp (when the message was sent or received)
- */
- async command void setTimestamp(message_t* msg, uint16_t time);
-
- /**
- * Sets the link quality indicator field for the received message
- */
- async command void setLinkQuality(message_t* msg, uint8_t lqi);
-
/**
* Gets the number of bytes we should read before the RadioReceive.header
* event is fired. If the length of the packet is less than this amount,
*/
async command uint8_t getMaxLength();
- /**
- * Returns the transmit power for the given message, this must be a value
- * in the range [0, 15] which will be stored in the PHY_TX_PWR register.
- */
- async command uint8_t getTransmitPower(message_t* msg);
-
/**
* This command is used at power up to set the default channel.
* The default CC2420 channel is 26.
{
provides
{
- interface Init as PlatformInit @exactlyonce();
-
interface RadioState;
interface RadioSend;
interface RadioReceive;
uses
{
interface RF230Config;
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint8_t> as PacketTransmitPower;
+ interface PacketField<uint16_t> as PacketTimeStamping;
+ interface PacketField<uint16_t> as PacketTimeSynchron;
}
}
{
components RF230LayerP, HplRF230C, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC;
- PlatformInit = RF230LayerP.PlatformInit;
-
RadioState = RF230LayerP;
RadioSend = RF230LayerP;
RadioReceive = RF230LayerP;
RadioCCA = RF230LayerP;
RF230Config = RF230LayerP;
+ PacketLinkQuality = RF230LayerP.PacketLinkQuality;
+ PacketTransmitPower = RF230LayerP.PacketTransmitPower;
+ PacketTimeStamping = RF230LayerP.PacketTimeStamping;
+ PacketTimeSynchron = RF230LayerP.PacketTimeSynchron;
RF230LayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
RadioAlarmC.Alarm -> HplRF230C.Alarm;
#endif
MainC.SoftwareInit -> RF230LayerP.SoftwareInit;
+
+ components RealMainP;
+ RealMainP.PlatformInit -> RF230LayerP.PlatformInit;
}
interface BusyWait<TMicro, uint16_t>;
interface RF230Config;
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint16_t> as PacketTimeStamping;
+ interface PacketField<uint16_t> as PacketTimeSynchron;
+ interface PacketField<uint8_t> as PacketTransmitPower;
interface Tasklet;
+ interface RadioAlarm;
#ifdef RF230_DEBUG
interface DiagMsg;
#endif
-
- interface RadioAlarm;
}
}
writeRegister(RF230_TRX_STATE, RF230_PLL_ON);
// do something useful, just to wait a little
- length = call RF230Config.getTransmitPower(msg) & RF230_TX_PWR_MASK;
+ length = (call PacketTransmitPower.isSet(msg) ?
+ call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK;
+
if( length != txPower )
{
txPower = length;
atomic
{
call SLP_TR.set();
- time = call RadioAlarm.getNow();
+ time = call RadioAlarm.getNow() + TX_SFD_DELAY;
}
call SLP_TR.clr();
// the FCS is atomatically generated
length -= 2;
+ // calculate and embed the time offset
+ if( call PacketTimeSynchron.isSet(msg) )
+ call PacketTimeSynchron.set(msg, call PacketTimeSynchron.get(msg) - time);
+
do {
call HplRF230.spiSplitReadWrite(*(data++));
}
return FAIL;
}
- time += TX_SFD_DELAY;
- call RF230Config.setTimestamp(msg, time);
+ // TODO: be nicer for retransmissions
+ // clear the embedded time stamp field
+ call PacketTimeSynchron.clear(msg);
+
+ call PacketTimeStamping.set(msg, time);
// wait for the TRX_END interrupt
state = STATE_BUSY_TX_2_RX_ON;
crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));
crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));
- call RF230Config.setLinkQuality(rxMsg, call HplRF230.spiSplitRead());
+ call PacketLinkQuality.set(rxMsg, call HplRF230.spiSplitRead());
}
else
crc = 1;
state = STATE_RX_ON;
cmd = CMD_NONE;
+ // we need a correct time stamp of the message
+ if( call PacketTimeSynchron.isSet(rxMsg) && call PacketTimeStamping.isSet(rxMsg) )
+ call PacketTimeSynchron.set(rxMsg, call PacketTimeSynchron.get(rxMsg) + call PacketTimeStamping.get(rxMsg));
+
// signal only if it has passed the CRC check
if( crc == 0 )
rxMsg = signal RadioReceive.receive(rxMsg);
* we could not be after a transmission, because then cmd =
* CMD_TRANSMIT.
*/
- call RF230Config.setTimestamp(rxMsg, time - RX_SFD_DELAY);
+ if( irq == RF230_IRQ_RX_START ) // just to be cautious
+ call PacketTimeStamping.set(rxMsg, time - RX_SFD_DELAY);
+ else
+ call PacketTimeStamping.clear(rxMsg);
+
cmd = CMD_RECEIVE;
}
else