implementation {
components TestNetworkC, MainC, LedsC, ActiveMessageC;
components DisseminationC;
- components new DisseminatorC(uint16_t, SAMPLE_RATE_KEY) as Object16C;
+ components new DisseminatorC(uint32_t, SAMPLE_RATE_KEY) as Object32C;
components CollectionC as Collector;
components new CollectionSenderC(CL_TEST);
components new TimerMilliC();
TestNetworkC.DisseminationControl -> DisseminationC;
TestNetworkC.Leds -> LedsC;
TestNetworkC.Timer -> TimerMilliC;
- TestNetworkC.DisseminationPeriod -> Object16C;
+ TestNetworkC.DisseminationPeriod -> Object32C;
TestNetworkC.Send -> CollectionSenderC;
TestNetworkC.ReadSensor -> DemoSensorC;
TestNetworkC.RootControl -> Collector;
uses interface SplitControl as SerialControl;
uses interface StdControl as RoutingControl;
uses interface StdControl as DisseminationControl;
- uses interface DisseminationValue<uint16_t> as DisseminationPeriod;
+ uses interface DisseminationValue<uint32_t> as DisseminationPeriod;
uses interface Send;
uses interface Leds;
uses interface Read<uint16_t> as ReadSensor;
void sendMessage() {
TestNetworkMsg* msg = (TestNetworkMsg*)call Send.getPayload(&packet, sizeof(TestNetworkMsg));
uint16_t metric;
- am_addr_t parent;
+ am_addr_t parent = 0;
call CtpInfo.getParent(&parent);
call CtpInfo.getEtx(&metric);
event void Timer.fired() {
- uint16_t nextInt;
+ uint32_t nextInt;
call Leds.led0Toggle();
dbg("TestNetworkC", "TestNetworkC: Timer fired.\n");
- nextInt = call Random.rand16() % SEND_INTERVAL;
+ nextInt = call Random.rand32() % SEND_INTERVAL;
nextInt += SEND_INTERVAL >> 1;
call Timer.startOneShot(nextInt);
if (!sendBusy)
}
event void DisseminationPeriod.changed() {
- const uint16_t* newVal = call DisseminationPeriod.get();
+ const uint32_t* newVal = call DisseminationPeriod.get();
call Timer.stop();
call Timer.startPeriodic(*newVal);
}
#define TINYOS_6LOWPAN_NETWORK_ID 0x3f
#endif
+/**
+ * The LPL defaults to stay-on.
+ */
+#ifndef LPL_DEF_LOCAL_WAKEUP
+#define LPL_DEF_LOCAL_WAKEUP 0
+#endif
+
+#ifndef LPL_DEF_REMOTE_WAKEUP
+#define LPL_DEF_REMOTE_WAKEUP 0
+#endif
+
enum {
// size of the header not including the length byte
MAC_HEADER_SIZE = sizeof( cc2420_header_t ) - 1,
new StateC() as SendStateC,
new TimerMilliC() as OffTimerC,
new TimerMilliC() as SendDoneTimerC,
+ SystemLowPowerListeningC,
LedsC;
LowPowerListening = DefaultLplP;
DefaultLplP.RadioBackoff -> CC2420CsmaC;
DefaultLplP.Random -> RandomC;
DefaultLplP.Leds -> LedsC;
-
+ DefaultLplP.SystemLowPowerListening -> SystemLowPowerListeningC;
}
interface Timer<TMilli> as SendDoneTimer;
interface Random;
interface Leds;
+ interface SystemLowPowerListening;
}
}
void initializeSend();
void startOffTimer();
- uint16_t getActualDutyCycle(uint16_t dutyCycle);
/***************** Init Commands ***************/
command error_t Init.init() {
/***************** LowPowerListening Commands ***************/
/**
- * Set this this node's radio sleep interval, in milliseconds.
+ * Set this this node's radio wakeup interval, in milliseconds.
* Once every interval, the node will sleep and perform an Rx check
- * on the radio. Setting the sleep interval to 0 will keep the radio
+ * on the radio. Setting the wakeup interval to 0 will keep the radio
* always on.
*
- * This is the equivalent of setting the local duty cycle rate.
- *
- * @param sleepIntervalMs the length of this node's Rx check interval, in [ms]
+ * @param intervalMs the length of this node's wakeup interval, in [ms]
*/
- command void LowPowerListening.setLocalSleepInterval(
- uint16_t sleepIntervalMs) {
- call PowerCycle.setSleepInterval(sleepIntervalMs);
+ command void LowPowerListening.setLocalWakeupInterval(uint16_t intervalMs) {
+ call PowerCycle.setSleepInterval(intervalMs);
}
/**
- * @return the local node's sleep interval, in [ms]
+ * @return the local node's wakeup interval, in [ms]
*/
- command uint16_t LowPowerListening.getLocalSleepInterval() {
+ command uint16_t LowPowerListening.getLocalWakeupInterval() {
return call PowerCycle.getSleepInterval();
}
- /**
- * Set this node's radio duty cycle rate, in units of [percentage*100].
- * For example, to get a 0.05% duty cycle,
- * <code>
- * call LowPowerListening.setDutyCycle(5);
- * </code>
- *
- * For a 100% duty cycle (always on),
- * <code>
- * call LowPowerListening.setDutyCycle(10000);
- * </code>
- *
- * This is the equivalent of setting the local sleep interval explicitly.
- *
- * @param dutyCycle The duty cycle percentage, in units of [percentage*100]
- */
- command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) {
- call PowerCycle.setSleepInterval(
- call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
- }
-
- /**
- * @return this node's radio duty cycle rate, in units of [percentage*100]
- */
- command uint16_t LowPowerListening.getLocalDutyCycle() {
- return call LowPowerListening.sleepIntervalToDutyCycle(
- call PowerCycle.getSleepInterval());
- }
-
-
/**
* Configure this outgoing message so it can be transmitted to a neighbor mote
- * with the specified Rx sleep interval.
+ * with the specified wakeup interval.
* @param msg Pointer to the message that will be sent
- * @param sleepInterval The receiving node's sleep interval, in [ms]
+ * @param intervalMs The receiving node's wakeup interval, in [ms]
*/
- command void LowPowerListening.setRxSleepInterval(message_t *msg,
- uint16_t sleepIntervalMs) {
- (call CC2420PacketBody.getMetadata(msg))->rxInterval = sleepIntervalMs;
+ command void LowPowerListening.setRemoteWakeupInterval(message_t *msg,
+ uint16_t intervalMs) {
+ (call CC2420PacketBody.getMetadata(msg))->rxInterval = intervalMs;
}
/**
- * @return the destination node's sleep interval configured in this message
+ * @return the destination node's wakeup interval configured in this message
*/
- command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) {
+ command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) {
return (call CC2420PacketBody.getMetadata(msg))->rxInterval;
}
- /**
- * Configure this outgoing message so it can be transmitted to a neighbor mote
- * with the specified Rx duty cycle rate.
- * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.
- *
- * @param msg Pointer to the message that will be sent
- * @param dutyCycle The duty cycle of the receiving mote, in units of
- * [percentage*100]
- */
- command void LowPowerListening.setRxDutyCycle(message_t *msg,
- uint16_t dutyCycle) {
- (call CC2420PacketBody.getMetadata(msg))->rxInterval =
- call LowPowerListening.dutyCycleToSleepInterval(dutyCycle);
- }
-
-
- /**
- * @return the destination node's duty cycle configured in this message
- * in units of [percentage*100]
- */
- command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) {
- return call LowPowerListening.sleepIntervalToDutyCycle(
- (call CC2420PacketBody.getMetadata(msg))->rxInterval);
- }
-
- /**
- * Convert a duty cycle, in units of [percentage*100], to
- * the sleep interval of the mote in milliseconds
- * @param dutyCycle The duty cycle in units of [percentage*100]
- * @return The equivalent sleep interval, in units of [ms]
- */
- command uint16_t LowPowerListening.dutyCycleToSleepInterval(
- uint16_t dutyCycle) {
- dutyCycle = getActualDutyCycle(dutyCycle);
-
- if(dutyCycle == 10000) {
- return 0;
- }
-
- return ((uint32_t)DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle;
- }
-
- /**
- * Convert a sleep interval, in units of [ms], to a duty cycle
- * in units of [percentage*100]
- * @param sleepInterval The sleep interval in units of [ms]
- * @return The duty cycle in units of [percentage*100]
- */
- command uint16_t LowPowerListening.sleepIntervalToDutyCycle(
- uint16_t sleepInterval) {
- if(sleepInterval == 0) {
- return 10000;
- }
-
- return getActualDutyCycle(((uint32_t)DUTY_ON_TIME * 10000)
- / (sleepInterval + DUTY_ON_TIME));
- }
-
-
/***************** Send Commands ***************/
/**
* Each call to this send command gives the message a single
/***************** Functions ***************/
void initializeSend() {
- if(call LowPowerListening.getRxSleepInterval(currentSendMsg)
+ if(call LowPowerListening.getRemoteWakeupInterval(currentSendMsg)
> ONE_MESSAGE) {
if((call CC2420PacketBody.getHeader(currentSendMsg))->dest == IEEE154_BROADCAST_ADDR) {
}
call SendDoneTimer.startOneShot(
- call LowPowerListening.getRxSleepInterval(currentSendMsg) + 20);
+ call LowPowerListening.getRemoteWakeupInterval(currentSendMsg) + 20);
}
post send();
void startOffTimer() {
- call OffTimer.startOneShot(DELAY_AFTER_RECEIVE);
+ call OffTimer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive());
}
- /**
- * Check the bounds on a given duty cycle
- * We're never over 100%, and we're never at 0%
- */
- uint16_t getActualDutyCycle(uint16_t dutyCycle) {
- if(dutyCycle > 10000) {
- return 10000;
- } else if(dutyCycle == 0) {
- return 1;
- }
-
- return dutyCycle;
- }
}
/**
* Dummy low power listening interface used when LowPowerListening is not
* compiled in with the application.
- * Sleep interval is always 0, and duty cycle is always 100%
+ * Wakeup interval is always 0 (always on)
* @author David Moss
*/
implementation {
- command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) {
+ command void LowPowerListening.setLocalWakeupInterval(uint16_t intervalMs) {
}
- command uint16_t LowPowerListening.getLocalSleepInterval() {
+ command uint16_t LowPowerListening.getLocalWakeupInterval() {
return 0;
}
- command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) {
+ command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t intervalMs) {
}
- command uint16_t LowPowerListening.getLocalDutyCycle() {
- return 10000;
- }
-
- command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) {
- }
-
- command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) {
+ command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) {
return 0;
}
- command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) {
- }
-
- command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) {
- return 10000;
- }
-
- command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) {
- return 0;
- }
-
- command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) {
- return 10000;
- }
-
}
PowerCycleP.SplitControlState -> SplitControlStateC;
PowerCycleP.OnTimer -> OnTimerC;
PowerCycleP.Leds -> LedsC;
-
}
implementation {
/** The current period of the duty cycle, equivalent of wakeup interval */
- uint16_t sleepInterval = 0;
+ uint16_t sleepInterval = LPL_DEF_LOCAL_WAKEUP;
/** The number of times the CCA has been sampled in this wakeup period */
uint16_t ccaChecks;
bool finishSplitControlRequests();
bool isDutyCycling();
-
/***************** PowerCycle Commands ****************/
/**
* Set the sleep interval, in binary milliseconds
implementation
{
- command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { }
+ command void LowPowerListening.setLocalWakeupInterval(uint16_t intervalMs) { }
- command uint16_t LowPowerListening.getLocalSleepInterval() { return 0; }
+ command uint16_t LowPowerListening.getLocalWakeupInterval() { return 0; }
- command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { }
+ command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t intervalMs) { }
- command uint16_t LowPowerListening.getLocalDutyCycle() { return 10000; }
-
- command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { }
-
- command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return 0; }
-
- command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { }
-
- command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return 10000; }
-
- command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { return 0; }
-
- command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { return 10000; }
+ command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) { return 0; }
}
implementation
{
components LowPowerListeningLayerP, new TimerMilliC();
+ components SystemLowPowerListeningC;
SplitControl = LowPowerListeningLayerP;
Send = LowPowerListeningLayerP;
PacketAcknowledgements = LowPowerListeningLayerP;
LowPowerListeningLayerP.Timer -> TimerMilliC;
+ LowPowerListeningLayerP.SystemLowPowerListening -> SystemLowPowerListeningC;
}
interface PacketAcknowledgements;
interface LowPowerListeningConfig as Config;
interface Timer<TMilli>;
+ interface SystemLowPowerListening;
}
}
// minimum wakeup time to catch a transmission in milliseconds
LISTEN_WAKEUP = 6U, // use xxxL if LISTEN_WAKEUP * 10000 > 65535
- // extra wakeup time after receiving a message in milliseconds
- AFTER_RECEIVE = 10U,
-
- // extra wakeup time after transmitting a message in milliseconds
- AFTER_TRANSMIT = 10U,
-
MIN_SLEEP = 2, // the minimum sleep interval in milliseconds
MAX_SLEEP = 30000, // the maximum sleep interval in milliseconds
MIN_DUTY = 2, // the minimum duty cycle
};
- uint16_t sleepInterval;
+ uint16_t sleepInterval = LPL_DEF_LOCAL_WAKEUP;
message_t* txMsg;
error_t txError;
}
else if( state == SEND_TIMER )
{
- transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg);
+ transmitInterval = call LowPowerListening.getRemoteWakeupInterval(txMsg);
if( transmitInterval > 0 )
call Timer.startOneShot(transmitInterval);
{
state = LISTEN;
if( sleepInterval > 0 )
- call Timer.startOneShot(AFTER_TRANSMIT);
+ call Timer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive());
signal Send.sendDone(txMsg, txError);
}
state = LISTEN;
if( state == LISTEN && sleepInterval > 0 )
- call Timer.startOneShot(AFTER_RECEIVE);
+ call Timer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive());
return signal Receive.receive(msg);
}
// TODO: extend the PacketAcknowledgements interface with getAckRequired
if( error != SUCCESS
- || call LowPowerListening.getRxSleepInterval(msg) == 0
+ || call LowPowerListening.getRemoteWakeupInterval(msg) == 0
|| state == SEND_SUBSEND_DONE_LAST
|| (call Config.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) )
{
return ((void*)msg) + sizeof(message_t) - call RadioPacket.metadataLength(msg);
}
- command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle)
- {
- if( dutyCycle >= 10000 )
- return 0;
- else if( dutyCycle <= MIN_DUTY )
- return MAX_SLEEP;
-
- return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP;
- }
-
- command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval)
- {
- if( interval < MIN_SLEEP )
- return 10000;
- else if( interval >= MAX_SLEEP )
- return MIN_DUTY;
-
- return (10000U * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval);
- }
-
- command void LowPowerListening.setLocalSleepInterval(uint16_t interval)
+ command void LowPowerListening.setLocalWakeupInterval(uint16_t interval)
{
if( interval < MIN_SLEEP )
interval = 0;
}
}
- command uint16_t LowPowerListening.getLocalSleepInterval()
+ command uint16_t LowPowerListening.getLocalWakeupInterval()
{
return sleepInterval;
}
- command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle)
- {
- call LowPowerListening.setLocalSleepInterval(
- call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
- }
-
- command uint16_t LowPowerListening.getLocalDutyCycle()
- {
- return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval);
- }
-
- command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval)
+ command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t interval)
{
if( interval < MIN_SLEEP )
interval = 0;
getMeta(msg)->sleepint = interval;
}
- command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg)
+ command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg)
{
return getMeta(msg)->sleepint;
}
- command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle)
- {
- call LowPowerListening.setRxSleepInterval(msg,
- call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
- }
-
- command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg)
- {
- return call LowPowerListening.sleepIntervalToDutyCycle(
- call LowPowerListening.getRxSleepInterval(msg));
- }
-
/*----------------- RadioPacket -----------------*/
async command uint8_t RadioPacket.headerLength(message_t* msg)
* @author Jonathan Hui
* @author David Moss
*/
-
+
#include "message.h"
-
-interface LowPowerListening {
+interface LowPowerListening {
/**
- * Set this this node's radio sleep interval, in milliseconds.
- * Once every interval, the node will sleep and perform an Rx check
- * on the radio. Setting the sleep interval to 0 will keep the radio
- * always on.
- *
- * This is the equivalent of setting the local duty cycle rate.
- *
- * @param sleepIntervalMs the length of this node's Rx check interval, in [ms]
- */
- command void setLocalSleepInterval(uint16_t sleepIntervalMs);
-
- /**
- * @return the local node's sleep interval, in [ms]
- */
- command uint16_t getLocalSleepInterval();
-
- /**
- * Set this node's radio duty cycle rate, in units of [percentage*100].
- * For example, to get a 0.05% duty cycle,
- * <code>
- * call LowPowerListening.setDutyCycle(5);
- * </code>
+ * Set this this node's radio wakeup interval, in milliseconds. After
+ * each interval, the node will wakeup and check for radio activity.
*
- * For a 100% duty cycle (always on),
- * <code>
- * call LowPowerListening.setDutyCycle(10000);
- * </code>
+ * Note: The wakeup interval can be set to 0 to indicate that the radio
+ * should stay on all the time but in order to get a startDone this
+ * should only be done when the duty-cycling is off (after a stopDone).
*
- * This is the equivalent of setting the local sleep interval explicitly.
- *
- * @param dutyCycle The duty cycle percentage, in units of [percentage*100]
- */
- command void setLocalDutyCycle(uint16_t dutyCycle);
-
- /**
- * @return this node's radio duty cycle rate, in units of [percentage*100]
- */
- command uint16_t getLocalDutyCycle();
-
-
- /**
- * Configure this outgoing message so it can be transmitted to a neighbor mote
- * with the specified Rx sleep interval.
- * @param 'message_t* ONE msg' Pointer to the message that will be sent
- * @param sleepInterval The receiving node's sleep interval, in [ms]
+ * @param intervalMs the length of this node's Rx check interval, in [ms]
*/
- command void setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs);
+ command void setLocalWakeupInterval(uint16_t intervalMs);
/**
- * @param 'message_t* ONE msg'
- * @return the destination node's sleep interval configured in this message
+ * @return the local node's wakeup interval, in [ms]
*/
- command uint16_t getRxSleepInterval(message_t *msg);
-
+ command uint16_t getLocalWakeupInterval();
+
/**
* Configure this outgoing message so it can be transmitted to a neighbor mote
- * with the specified Rx duty cycle rate.
- * Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.
- *
+ * with the specified wakeup interval.
* @param 'message_t* ONE msg' Pointer to the message that will be sent
- * @param dutyCycle The duty cycle of the receiving mote, in units of
- * [percentage*100]
+ * @param intervalMs The receiving node's wakeup interval, in [ms]
*/
- command void setRxDutyCycle(message_t *msg, uint16_t dutyCycle);
-
+ command void setRemoteWakeupInterval(message_t *msg, uint16_t intervalMs);
+
/**
* @param 'message_t* ONE msg'
- * @return the destination node's duty cycle configured in this message
- * in units of [percentage*100]
- */
- command uint16_t getRxDutyCycle(message_t *msg);
-
- /**
- * Convert a duty cycle, in units of [percentage*100], to
- * the sleep interval of the mote in milliseconds
- * @param dutyCycle The duty cycle in units of [percentage*100]
- * @return The equivalent sleep interval, in units of [ms]
+ * @return the destination node's wakeup interval configured in this message
*/
- command uint16_t dutyCycleToSleepInterval(uint16_t dutyCycle);
-
- /**
- * Convert a sleep interval, in units of [ms], to a duty cycle
- * in units of [percentage*100]
- * @param sleepInterval The sleep interval in units of [ms]
- * @return The duty cycle in units of [percentage*100]
- */
- command uint16_t sleepIntervalToDutyCycle(uint16_t sleepInterval);
-
+ command uint16_t getRemoteWakeupInterval(message_t *msg);
}
--- /dev/null
+interface SystemLowPowerListening
+{
+ command void setDefaultRemoteWakeupInterval(uint16_t intervalMs);
+ command void setDelayAfterReceive(uint16_t intervalMs);
+
+ command uint16_t getDefaultRemoteWakeupInterval();
+ command uint16_t getDelayAfterReceive();
+}
/**
*
- * The Active Message layer on the micaZ platform. This is a naming wrapper
+ * The Active Message layer on the Telos platform. This is a naming wrapper
* around the CC2420 Active Message layer.
*
* @author Philip Levis
- * @date June 19 2005
+ * @version $Revision$ $Date$
*/
#include "Timer.h"
interface PacketAcknowledgements;
interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ interface LowPowerListening;
}
}
implementation {
components CC2420ActiveMessageC as AM;
-
+
SplitControl = AM;
AMSend = AM;
Packet = AM;
AMPacket = AM;
PacketAcknowledgements = AM;
+ LowPowerListening = AM;
components CC2420PacketC;
PacketTimeStamp32khz = CC2420PacketC;
interface PacketAcknowledgements;
interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ interface LowPowerListening;
}
}
implementation {
Packet = AM;
AMPacket = AM;
PacketAcknowledgements = AM;
+ LowPowerListening = AM;
components CC2420PacketC;
PacketTimeStamp32khz = CC2420PacketC;
}
implementation {
- components new AMQueueEntryP(AMId) as AMQueueEntryP;
- components AMQueueP, ActiveMessageC;
- AMQueueEntryP.Send -> AMQueueP.Send[unique(UQ_AMQUEUE_SEND)];
- AMQueueEntryP.AMPacket -> ActiveMessageC;
-
- AMSend = AMQueueEntryP;
- Packet = ActiveMessageC;
- AMPacket = ActiveMessageC;
- Acks = ActiveMessageC;
+#if defined(LOW_POWER_LISTENING)
+ components new LplAMSenderC(AMId) as SenderC;
+#else
+ components new DirectAMSenderC(AMId) as SenderC;
+#endif
+
+ AMSend = SenderC;
+ Packet = SenderC;
+ AMPacket = SenderC;
+ Acks = SenderC;
}
--- /dev/null
+// $Id$
+/*
+ * "Copyright (c) 2006 Stanford 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 STANFORD 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 STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * STANFORD 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 STANFORD UNIVERSITY
+ * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS."
+ */
+
+/**
+ * The virtualized active message send abstraction. Each instantiation
+ * of AMSenderC has its own queue of depth one. Therefore, it does not
+ * have to contend with other AMSenderC instantiations for queue space.
+ * The underlying implementation schedules the packets in these queues
+ * using some form of fair-share queueing.
+ *
+ * @author Philip Levis
+ * @date Jan 16 2006
+ * @see TEP 116: Packet Protocols
+ */
+
+#include "AM.h"
+
+generic configuration DirectAMSenderC(am_id_t AMId) {
+ provides {
+ interface AMSend;
+ interface Packet;
+ interface AMPacket;
+ interface PacketAcknowledgements as Acks;
+ }
+}
+
+implementation {
+ components new AMQueueEntryP(AMId) as AMQueueEntryP;
+ components AMQueueP, ActiveMessageC;
+
+ AMQueueEntryP.Send -> AMQueueP.Send[unique(UQ_AMQUEUE_SEND)];
+ AMQueueEntryP.AMPacket -> ActiveMessageC;
+
+ AMSend = AMQueueEntryP;
+ Packet = ActiveMessageC;
+ AMPacket = ActiveMessageC;
+ Acks = ActiveMessageC;
+}
--- /dev/null
+#include "AM.h"
+
+generic configuration LplAMSenderC(am_id_t AMId)
+{
+ provides {
+ interface AMSend;
+ interface Packet;
+ interface AMPacket;
+ interface PacketAcknowledgements as Acks;
+ }
+}
+
+implementation
+{
+ components new DirectAMSenderC(AMId);
+ components new LplAMSenderP();
+ components ActiveMessageC;
+ components SystemLowPowerListeningC;
+
+ AMSend = LplAMSenderP;
+ Packet = DirectAMSenderC;
+ AMPacket = DirectAMSenderC;
+ Acks = DirectAMSenderC;
+
+ LplAMSenderP.SubAMSend -> DirectAMSenderC;
+ LplAMSenderP.Lpl -> ActiveMessageC;
+ LplAMSenderP.SystemLowPowerListening -> SystemLowPowerListeningC;
+}
--- /dev/null
+generic module LplAMSenderP()
+{
+ provides interface AMSend;
+ uses {
+ interface AMSend as SubAMSend;
+ interface LowPowerListening as Lpl;
+ interface SystemLowPowerListening;
+ }
+}
+
+implementation
+{
+ event void SubAMSend.sendDone(message_t* msg, error_t error)
+ {
+ call Lpl.setRemoteWakeupInterval(msg, call SystemLowPowerListening.getDefaultRemoteWakeupInterval());
+ signal AMSend.sendDone(msg, error);
+ }
+
+ command error_t AMSend.send(am_addr_t addr, message_t* msg, uint8_t len) { return call SubAMSend.send(addr, msg, len); }
+ command error_t AMSend.cancel(message_t* msg) { return call SubAMSend.cancel(msg); }
+ command uint8_t AMSend.maxPayloadLength() { return call SubAMSend.maxPayloadLength(); }
+ command void* AMSend.getPayload(message_t* msg, uint8_t len) { return call SubAMSend.getPayload(msg, len); }
+}
--- /dev/null
+configuration SystemLowPowerListeningC
+{
+ provides interface SystemLowPowerListening;
+}
+
+implementation
+{
+ components SystemLowPowerListeningP;
+ SystemLowPowerListening = SystemLowPowerListeningP;
+}
--- /dev/null
+module SystemLowPowerListeningP
+{
+ provides interface SystemLowPowerListening;
+}
+
+implementation
+{
+ uint16_t remoteWakeup = LPL_DEF_REMOTE_WAKEUP;
+ uint16_t delayAfterReceive = DELAY_AFTER_RECEIVE;
+
+ command void SystemLowPowerListening.setDefaultRemoteWakeupInterval(uint16_t intervalMs) { remoteWakeup = intervalMs; }
+ command void SystemLowPowerListening.setDelayAfterReceive(uint16_t intervalMs) { delayAfterReceive = intervalMs; }
+
+ command uint16_t SystemLowPowerListening.getDefaultRemoteWakeupInterval() { return remoteWakeup; }
+ command uint16_t SystemLowPowerListening.getDelayAfterReceive() { return delayAfterReceive; }
+}