* @author David Moss
*/
+#include "Lpl.h"
#include "DefaultLpl.h"
#include "AM.h"
uses {
interface Send as SubSend;
interface CC2420Transmit as Resend;
- interface RadioBackoff[am_id_t amId];
+ interface RadioBackoff;
interface Receive as SubReceive;
- interface AMPacket;
interface SplitControl as SubControl;
interface PowerCycle;
interface CC2420PacketBody;
interface Timer<TMilli> as SendDoneTimer;
interface Random;
interface Leds;
+ interface SystemLowPowerListening;
}
}
bool dutyCycling;
/**
- * Radio State
+ * Radio Power State
*/
enum {
- S_OFF,
+ S_OFF, // off by default
+ S_TURNING_ON,
S_ON,
+ S_TURNING_OFF,
};
/**
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 (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((DUTY_ON_TIME * 10000)
- / (sleepInterval + DUTY_ON_TIME));
- }
-
-
/***************** Send Commands ***************/
/**
* Each call to this send command gives the message a single
return SUCCESS;
}
- return FAIL;
+ return EBUSY;
}
command error_t Send.cancel(message_t *msg) {
return call SubSend.maxPayloadLength();
}
- command void *Send.getPayload(message_t* msg) {
- return call SubSend.getPayload(msg);
+ command void *Send.getPayload(message_t* msg, uint8_t len) {
+ return call SubSend.getPayload(msg, len);
}
/***************** RadioBackoff Events ****************/
- async event void RadioBackoff.requestInitialBackoff[am_id_t amId](message_t *msg) {
+ async event void RadioBackoff.requestInitialBackoff(message_t *msg) {
if((call CC2420PacketBody.getMetadata(msg))->rxInterval
> ONE_MESSAGE) {
- call RadioBackoff.setInitialBackoff[amId]( call Random.rand16()
+ call RadioBackoff.setInitialBackoff( call Random.rand16()
% (0x4 * CC2420_BACKOFF_PERIOD) + CC2420_MIN_BACKOFF);
}
}
- async event void RadioBackoff.requestCongestionBackoff[am_id_t amId](message_t *msg) {
+ async event void RadioBackoff.requestCongestionBackoff(message_t *msg) {
if((call CC2420PacketBody.getMetadata(msg))->rxInterval
> ONE_MESSAGE) {
- call RadioBackoff.setCongestionBackoff[amId]( call Random.rand16()
+ call RadioBackoff.setCongestionBackoff( call Random.rand16()
% (0x3 * CC2420_BACKOFF_PERIOD) + CC2420_MIN_BACKOFF);
}
}
- async event void RadioBackoff.requestCca[am_id_t amId](message_t *msg) {
+ async event void RadioBackoff.requestCca(message_t *msg) {
}
- /***************** Receive Commands ***************/
- command void *Receive.getPayload(message_t* msg, uint8_t* len) {
- return call SubReceive.getPayload(msg, len);
- }
-
- command uint8_t Receive.payloadLength(message_t* msg) {
- return call SubReceive.payloadLength(msg);
- }
-
/***************** DutyCycle Events ***************/
/**
// just a little longer in case there is more than one lpl transmitter on
// the channel.
- if(call SendState.isIdle()) {
- startOffTimer();
- }
+ startOffTimer();
}
}
/***************** Timer Events ****************/
- event void OffTimer.fired() {
+ event void OffTimer.fired() {
/*
* Only stop the radio if the radio is supposed to be off permanently
* or if the duty cycle is on and our sleep interval is not 0
*/
if(call SplitControlState.getState() == S_OFF
|| (call PowerCycle.getSleepInterval() > 0
- && call SplitControlState.getState() == S_ON
+ && call SplitControlState.getState() != S_OFF
&& call SendState.getState() == S_LPL_NOT_SENDING)) {
post stopRadio();
}
/***************** Functions ***************/
void initializeSend() {
- if(call LowPowerListening.getRxSleepInterval(currentSendMsg)
+ if(call LowPowerListening.getRemoteWakeupInterval(currentSendMsg)
> ONE_MESSAGE) {
- if(call AMPacket.destination(currentSendMsg) == AM_BROADCAST_ADDR) {
+ if((call CC2420PacketBody.getHeader(currentSendMsg))->dest == IEEE154_BROADCAST_ADDR) {
call PacketAcknowledgements.noAck(currentSendMsg);
} else {
// Send it repetitively within our transmit window
}
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;
- }
}