]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc
automatically request acks for non-broadcast messages in LPL mode
[tinyos-2.x.git] / tos / chips / rf2xx / layers / LowPowerListeningLayerP.nc
index ef4bac568622da67001c384b7a0f47ca8256962b..7efab6dc21311283ac63822f1cb1949b6f7cec5c 100644 (file)
  */
 
 #include <RadioAssert.h>
+#include <LowPowerListeningLayer.h>
+#include <Lpl.h>
 
 module LowPowerListeningLayerP
 {
        provides
        {
                interface SplitControl;
-               interface Send;
-               interface Receive;
+               interface BareSend as Send;
+               interface BareReceive as Receive;
+               interface RadioPacket;
 
                interface LowPowerListening;
        }
@@ -37,13 +40,14 @@ module LowPowerListeningLayerP
        uses
        {
                interface SplitControl as SubControl;
-               interface Send as SubSend;
-               interface Receive as SubReceive;
+               interface BareSend as SubSend;
+               interface BareReceive as SubReceive;
+               interface RadioPacket as SubPacket;
 
-               interface PacketField<uint16_t> as PacketSleepInterval;
-               interface IEEE154Packet;
                interface PacketAcknowledgements;
+               interface LowPowerListeningConfig as Config;
                interface Timer<TMilli>;
+               interface SystemLowPowerListening;
        }
 }
 
@@ -54,21 +58,12 @@ implementation
                // 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;
-       uint8_t txLen;
        error_t txError;
 
 /*----------------- state machine -----------------*/
@@ -77,22 +72,22 @@ implementation
        {
                OFF = 0,                                        
                OFF_SUBSTOP = 1,                        // must have consecutive indices
-               OFF_SUBSTOP_DONE = 2,           // must have consecutive indices
+               OFF_SUBSTOP_DONE = 2,                   // must have consecutive indices
                OFF_STOP_END = 3,                       // must have consecutive indices
                OFF_START_END = 4,
 
-               LISTEN_SUBSTART = 5,            // must have consecutive indices
-               LISTEN_SUBSTART_DONE = 6,       // must have consecutive indices
+               LISTEN_SUBSTART = 5,                    // must have consecutive indices
+               LISTEN_SUBSTART_DONE = 6,               // must have consecutive indices
                LISTEN_TIMER = 7,                       // must have consecutive indices
-               LISTEN = 8,                                     // must have consecutive indices
+               LISTEN = 8,                             // must have consecutive indices
 
                SLEEP_SUBSTOP = 9,                      // must have consecutive indices
-               SLEEP_SUBSTOP_DONE = 10,        // must have consecutive indices
+               SLEEP_SUBSTOP_DONE = 10,                // must have consecutive indices
                SLEEP_TIMER = 11,                       // must have consecutive indices
-               SLEEP = 12,                                     // must have consecutive indices
+               SLEEP = 12,                             // must have consecutive indices
 
                SEND_SUBSTART = 13,                     // must have consecutive indices
-               SEND_SUBSTART_DONE = 14,        // must have consecutive indices
+               SEND_SUBSTART_DONE = 14,                // must have consecutive indices
                SEND_TIMER = 15,                        // must have consecutive indices
                SEND_SUBSEND= 16,
                SEND_SUBSEND_DONE = 17,
@@ -160,7 +155,7 @@ implementation
                }
                else if( state == SEND_TIMER )
                {
-                       transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg);
+                       transmitInterval = call LowPowerListening.getRemoteWakeupInterval(txMsg);
 
                        if( transmitInterval > 0 )
                                call Timer.startOneShot(transmitInterval);
@@ -170,7 +165,7 @@ implementation
                }
                else if( state == SEND_SUBSEND)
                {
-                       txError = call SubSend.send(txMsg, txLen);
+                       txError = call SubSend.send(txMsg);
 
                        if( txError == SUCCESS )
                                state = SEND_SUBSEND_DONE;
@@ -184,7 +179,7 @@ implementation
                {
                        state = LISTEN;
                        if( sleepInterval > 0 )
-                               call Timer.startOneShot(AFTER_TRANSMIT);
+                               call Timer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive());
 
                        signal Send.sendDone(txMsg, txError);
                }
@@ -267,18 +262,18 @@ implementation
                post transition();
        }
 
-       event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
+       event message_t* SubReceive.receive(message_t* msg)
        {
                if( state == SLEEP_SUBSTOP )
                        state = LISTEN;
 
                if( state == LISTEN && sleepInterval > 0 )
-                       call Timer.startOneShot(AFTER_RECEIVE);
+                       call Timer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive());
 
