-// $Id$
-
/*
* "Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* addr and group).
*
* @author Philip Levis
- * @date June 19 2005
+ * @author Marco Langerwisch (Packet timestamping)
*/
configuration CC1000ActiveMessageC {
interface Packet;
interface PacketAcknowledgements;
interface LinkPacketMetadata;
+
+ interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ interface PacketTimeSyncOffset;
}
}
implementation {
AM.amAddress -> Address;
AM.Packet -> Radio;
+ PacketTimeStamp32khz = Radio;
+ PacketTimeStampMilli = Radio;
+ PacketTimeSyncOffset = Radio;
}
-/* $Id$
+/*
* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
*
*
* @author Joe Polastre
* @author David Gay
+ * @author Marco Langerwisch (Packet timestamping)
*/
#include "CC1000Const.h"
interface Send;
interface Receive;
- interface Packet;
+ interface Packet;
interface CsmaControl;
interface CsmaBackoff;
- interface RadioTimeStamping;
interface PacketAcknowledgements;
interface LinkPacketMetadata;
-
+
interface LowPowerListening;
+
+ interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ interface PacketTimeSyncOffset;
}
}
implementation {
CsmaControl = Csma;
CsmaBackoff = Csma;
LowPowerListening = Csma;
- RadioTimeStamping = SendReceive;
PacketAcknowledgements = SendReceive;
LinkPacketMetadata = SendReceive;
-
+
Csma.CC1000Control -> Control;
Csma.Random -> RandomC;
Csma.CC1000Squelch -> Squelch;
SendReceive.amAddress -> ActiveMessageAddressC;
SendReceive.RssiRx -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
SendReceive.CC1000Squelch -> Squelch;
-
+
Csma.RssiNoiseFloor -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
Csma.RssiCheckChannel -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
Csma.RssiPulseCheck -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
Rssi.Resource -> Hpl;
Control.CC -> Hpl;
Control.BusyWait -> BusyWaitMicroC;
+
+ PacketTimeStamp32khz = SendReceive;
+ PacketTimeStampMilli = SendReceive;
+ PacketTimeSyncOffset = SendReceive;
+
+ components Counter32khz32C, new CounterToLocalTimeC(T32khz);
+ CounterToLocalTimeC.Counter -> Counter32khz32C;
+ SendReceive.LocalTime32khz -> CounterToLocalTimeC;
+
+ //DummyTimer is introduced to compile apps that use no timers
+ components HilTimerMilliC, new TimerMilliC() as DummyTimer;
+ SendReceive.LocalTimeMilli -> HilTimerMilliC;
}
typedef nx_struct CC1KMetadata {
nx_int16_t strength_or_preamble; /* negative when used for preamble length */
nx_uint8_t metadataBits;
- nx_uint16_t time;
+ nx_bool timesync;
+ nx_uint32_t timestamp;
nx_uint8_t sendSecurityMode;
nx_uint8_t receiveSecurityMode;
} cc1000_metadata_t;
+enum
+{
+ CC1000_INVALID_TIMESTAMP = 0x80000000L,
+};
+
#endif
-// $Id$
-
/*
* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
#include "crc.h"
#include "CC1000Const.h"
#include "Timer.h"
+#include "CC1000TimeSyncMessage.h"
/**
* A rewrite of the low-power-listening CC1000 radio stack.
* @author Jaein Jeong
* @author Joe Polastre
* @author David Gay
+ * @author Marco Langerwisch (Packet timestamping)
*/
module CC1000SendReceiveP @safe() {
interface StdControl;
interface Send;
interface Receive;
- interface RadioTimeStamping;
interface Packet;
interface ByteRadio;
interface PacketAcknowledgements;
interface LinkPacketMetadata;
+
+ interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ interface PacketTimeSyncOffset;
}
uses {
//interface PowerManagement;
interface CC1000Squelch;
interface ReadNow<uint16_t> as RssiRx;
async command am_addr_t amAddress();
+
+ interface LocalTime<T32khz> as LocalTime32khz;
+ interface LocalTime<TMilli> as LocalTimeMilli;
}
}
implementation
{
+#ifdef PLATFORM_MICA2
+ // estimated calibration, 19.2 Kbps data, Manchester Encoding, time in jiffies (32768 Hz)
+ static const int8_t BIT_CORRECTION[8] = { 27, 28, 30, 32, 34, 36, 38, 40 };
+#else
+ // other platforms not calibrated yet
+ static const uint8_t BIT_CORRECTION[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+#endif
+
enum {
OFF_STATE,
return FAIL;
else {
cc1000_header_t *header = getHeader(msg);
+ cc1000_metadata_t *metadata = getMetadata(msg);
f.txBusy = TRUE;
header->length = len;
txBufPtr = msg;
+
+ metadata->timesync = FALSE;
+ metadata->timestamp = CC1000_INVALID_TIMESTAMP;
}
}
signal ByteRadio.rts(msg);
sendNextByte();
nextTxByte = SYNC_BYTE2;
enterTxDataState();
- signal RadioTimeStamping.transmittedSFD(0, txBufPtr);
}
void txData() {
cc1000_header_t *txHeader = getHeader(txBufPtr);
sendNextByte();
+
+ if (nextTxByte == SYNC_BYTE2) {
+ // SYNC_WORD has just been sent
+ uint32_t time32khz = call LocalTime32khz.get();
+ call PacketTimeStamp32khz.set(txBufPtr, time32khz);
+
+ if (call PacketTimeSyncOffset.isSet(txBufPtr)) {
+ timesync_radio_t *timesync = (timesync_radio_t*)((void*)txBufPtr + call PacketTimeSyncOffset.get(txBufPtr));
+ // set timesync event time as the offset between the event time and the SFD interrupt time (TEP 133)
+ *timesync -= time32khz;
+ }
+ }
if (count < txHeader->length + sizeof(message_header_t))
{
else if (count <= 6)
{
// TODO: Modify to be tolerant of bad bits in the preamble...
+ uint32_t time;
uint16_t tmp;
uint8_t i;
+ time = call LocalTime32khz.get();
+
// bit shift the data in with previous sample to find sync
tmp = rxShiftBuf;
rxShiftBuf = rxShiftBuf << 8 | in;
enterRxState();
signal ByteRadio.rx();
f.rxBitOffset = 7 - i;
- signal RadioTimeStamping.receivedSFD(0);
+ // correct receive time according to bit offset and set timestamp
+ time -= BIT_CORRECTION[f.rxBitOffset];
+ call PacketTimeStamp32khz.set(rxBufPtr, time);
+
call RssiRx.read();
}
}
async command bool LinkPacketMetadata.highChannelQuality(message_t* msg) {
return getMetadata(msg)->metadataBits & CC1000_WHITE_BIT;
}
-
- // Default events for radio send/receive coordinators do nothing.
- // Be very careful using these, or you'll break the stack.
- default async event void RadioTimeStamping.transmittedSFD(uint16_t time, message_t *msgBuff) { }
- default async event void RadioTimeStamping.receivedSFD(uint16_t time) { }
+
+ /***************** PacketTimeStamp32khz Commands ****************/
+ async command bool PacketTimeStamp32khz.isValid(message_t* msg)
+ {
+ return (getMetadata(msg)->timestamp != CC1000_INVALID_TIMESTAMP);
+ }
+
+ async command uint32_t PacketTimeStamp32khz.timestamp(message_t* msg)
+ {
+ return getMetadata(msg)->timestamp;
+ }
+
+ async command void PacketTimeStamp32khz.clear(message_t* msg)
+ {
+ getMetadata(msg)->timesync = FALSE;
+ getMetadata(msg)->timestamp = CC1000_INVALID_TIMESTAMP;
+ }
+
+ async command void PacketTimeStamp32khz.set(message_t* msg, uint32_t value)
+ {
+ getMetadata(msg)->timestamp = value;
+ }
+
+ /***************** PacketTimeStampMilli Commands ****************/
+ // over the air value is always T32khz
+ async command bool PacketTimeStampMilli.isValid(message_t* msg)
+ {
+ return call PacketTimeStamp32khz.isValid(msg);
+ }
+
+ async command uint32_t PacketTimeStampMilli.timestamp(message_t* msg)
+ {
+ int32_t offset = call PacketTimeStamp32khz.timestamp(msg) - call LocalTime32khz.get();
+ return (offset >> 5) + call LocalTimeMilli.get();
+ }
+
+ async command void PacketTimeStampMilli.clear(message_t* msg)
+ {
+ call PacketTimeStamp32khz.clear(msg);
+ }
+
+ async command void PacketTimeStampMilli.set(message_t* msg, uint32_t value)
+ {
+ int32_t offset = (value - call LocalTimeMilli.get()) << 5;
+ call PacketTimeStamp32khz.set(msg, offset + call LocalTime32khz.get());
+ }
+
+ /*----------------- PacketTimeSyncOffset -----------------*/
+ async command bool PacketTimeSyncOffset.isSet(message_t* msg)
+ {
+ return getMetadata(msg)->timesync;
+ }
+
+ async command uint8_t PacketTimeSyncOffset.get(message_t* msg)
+ {
+ return sizeof(cc1000_header_t) + getHeader(msg)->length - sizeof(timesync_radio_t);
+ }
+
+ async command void PacketTimeSyncOffset.set(message_t* msg)
+ {
+ getMetadata(msg)->timesync = TRUE;
+ }
+
+ async command void PacketTimeSyncOffset.cancel(message_t* msg)
+ {
+ getMetadata(msg)->timesync = FALSE;
+ }
}
--- /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 __TIMESYNCMESSAGE_H__
+#define __TIMESYNCMESSAGE_H__
+
+// this value is sent in the air
+typedef nx_uint32_t timesync_radio_t;
+
+#endif//__TIMESYNCMESSAGE_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.
+ */
+
+/**
+ * The Active Message layer for the CC1000 radio with timesync support. This
+ * configuration is just layer above CC1000ActiveMessageC that supports
+ * TimeSyncPacket and TimeSyncAMSend interfaces (TEP 133)
+ *
+ * @author: Miklos Maroti
+ * @author: Brano Kusy (CC2420 port)
+ * @author: Marco Langerwisch (CC1000 port)
+ */
+
+#include <Timer.h>
+#include <AM.h>
+
+configuration CC1000TimeSyncMessageC
+{
+ provides
+ {
+ interface SplitControl;
+ interface Receive[am_id_t id];
+ interface Receive as Snoop[am_id_t id];
+ interface Packet;
+ interface AMPacket;
+
+ interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+
+ interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[am_id_t id];
+ interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+
+ interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
+ interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+ }
+}
+
+implementation
+{
+ components CC1000TimeSyncMessageP, CC1000ActiveMessageC, LedsC;
+
+ PacketTimeStamp32khz = CC1000ActiveMessageC;
+ PacketTimeStampMilli = CC1000ActiveMessageC;
+
+ TimeSyncAMSend32khz = CC1000TimeSyncMessageP;
+ TimeSyncPacket32khz = CC1000TimeSyncMessageP;
+
+ TimeSyncAMSendMilli = CC1000TimeSyncMessageP;
+ TimeSyncPacketMilli = CC1000TimeSyncMessageP;
+
+ Packet = CC1000TimeSyncMessageP;
+ CC1000TimeSyncMessageP.SubSend -> CC1000ActiveMessageC.AMSend;
+ CC1000TimeSyncMessageP.SubPacket -> CC1000ActiveMessageC.Packet;
+ CC1000TimeSyncMessageP.PacketTimeStamp32khz -> CC1000ActiveMessageC;
+ CC1000TimeSyncMessageP.PacketTimeStampMilli -> CC1000ActiveMessageC;
+ CC1000TimeSyncMessageP.PacketTimeSyncOffset -> CC1000ActiveMessageC;
+
+ components Counter32khz32C,
+ new CounterToLocalTimeC(T32khz) as LocalTime32khzC, LocalTimeMilliC;
+ LocalTime32khzC.Counter -> Counter32khz32C;
+ CC1000TimeSyncMessageP.LocalTime32khz -> LocalTime32khzC;
+ CC1000TimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
+ CC1000TimeSyncMessageP.Leds -> LedsC;
+
+ SplitControl = CC1000ActiveMessageC;
+ Receive = CC1000ActiveMessageC.Receive;
+ Snoop = CC1000ActiveMessageC.Snoop;
+ AMPacket = CC1000ActiveMessageC;
+}
--- /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
+ * @author: Brano Kusy (CC2420 port)
+ * @author: Marco Langerwisch (CC1000 port)
+ */
+#include "CC1000TimeSyncMessage.h"
+
+module CC1000TimeSyncMessageP
+{
+ provides
+ {
+ interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[uint8_t id];
+ interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[uint8_t id];
+ interface Packet;
+
+ interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+ interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+ }
+
+ uses
+ {
+ interface AMSend as SubSend[uint8_t id];
+ interface Packet as SubPacket;
+
+ interface PacketTimeStamp<T32khz,uint32_t> as PacketTimeStamp32khz;
+ interface PacketTimeStamp<TMilli,uint32_t> as PacketTimeStampMilli;
+ interface PacketTimeSyncOffset;
+
+ interface LocalTime<T32khz> as LocalTime32khz;
+ interface LocalTime<TMilli> as LocalTimeMilli;
+ interface Leds;
+ }
+}
+
+implementation
+{
+ // TODO: change the Packet.payloadLength and Packet.maxPayloadLength commands to async
+ inline void* getFooter(message_t* msg)
+ {
+ // we use the payload length that we export (the smaller one)
+ return msg->data + call Packet.payloadLength(msg);
+ }
+
+/*----------------- Packet -----------------*/
+ command void Packet.clear(message_t* msg)
+ {
+ call PacketTimeSyncOffset.cancel(msg);
+ call SubPacket.clear(msg);
+ }
+
+ command void Packet.setPayloadLength(message_t* msg, uint8_t len)
+ {
+ call SubPacket.setPayloadLength(msg, len + sizeof(timesync_radio_t));
+ }
+
+ command uint8_t Packet.payloadLength(message_t* msg)
+ {
+ return call SubPacket.payloadLength(msg) - sizeof(timesync_radio_t);
+ }
+
+ command uint8_t Packet.maxPayloadLength()
+ {
+ return call SubPacket.maxPayloadLength() - sizeof(timesync_radio_t);
+ }
+
+ command void* Packet.getPayload(message_t* msg, uint8_t len)
+ {
+ return call SubPacket.getPayload(msg, len + sizeof(timesync_radio_t));
+ }
+
+/*----------------- TimeSyncAMSend32khz -----------------*/
+ command error_t TimeSyncAMSend32khz.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+ {
+ error_t err;
+ timesync_radio_t* timesync = (timesync_radio_t*)(msg->data + len);
+ *timesync = event_time;
+
+ err = call SubSend.send[id](addr, msg, len + sizeof(timesync_radio_t));
+ call PacketTimeSyncOffset.set(msg);
+ return err;
+ }
+
+ command error_t TimeSyncAMSend32khz.cancel[am_id_t id](message_t* msg)
+ {
+ call PacketTimeSyncOffset.cancel(msg);
+ return call SubSend.cancel[id](msg);
+ }
+
+ default event void TimeSyncAMSend32khz.sendDone[am_id_t id](message_t* msg, error_t error) {}
+
+ command uint8_t TimeSyncAMSend32khz.maxPayloadLength[am_id_t id]()
+ {
+ return call SubSend.maxPayloadLength[id]() - sizeof(timesync_radio_t);
+ }
+
+ command void* TimeSyncAMSend32khz.getPayload[am_id_t id](message_t* msg, uint8_t len)
+ {
+ return call SubSend.getPayload[id](msg, len + sizeof(timesync_radio_t));
+ }
+
+/*----------------- TimeSyncAMSendMilli -----------------*/
+ command error_t TimeSyncAMSendMilli.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+ {
+ // compute elapsed time in millisecond
+ event_time = ((event_time - call LocalTimeMilli.get()) << 5) + call LocalTime32khz.get();
+ return call TimeSyncAMSend32khz.send[id](addr, msg, len, event_time);
+ }
+
+ command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg)
+ {
+ return call TimeSyncAMSend32khz.cancel[id](msg);
+ }
+
+ default event void TimeSyncAMSendMilli.sendDone[am_id_t id](message_t* msg, error_t error){}
+
+ command uint8_t TimeSyncAMSendMilli.maxPayloadLength[am_id_t id]()
+ {
+ return call TimeSyncAMSend32khz.maxPayloadLength[id]();
+ }
+
+ command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
+ {
+ return call TimeSyncAMSend32khz.getPayload[id](msg, len);
+ }
+
+/*----------------- SubSend.sendDone -------------------*/
+ event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error)
+ {
+ signal TimeSyncAMSend32khz.sendDone[id](msg, error);
+ signal TimeSyncAMSendMilli.sendDone[id](msg, error);
+ }
+
+/*----------------- TimeSyncPacket32khz -----------------*/
+ command bool TimeSyncPacket32khz.isValid(message_t* msg)
+ {
+ timesync_radio_t* timesync = getFooter(msg);
+ return call PacketTimeStamp32khz.isValid(msg) && *timesync != CC1000_INVALID_TIMESTAMP;
+ }
+
+ command uint32_t TimeSyncPacket32khz.eventTime(message_t* msg)
+ {
+ timesync_radio_t* timesync = getFooter(msg);
+
+ return (uint32_t)(*timesync) + call PacketTimeStamp32khz.timestamp(msg);
+ }
+
+/*----------------- TimeSyncPacketMilli -----------------*/
+ command bool TimeSyncPacketMilli.isValid(message_t* msg)
+ {
+ timesync_radio_t* timesync = getFooter(msg);
+ return call PacketTimeStampMilli.isValid(msg) && *timesync != CC1000_INVALID_TIMESTAMP;
+ }
+
+ command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg)
+ {
+ timesync_radio_t* timesync = getFooter(msg);
+ return ((int32_t)(*timesync) >> 5) + call PacketTimeStampMilli.timestamp(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, Brano Kusy
+ *
+ * Interface for one hop time synchronization. Allows to modify timesync
+ * messages in the MAC layer with elapsed time of an event (ETA timesync
+ * primitive). Interface also provides a command to determine offset within
+ * a CC1000 packet, where the timesync ETA value is stored. word 'timestamping'
+ * used in describing commands does not refer to metadata.timestamp value,
+ * rather it refers to the timesync ETA timestamp which is part of data
+ * payload and is transmitted over the air.
+ */
+
+interface PacketTimeSyncOffset
+{
+ /**
+ * @param 'message_t *ONE msg' message to examine.
+ *
+ * Returns TRUE if the current message should be timestamped.
+ */
+ async command bool isSet(message_t* msg);
+
+ /**
+ * @param 'message_t *ONE msg' message to examine.
+ *
+ * Returns the offset of where the timesync timestamp is sotred in a
+ * CC2420 packet
+ */
+ async command uint8_t get(message_t* msg);
+
+ /**
+ * @param 'message_t *ONE msg' message to modify.
+ *
+ * Sets the current message to be timestamped in the MAC layer.
+ */
+ async command void set(message_t* msg);
+
+ /**
+ * @param 'message_t *ONE msg' message to modify.
+ *
+ * Cancels any pending requests to timestamp the message in MAC.
+ */
+ async command void cancel(message_t* msg);
+}
+
--- /dev/null
+/*
+ * "Copyright (c) 2004-2005 The Regents of the University of California.
+ * 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 UNIVERSITY OF CALIFORNIA 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 UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA 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 UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2004-2005 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
+ * 94704. Attention: Intel License Inquiry.
+ */
+
+/**
+ *
+ * The Active Message layer on the mica2 platform. This is a naming wrapper
+ * around the CC1000 Active Message layer that implemets timesync interface (TEP 133).
+ *
+ * @author Philip Levis
+ * @author Brano Kusy
+ * @author Marco Langerwisch (Mica2 port)
+ */
+
+configuration TimeSyncMessageC {
+ provides
+ {
+ interface SplitControl;
+ interface Receive[am_id_t id];
+ interface Receive as Snoop[am_id_t id];
+ interface Packet;
+ interface AMPacket;
+
+ interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+
+ interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[am_id_t id];
+ interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+
+ interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
+ interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+ }
+}
+implementation {
+ components CC1000TimeSyncMessageC as AM;
+
+ SplitControl = AM;
+
+ Receive = AM.Receive;
+ Snoop = AM.Snoop;
+ Packet = AM;
+ AMPacket = AM;
+ TimeSyncAMSend32khz = AM;
+ TimeSyncAMSendMilli = AM;
+ TimeSyncPacket32khz = AM;
+ TimeSyncPacketMilli = AM;
+ PacketTimeStamp32khz = AM;
+ PacketTimeStampMilli = AM;
+}