-               return signal Receive.receive(msg, payload, len);
+               return signal Receive.receive(msg);
        }
 
-       command error_t Send.send(message_t* msg, uint8_t len)
+       command error_t Send.send(message_t* msg)
        {
                if( state == LISTEN || state == SLEEP )
                {
@@ -295,8 +290,10 @@ implementation
                else
                        return EBUSY;
 
+               if( call Config.needsAutoAckRequest(msg) )
+                       call PacketAcknowledgements.requestAck(msg);
+
                txMsg = msg;
-               txLen = len;
                txError = FAIL;
 
                return SUCCESS;
@@ -333,9 +330,9 @@ implementation
 
                // 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 IEEE154Packet.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) )
+                       || (call Config.ackRequested(msg) && call PacketAcknowledgements.wasAcked(msg)) )
                {
                        call Timer.stop();
                        state = SEND_DONE;
@@ -346,44 +343,17 @@ implementation
                post transition();
        }
 
-       command uint8_t Send.maxPayloadLength()
-       {
-               return call SubSend.maxPayloadLength();
-       }
-
-       command void* Send.getPayload(message_t* msg, uint8_t len)
-       {
-               return call SubSend.getPayload(msg, len);
-       }
-
 /*----------------- LowPowerListening -----------------*/
 
-       command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle)
+       lpl_metadata_t* getMeta(message_t* msg)
        {
-               if( dutyCycle >= 10000 )
-                       return 0;
-               else if( dutyCycle <= MIN_DUTY  )
-                       return MAX_SLEEP;
-
-               return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP;
+               return ((void*)msg) + sizeof(message_t) - call RadioPacket.metadataLength(msg);
        }
 
-       command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval)
+       command void LowPowerListening.setLocalWakeupInterval(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)
-    {
                if( interval < MIN_SLEEP )
                        interval = 0;
-               else if( interval > MAX_SLEEP )
-                       interval = MAX_SLEEP;
 
                sleepInterval = interval;
 
@@ -395,49 +365,54 @@ implementation
                }
        }
 
-       command uint16_t LowPowerListening.getLocalSleepInterval()
-    {  
+       command uint16_t LowPowerListening.getLocalWakeupInterval()
+       {       
                return sleepInterval;
        }
 
-       command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle)
+       command void LowPowerListening.setRemoteWakeupInterval(message_t *msg, uint16_t interval)
        {
-               call LowPowerListening.setLocalSleepInterval(
-                       call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
+               if( interval < MIN_SLEEP )
+                       interval = 0;
+
+               getMeta(msg)->sleepint = interval;
        }
 
-       command uint16_t LowPowerListening.getLocalDutyCycle()
+       command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg)
        {
-               return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval);
+               return getMeta(msg)->sleepint;
        }
 
-       command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval)
+/*----------------- RadioPacket -----------------*/
+       
+       async command uint8_t RadioPacket.headerLength(message_t* msg)
        {
-               if( interval < MIN_SLEEP )
-                       interval = 0;
-               else if( interval > MAX_SLEEP )
-                       interval = MAX_SLEEP;
+               return call SubPacket.headerLength(msg);
+       }
 
-               call PacketSleepInterval.set(msg, interval);
+       async command uint8_t RadioPacket.payloadLength(message_t* msg)
+       {
+               return call SubPacket.payloadLength(msg);
        }
 
-       command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg)
-    {
-               if( ! call PacketSleepInterval.isSet(msg) )
-                       return sleepInterval;
+       async command void RadioPacket.setPayloadLength(message_t* msg, uint8_t length)
+       {
+               call SubPacket.setPayloadLength(msg, length);
+       }
 
-               return call PacketSleepInterval.get(msg);
+       async command uint8_t RadioPacket.maxPayloadLength()
+       {
+               return call SubPacket.maxPayloadLength();
        }
 
-       command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle)
-    {
-               call LowPowerListening.setRxSleepInterval(msg, 
-                       call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
+       async command uint8_t RadioPacket.metadataLength(message_t* msg)
+       {
+               return call SubPacket.metadataLength(msg) + sizeof(lpl_metadata_t);
        }
 
-       command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg)
-    {
-               return call LowPowerListening.sleepIntervalToDutyCycle(
-                       call LowPowerListening.getRxSleepInterval(msg));
+       async command void RadioPacket.clear(message_t* msg)
+       {
+               getMeta(msg)->sleepint = 0;
+               call SubPacket.clear(msg);
        }
 }