]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/tda5250/mac/RedMacP.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / chips / tda5250 / mac / RedMacP.nc
index 1a8600f7a1f016e37df9404e5558bd4c06b2295f..d0de4d0e4b5f0aba95df81735928e491a80095f1 100644 (file)
 #include "PacketAck.h"
 #include "RedMac.h"
 
-// #define MACM_DEBUG                    // debug...
+#ifdef DELTATIMEDEBUG
+#include "DeltaTrace.h"
+#endif
+
 module RedMacP {
     provides {
         interface Init;
@@ -47,11 +50,12 @@ module RedMacP {
         interface MacSend;
         interface MacReceive;
         interface Packet;
-        interface LocalTime<T32khz> as LocalTime32khz;
-        interface SleepTime;
+        interface Sleeptime;
         interface Teamgeist;
         interface ChannelCongestion;
-        interface McuPowerOverride;
+#ifdef MAC_EVAL
+        interface MacEval;
+#endif
     }
     uses {
         interface StdControl as CcaStdControl;
@@ -74,13 +78,27 @@ module RedMacP {
         
         interface Alarm<T32khz, uint16_t> as Timer;
         interface Alarm<T32khz, uint16_t> as SampleTimer;
-        interface Counter<T32khz,uint16_t> as Counter32khz16;
+        interface LocalTime<T32khz> as LocalTime32kHz;
+
+        interface Duplicate;
+        interface TimeDiff16;
+        interface TimeDiff32;
+        
         async command am_addr_t amAddress();
-#ifdef MACM_DEBUG
+/*
         interface GeneralIO as Led0;
         interface GeneralIO as Led1;
         interface GeneralIO as Led2;
-        interface GeneralIO as Led3;
+        interface GeneralIO as Led3;        
+*/  
+#ifdef REDMAC_DEBUG
+        interface SerialDebug;
+#endif
+#ifdef REDMAC_PERFORMANCE
+        interface Performance;
+#endif
+#ifdef DELTATIMEDEBUG
+        interface DeltaTrace;
 #endif
     }
 }
@@ -104,134 +122,73 @@ implementation
     macState_t macState;
 
     /****** debug vars & defs & functions  ***********************/
-#ifdef MACM_DEBUG
-#define HISTORY_ENTRIES 60
-    typedef struct {
-        int index;
-        macState_t state;
-        int        place;
-    } history_t;
-    
-    history_t history[HISTORY_ENTRIES];
-    unsigned histIndex;
-    void storeOldState(int p) {
-        atomic {
-            history[histIndex].index = histIndex;
-            history[histIndex].state = macState;
-            history[histIndex].place = p;
-            histIndex++;
-            if(histIndex >= HISTORY_ENTRIES) histIndex = 0;
-        }
+#ifdef REDMAC_DEBUG
+    void sdDebug(uint16_t p) {
+        call SerialDebug.putPlace(p);
     }
+    uint8_t repCounter;
 #else
-    void storeOldState(int p) {};
-#endif
-
-    void signalFailure(uint8_t place) {
-#ifdef MACM_DEBUG
-        unsigned long i,j;
-        atomic {
-            for(;;) {
-                call Led0.clr();
-                call Led1.clr();
-                call Led2.clr();
-                call Led3.clr();
-                
-                for(i = 0; i < 100; i++) {
-                    for(j=0; j < 200; j++) {
-                        (i & 1) ? call Led0.set() : call Led0.clr();
-                    }
-                    for(j=0; j < 200; j++) {
-                        (i & 2) ? call Led1.set() : call Led1.clr();
-                    }
-                    for(j=0; j < 200; j++) {
-                        (i & 4) ? call Led2.set() : call Led2.clr();
-                    }
-                    for(j=0; j < 200; j++) {
-                        (i & 8) ? call Led3.set() : call Led3.clr();
-                    }
-                }
-
-                (place & 1) ? call Led0.set() : call Led0.clr();
-                (place & 2) ? call Led1.set() : call Led1.clr();
-                (place & 4) ? call Led2.set() : call Led2.clr();
-                (place & 8) ? call Led3.set() : call Led3.clr();
-
-                for(i = 0; i < 1000000; i++) {
-                    ;
-                }
-
-                (macState & 1) ? call Led0.set() : call Led0.clr();
-                (macState & 2) ? call Led1.set() : call Led1.clr();
-                (macState & 4) ? call Led2.set() : call Led2.clr();
-                (macState & 8) ? call Led3.set() : call Led3.clr();
-
-                for(i = 0; i < 1000000; i++) {
-                    ;
-                }
-            }
-        }
+    void sdDebug(uint16_t p) {};
 #endif
-    }
-
-    void signalMacState() {
-#ifdef MACM_DEBUG
-/*         (macState & 1) ? call Led0.set() : call Led0.clr();
-         (macState & 2) ? call Led1.set() : call Led1.clr();
-         (macState & 4) ? call Led2.set() : call Led2.clr();
-         (macState & 8) ? call Led3.set() : call Led3.clr();
-*/
+    
+#ifdef REDMAC_PERFORMANCE
+     PfmTxMsg_t txStat;
+     PfmRxMsg_t rxStat;
 #endif
-    }
-
 
     /**************** Module Global Constants  *****************/
     enum {
-        BYTE_TIME=13,                // byte at 38400 kBit/s, 4b6b encoded
-        PREAMBLE_BYTE_TIME=9,        // byte at 38400 kBit/s, no coding
-        PHY_HEADER_TIME=51,          // 6 Phy Preamble at 38400
-        SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(tda5250_header_t)*BYTE_TIME,
-        SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 38400 kBit/s with 4b6b encoding
-        MAX_TIME_VALUE=0xFFFFFFFF,
-        MAXTIMERVALUE=0xFFFF,        // helps to compute backoff
-        //DEFAULT_SLEEP_TIME=3250,
-        DEFAULT_SLEEP_TIME=6500,
-        // DEFAULT_SLEEP_TIME=9750,
+        
+        BYTE_TIME=ENCODED_32KHZ_BYTE_TIME,           // phy encoded
+        PREAMBLE_BYTE_TIME=TDA5250_32KHZ_BYTE_TIME,  // no coding
+        PHY_HEADER_TIME=6*PREAMBLE_BYTE_TIME,        // 6 Phy Preamble
+        TIME_CORRECTION=TDA5250_32KHZ_BYTE_TIME+2,   // difference between txSFD and rxSFD
+
+        SUB_HEADER_TIME=PHY_HEADER_TIME + sizeof(message_header_t)*BYTE_TIME,
+        SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 
+        // DEFAULT_SLEEP_TIME=1625,
+#ifndef DEFAULT_SLEEP_TIME
+        DEFAULT_SLEEP_TIME=2048,
+        // DEFAULT_SLEEP_TIME=4096,
+        // DEFAULT_SLEEP_TIME=8192,
+        // DEFAULT_SLEEP_TIME=16384,
+        // DEFAULT_SLEEP_TIME=32768U,
+        // DEFAULT_SLEEP_TIME=65535U,
+#endif
         DATA_DETECT_TIME=17,
-        RX_SETUP_TIME=111,    // time to set up receiver
-        TX_SETUP_TIME=69,     // time to set up transmitter
-        ADDED_DELAY = 40,
-        RX_ACK_TIMEOUT = RX_SETUP_TIME + PHY_HEADER_TIME + 29 + 2*ADDED_DELAY,
-        TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11,
+        RX_SETUP_TIME=102,    // time to set up receiver
+        TX_SETUP_TIME=58,     // time to set up transmitter
+        ADDED_DELAY = 30,
+        RX_ACK_TIMEOUT = RX_SETUP_TIME + PHY_HEADER_TIME + ADDED_DELAY + 30,
+        TX_GAP_TIME = RX_ACK_TIMEOUT + TX_SETUP_TIME + 33,
         // the duration of a send ACK
         ACK_DURATION = SUB_HEADER_TIME + SUB_FOOTER_TIME,
-        MAX_SHORT_RETRY=7,
-        MAX_LONG_RETRY=2,
-        MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY,
-        MSG_TABLE_ENTRIES=20,
+        NAV_FACTOR = 4,
+#ifndef MAC_EVAL
+        MAX_SHORT_RETRY=9,
+        MAX_LONG_RETRY=3,
+        ADD_NAV = 2,
+        INCREASE_BACKOFF = TRUE,
+#endif
         TOKEN_ACK_FLAG = 64,
         TOKEN_ACK_MASK = 0x3f,
-        /* correct the difference between the transmittedSFD and the receivedSFD
-           that appears due to buffering, measured value on an osci is 320us, so this
-           value is actually 10.48576
-        */
-        TIME_CORRECTION = 10,
         INVALID_SNR = 0xffff,
-        PREAMBLE_LONG = 6,
-        PREAMBLE_SHORT = 2,
+        // PREAMBLE_LONG = 5,
+        // PREAMBLE_SHORT = 2,
+        // reduced minimal backoff
+        ZERO_BACKOFF_MASK = 0xff
     };
-    
 
+#ifdef MAC_EVAL
+    uint8_t MAX_SHORT_RETRY = 9;
+    uint8_t MAX_LONG_RETRY = 3;
+    uint8_t ADD_NAV = 4;
+    bool INCREASE_BACKOFF = TRUE;
+#endif
+#ifdef DELTATIMEDEBUG
+    DeltaTrace_t dTrace;
+#endif    
     /**************** Module Global Variables  *****************/
-    typedef union 
-    {
-        uint32_t op;
-        struct {
-            uint16_t lo;
-            uint16_t hi;
-        };
-    } ui32parts_t;
-    
     /* flags */
     typedef enum {
         SWITCHING = 1,
@@ -244,37 +201,29 @@ implementation
         TEAMGEIST_ACTIVE=128
     } flags_t;
 
-        /* duplicate suppression */
-    typedef struct knownMessage_t {
-        am_addr_t src;
-        uint8_t token;
-        uint8_t age;
-    } knownMessage_t;
+    uint8_t flags = 0;
+    uint8_t checkCounter = 0;
+    uint8_t shortRetryCounter = 0;
+    uint8_t longRetryCounter = 0;
+    uint16_t networkSleeptime = DEFAULT_SLEEP_TIME;
+    uint16_t localSleeptime = DEFAULT_SLEEP_TIME;
+    uint16_t rssiValue = 0;
+    uint32_t restLaufzeit = 0;
     
-    knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES];
-    uint8_t flags;
-    uint8_t checkCounter;
-    uint8_t shortRetryCounter;
-    uint8_t longRetryCounter;
-    uint16_t sleepTime;
-    uint16_t rssiValue;
-    uint32_t restLaufzeit;
-    
-    message_t *txBufPtr;
-    uint16_t txLen;
-    red_mac_header_t *txMacHdr;
+    uint32_t rxTime = 0;
+
+    am_id_t teamgeistType = 0;
 
+    uint8_t congestionLevel = 0;
+    
+    message_t *txBufPtr = NULL;
+    uint16_t txLen = 0;
+    red_mac_header_t *txMacHdr = NULL;
     uint16_t seqNo;
     message_t ackMsg;
 
-    uint16_t counter2sec;
-    uint32_t rxTime;
-
-    am_id_t teamgeistType;
-
-    uint8_t congestionLevel;
     uint16_t MIN_BACKOFF_MASK;
-    
+
     /****** Secure switching of radio modes ***/
     void interruptBackoffTimer();
     
@@ -301,12 +250,17 @@ implementation
     void setRxMode() {
         setFlag(&flags, SWITCHING);
         clearFlag(&flags, RSSI_STABLE);
-        storeOldState(0);
+        // sdDebug(10);
         checkCounter = 0;
         rssiValue = INVALID_SNR;
         if(call RadioModes.RxMode() == FAIL) {
             post SetRxModeTask();
         }
+        else {
+#ifdef REDMAC_PERFORMANCE
+            call Performance.macRxMode();
+#endif
+        }
         requestAdc();
     }
     
@@ -317,13 +271,18 @@ implementation
     }
 
     void setSleepMode() {
-        storeOldState(161);
+        // sdDebug(20);
         clearFlag(&flags, RSSI_STABLE);
         post ReleaseAdcTask();
         setFlag(&flags, SWITCHING);
         if(call RadioModes.SleepMode() == FAIL) {
             post SetSleepModeTask();
         }
+        else {
+#ifdef REDMAC_PERFORMANCE
+            call Performance.macSleepMode();
+#endif
+        }
     }
     
     task void SetSleepModeTask() {
@@ -333,12 +292,17 @@ implementation
 
     void setTxMode() {
         post ReleaseAdcTask();
-        storeOldState(2);
+        // sdDebug(30);
         clearFlag(&flags, RSSI_STABLE);
         setFlag(&flags, SWITCHING);
         if(call RadioModes.TxMode() == FAIL) {
             post SetTxModeTask();
         }
+        else {
+#ifdef REDMAC_PERFORMANCE
+            call Performance.macTxMode();
+#endif
+        }
     }
 
     task void SetTxModeTask() {
@@ -347,21 +311,34 @@ implementation
         }
     }
 
-    /**************** Helper functions ************************/
+    /**************** Helper functions ************************/    
+    void computeBackoff();
+    
     void checkSend() {
-        storeOldState(10);
         if((shortRetryCounter) && (txBufPtr != NULL) && (isFlagSet(&flags, MESSAGE_PREPARED)) && 
            (macState == SLEEP) && (!isFlagSet(&flags, RESUME_BACKOFF)) && (!call Timer.isRunning())) {
-            storeOldState(11);
+            // sdDebug(40);
             macState = CCA;
             checkCounter = 0;
             setRxMode();
         }
+/*        else {
+            if(txBufPtr) // sdDebug(41);
+            if(shortRetryCounter) // sdDebug(42);
+            if(isFlagSet(&flags, MESSAGE_PREPARED)) // sdDebug(43);
+            if(txBufPtr) {
+                if(macState == SLEEP) // sdDebug(44);
+                if(!isFlagSet(&flags, RESUME_BACKOFF)) // sdDebug(45);
+                if(!call Timer.isRunning()) // sdDebug(46);
+            }
+        }
+*/
     }
 
     uint32_t backoff(uint8_t counter) {
         uint32_t rVal = call Random.rand16() &  MIN_BACKOFF_MASK;
-        return rVal << counter;
+        if(!INCREASE_BACKOFF) counter = 1;
+        return (rVal << counter) + ZERO_BACKOFF_MASK;
     }
     
     bool needsAckTx(message_t* msg) {
@@ -390,8 +367,8 @@ implementation
                 if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
                    (getHeader(msg)->type == teamgeistType)) {
                     if(rssiValue != INVALID_SNR) snr = rssiValue;
+                    *level = 2;
                     rVal = signal Teamgeist.needsAck(msg, getHeader(msg)->src, getHeader(msg)->dest, snr);
-                    *level = 1;
                 }
             }
         }
@@ -406,10 +383,10 @@ implementation
         atomic {
             msg = txBufPtr;
             length = txLen;
-            sT = sleepTime;
+            sT = networkSleeptime;
         }
         if(msg == NULL) return;
-        macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, NULL);
+        macHdr = (red_mac_header_t *)call SubPacket.getPayload(msg, sizeof(red_mac_header_t));
         macHdr->repetitionCounter = sT/(length * BYTE_TIME + SUB_HEADER_TIME + SUB_FOOTER_TIME + 
                                         TX_GAP_TIME) + 1;
         atomic {
@@ -423,7 +400,37 @@ implementation
             txMacHdr = macHdr;
             setFlag(&flags, MESSAGE_PREPARED);
             if((macState == SLEEP) && (!call Timer.isRunning()) && (!isFlagSet(&flags, RESUME_BACKOFF))) {
-                call Timer.start(backoff(longRetryCounter));
+                if((longRetryCounter == 1) &&
+                   (getHeader(msg)->dest != AM_BROADCAST_ADDR)) {
+                    call Timer.start((call Random.rand16() >> 3) & ZERO_BACKOFF_MASK);
+                }
+                else {
+                    sdDebug(332);
+                    sdDebug(macHdr->repetitionCounter);
+                    call Timer.start(backoff(longRetryCounter));
+                }
+            }
+#ifdef REDMAC_PERFORMANCE
+            txStat.type = getHeader(msg)->type;
+            txStat.to = getHeader(msg)->dest;
+            txStat.token = getHeader(msg)->token;
+            txStat.maxRepCounter = macHdr->repetitionCounter;
+            txStat.creationTime =  getMetadata(msg)->time;
+#endif
+            getMetadata(msg)->maxRepetitions = macHdr->repetitionCounter;
+        }
+    }
+
+    void storeStrength(message_t *m) {
+        if(rssiValue != INVALID_SNR) {
+            (getMetadata(m))->strength = rssiValue;
+        }
+        else {
+            if(call RssiAdcResource.isOwner()) {
+                (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
+            }
+            else {
+                (getMetadata(m))->strength = 1;
             }
         }
     }
@@ -431,35 +438,47 @@ implementation
     bool prepareRepetition() {
         bool repeat;
         atomic {
-            if(isFlagSet(&flags, CANCEL_SEND)) txMacHdr->repetitionCounter = 0;
-            repeat = (txMacHdr->repetitionCounter >= 1);
-            txMacHdr->repetitionCounter--;
+            if(isFlagSet(&flags, CANCEL_SEND)) {
+                repeat = txMacHdr->repetitionCounter = 0;
+            }
+            else {
+                repeat = txMacHdr->repetitionCounter;
+                txMacHdr->repetitionCounter--;
+            }
         }
         return repeat;
     }
-
+    
     void signalSendDone(error_t error) {
         message_t *m;
         error_t e = error;
-        storeOldState(12);
+        // sdDebug(50);
         atomic {
             m = txBufPtr;
             txBufPtr = NULL;
             txLen  = 0;
+#ifdef REDMAC_PERFORMANCE
+            txStat.repCounter = txMacHdr->repetitionCounter;
+            txStat.longRetry = longRetryCounter;
+            txStat.shortRetry = shortRetryCounter;
+#endif
             longRetryCounter = 0;
             shortRetryCounter = 0;
-            if(rssiValue != INVALID_SNR) {
-                (getMetadata(m))->strength = rssiValue;
-            }
-            else {
-                (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
-            }
+            storeStrength(m);
             if(isFlagSet(&flags, CANCEL_SEND)) {
                 e = ECANCEL;
             }
+            clearFlag(&flags, MESSAGE_PREPARED);
             clearFlag(&flags, CANCEL_SEND);
         }
+        // sdDebug(3000 + e);
+        // sdDebug(4000 + getHeader(m)->type);
         signal MacSend.sendDone(m, e);
+#ifdef REDMAC_PERFORMANCE
+        txStat.success = e;
+        txStat.strength = getMetadata(m)->strength;
+        call Performance.macTxMsgStats(&txStat);
+#endif
     }
     
     void updateRetryCounters() {
@@ -468,7 +487,7 @@ implementation
             longRetryCounter++;
             shortRetryCounter = 1;
             if(longRetryCounter > MAX_LONG_RETRY) {
-                storeOldState(13);
+                // sdDebug(60);
                 signalSendDone(FAIL);
             }
         }
@@ -480,7 +499,7 @@ implementation
             longRetryCounter++;
             shortRetryCounter = 1;
             if(longRetryCounter > MAX_LONG_RETRY) {
-                storeOldState(13);
+                // sdDebug(70);
                 signalSendDone(FAIL);
             } else {
                 post PrepareMsgTask();
@@ -496,19 +515,11 @@ implementation
     }
 
     void interruptBackoffTimer() {
-        uint16_t now;
         if(call Timer.isRunning()) {
-            restLaufzeit = call Timer.getAlarm();
+            restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());
             call Timer.stop();
-            now = call Timer.getNow();
-            if(restLaufzeit >= now) {
-                restLaufzeit = restLaufzeit - now;
-            }
-            else {
-                restLaufzeit +=  MAXTIMERVALUE - now;
-            }
             if(restLaufzeit > MIN_BACKOFF_MASK << MAX_LONG_RETRY) {
-                restLaufzeit = backoff(0);
+                restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
             }
             setFlag(&flags, RESUME_BACKOFF);
         }
@@ -519,7 +530,6 @@ implementation
             setFlag(&flags, RESUME_BACKOFF);
             restLaufzeit = backoff(longRetryCounter);
             updateRetryCounters();
-            storeOldState(92);
         }
     }
 
@@ -536,38 +546,14 @@ implementation
     }
     
     bool isNewMsg(message_t* msg) {
-        bool rVal = TRUE;
-        uint8_t i;
-        for(i=0; i < MSG_TABLE_ENTRIES; i++) {
-            if((getHeader(msg)->src == knownMsgTable[i].src) &&
-               (((getHeader(msg)->token) & TOKEN_ACK_MASK) == knownMsgTable[i].token) &&
-               (knownMsgTable[i].age < MAX_AGE)) {
-                knownMsgTable[i].age = 0;
-                rVal = FALSE;
-                break;
-            }
-        }
-        return rVal;
-    }
-
-    unsigned findOldest() {
-        unsigned i;
-        unsigned oldIndex = 0;
-        unsigned age = knownMsgTable[oldIndex].age;
-        for(i = 1; i < MSG_TABLE_ENTRIES; i++) {
-            if(age < knownMsgTable[i].age) {
-                oldIndex = i;
-                age = knownMsgTable[i].age;
-            }
-        }
-        return oldIndex;
-    }
+        return call Duplicate.isNew(getHeader(msg)->src,
+                                    getHeader(msg)->dest,
+                                    (getHeader(msg)->token) & TOKEN_ACK_MASK);
+   }
 
     void rememberMsg(message_t* msg) {
-        unsigned oldest = findOldest();
-        knownMsgTable[oldest].src = getHeader(msg)->src;
-        knownMsgTable[oldest].token = (getHeader(msg)->token) & TOKEN_ACK_MASK;
-        knownMsgTable[oldest].age = 0;
+        call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest,
+                                (getHeader(msg)->token) & TOKEN_ACK_MASK);
     }
 
     void prepareAck(message_t* msg) {
@@ -577,50 +563,46 @@ implementation
         getHeader(&ackMsg)->src = call amAddress();
         getHeader(&ackMsg)->dest = getHeader(msg)->src;
         getHeader(&ackMsg)->type = getHeader(msg)->type;
+#ifdef REDMAC_DEBUG
+        repCounter = ((red_mac_header_t *)
+                      call SubPacket.getPayload(msg, sizeof(red_mac_header_t)))->repetitionCounter;
+#endif
     }
     
     uint32_t calcGeneratedTime(red_mac_header_t *m) {
-        return rxTime - m->time - TIME_CORRECTION;
+        uint32_t lt = rxTime - m->time - TIME_CORRECTION;
+#ifdef DELTATIMEDEBUG
+        dTrace.now = rxTime;
+        dTrace.msgTime = lt;
+        dTrace.delta = m->time;
+        call DeltaTrace.traceRx(&dTrace);
+#endif
+        return lt;
     }
-    
+
     /**************** Init ************************/
     
     command error_t Init.init(){
-        uint8_t i;
         atomic {
             macState = INIT;
-            flags = 0;
-            checkCounter = 0;
-            rssiValue = 0;
-            restLaufzeit = 0;
             seqNo = call Random.rand16() % TOKEN_ACK_FLAG;
-            txBufPtr = NULL;
-            txLen = 0;
-            txMacHdr = NULL;
-            sleepTime = DEFAULT_SLEEP_TIME;
-            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
-                knownMsgTable[i].age = MAX_AGE;
-            }
-            for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sleepTime; ) {
+            for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < networkSleeptime; ) {
                 MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
             }
             MIN_BACKOFF_MASK >>= 2;
-            storeOldState(20);
-            shortRetryCounter = 0;
-            longRetryCounter = 0;
-            counter2sec = 127;
-            rxTime = 0;
-            teamgeistType = 0;
         }
+#ifdef REDMAC_DEBUG
+        call SerialDebug.putShortDesc("RedMacP");
+#endif
         return SUCCESS;
     }
 
     /****************  SplitControl  *****************/
 
     task void StartDoneTask() {
-        storeOldState(14);
+        // sdDebug(90);
         atomic  {
-            call SampleTimer.start(sleepTime);
+            call SampleTimer.start(localSleeptime);
             macState = SLEEP;
             setFlag(&flags, TEAMGEIST_ACTIVE);
             teamgeistType = signal Teamgeist.observedAMType();
@@ -632,16 +614,15 @@ implementation
         call CcaStdControl.start();
         atomic {
             macState = INIT;
-            // signalMacState();
             setRxMode();
-            storeOldState(15);
+            // sdDebug(100);
         }
         return SUCCESS;
     }
     
     task void StopDoneTask() {
         call Init.init();
-        storeOldState(16);
+        // sdDebug(110);
         signal SplitControl.stopDone(SUCCESS);        
     }
     
@@ -652,12 +633,12 @@ implementation
         atomic {
             if((macState == SLEEP) && isFlagSet(&flags, SWITCHING)) {
                 macState = STOP;
-                storeOldState(17);
+                // sdDebug(120);
             }
             else {
                 macState = STOP;
                 setSleepMode();
-                storeOldState(18);
+                // sdDebug(121);
             }
         }
         return SUCCESS;
@@ -680,34 +661,28 @@ implementation
         return call SubPacket.maxPayloadLength() - sizeof(red_mac_header_t);
     }
     
-    command void* Packet.getPayload(message_t* msg, uint8_t* len) {
-        nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len);
-        if (len != NULL) {
-            *len -= sizeof(red_mac_header_t);
-        }
+    command void* Packet.getPayload(message_t* msg, uint8_t len) {
+        nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len + sizeof(red_mac_header_t));
         return (void*)(payload + sizeof(red_mac_header_t));
     }
     
     /****** Radio(Mode) events *************************/
     async event void RadioModes.RssiStable() {
-        if(isFlagSet(&flags, RSSI_STABLE)) signalFailure(0);
         setFlag(&flags, RSSI_STABLE);
         if((macState == RX) || (macState == CCA)) {
             call Timer.start(DATA_DETECT_TIME);
-            storeOldState(30);
+            // sdDebug(130);
         }
         else if(macState == RX_P) {
-            storeOldState(31);
+            // sdDebug(131);
             if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
         }
         else if(macState == RX_ACK) {
-            // if(call RssiAdcResource.isOwner()) call ChannelMonitor.start();
-            storeOldState(32);
         }
         else if(macState == RX_ACK_P) {
         }
         else if(macState == INIT) {
-            storeOldState(33);
+            // sdDebug(133);
             if(call RssiAdcResource.isOwner()) {
                 call ChannelMonitorControl.updateNoiseFloor();
             } else {
@@ -715,65 +690,55 @@ implementation
             }
         }
         else if(macState == STOP) {
-            storeOldState(34);
+            // sdDebug(134);
         }
         else {
-            storeOldState(35);
-            signalFailure(1);
+            // sdDebug(135);
         }
     }
     
     async event void RadioModes.RxModeDone() {
-        storeOldState(40);
-        if(!isFlagSet(&flags, SWITCHING)) signalFailure(2);
         atomic {
             clearFlag(&flags, SWITCHING);
             if((macState == RX) || (macState == RX_ACK) || (macState == CCA) ||
                (macState == INIT) || (macState == STOP)) {
-                storeOldState(41);
+                // sdDebug(140);
                 if(macState != RX_ACK) requestAdc();
             }
             else {
-                storeOldState(42);
-                signalFailure(3);
+                // sdDebug(141);
             }
         }
     }
     
     async event void RadioModes.TxModeDone() {
-        storeOldState(50);
-        if(!isFlagSet(&flags, SWITCHING)) signalFailure(4);
+        // sdDebug(150);
         atomic {
             clearFlag(&flags, SWITCHING);
             if(macState == TX) {
-                call UartPhyControl.setNumPreambles(PREAMBLE_SHORT);
                 setFlag(&flags, ACTION_DETECTED);
-                if(txBufPtr == NULL) signalFailure(5);
                 if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
-                    storeOldState(51);
-                } else {
-                    storeOldState(52);
-                    signalFailure(6);
+                    // sdDebug(151);
+                }
+                else {
+                    // sdDebug(152);
                 }
             }
             else if(macState == TX_ACK) {
                 if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
-                    storeOldState(53);
+                    // sdDebug(153);
                 } else {
-                    storeOldState(54);
-                    signalFailure(6);
+                    // sdDebug(154);
                 }
             }
             else {
-                storeOldState(55);
-                signalFailure(7);
+                // sdDebug(155);
             }
         }
     }
 
     async event void RadioModes.SleepModeDone() {
-        storeOldState(60);
-        if(!isFlagSet(&flags, SWITCHING)) signalFailure(8);
+        // sdDebug(160);
         atomic {
             clearFlag(&flags, SWITCHING);
             if(isFlagSet(&flags, ACTION_DETECTED)) {
@@ -781,24 +746,25 @@ implementation
             } else {
                 if(congestionLevel > 0) congestionLevel--;
             }
-            if((macState == SLEEP) && (!call Timer.isRunning())) {
-                if(isFlagSet(&flags, RESUME_BACKOFF)) {
-                    storeOldState(61);
-                    clearFlag(&flags, RESUME_BACKOFF);
-                    call Timer.start(restLaufzeit);
-                    restLaufzeit = 0;
-                }
-                else {
-                    storeOldState(62);
-                    checkSend();
+            // if(congestionLevel > 3) // sdDebug(2000 + congestionLevel);
+            if(macState == SLEEP) {
+                // sdDebug(161);
+                if(!call Timer.isRunning()) {
+                    // sdDebug(162);
+                    if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                        // sdDebug(164);
+                        clearFlag(&flags, RESUME_BACKOFF);
+                        call Timer.start(restLaufzeit);
+                        restLaufzeit = 0;
+                    }
+                    else {
+                        // sdDebug(165);
+                        checkSend();
+                    }
                 }
             }
-            else if(macState == INIT) {
-                storeOldState(63);
-                post StartDoneTask();
-            }
             else if(macState == STOP) {
-                storeOldState(64);
+                // sdDebug(168);
                 post StopDoneTask();
             }
             signal ChannelCongestion.congestionEvent(congestionLevel);
@@ -811,16 +777,20 @@ implementation
         atomic {
             if((shortRetryCounter == 0) && (txBufPtr == NULL)) {
                 clearFlag(&flags, MESSAGE_PREPARED);
-                storeOldState(65);
+                // sdDebug(5000 + getHeader(msg)->type);
                 shortRetryCounter = 1;
                 longRetryCounter = 1;
                 txBufPtr = msg;
                 txLen = len + sizeof(red_mac_header_t);
                 seqNo++;
                 if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
+#ifdef REDMAC_PERFORMANCE
+                txStat.payloadLength = txLen;
+                txStat.interfaceTime = call LocalTime32kHz.get();
+#endif
             }
             else {
-                storeOldState(66);
+                // sdDebug(171);
                 err = EBUSY;
             }
         }
@@ -834,12 +804,24 @@ implementation
         error_t err = FAIL;
         atomic {
             if(msg == txBufPtr) {
+                // sdDebug(320);
                 setFlag(&flags, CANCEL_SEND);
                 shortRetryCounter = MAX_SHORT_RETRY + 2;
                 longRetryCounter  = MAX_LONG_RETRY + 2;
-                if(macState == SLEEP) signalSendDone(ECANCEL);
+                if(macState == SLEEP) {
+                    // sdDebug(321);
+                    signalSendDone(ECANCEL);
+                }
+                else {
+                    // sdDebug(322);
+                }
+                // sdDebug(1000 + macState);
                 err = SUCCESS;
             }
+            else {
+                // sdDebug(323);
+                // sdDebug(1100 + macState);
+            }
         }
         return err;
     }
@@ -849,8 +831,14 @@ implementation
     async event void PacketReceive.receiveDetected() {
         rssiValue = INVALID_SNR;
         setFlag(&flags, ACTION_DETECTED);
+        call ChannelMonitor.rxSuccess();
         if(macState <= CCA_ACK) {
-            if(macState == CCA) computeBackoff();
+            if(macState == CCA) {
+                computeBackoff();
+#ifdef REDMAC_PERFORMANCE
+                call Performance.macDetectedOnCca();
+#endif
+            }
             if(macState != RX_ACK) {
                 macState = RX_P;
             } else {
@@ -858,8 +846,7 @@ implementation
             }
         }
         else if(macState == INIT) {
-            storeOldState(72);
-            if(isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(9);
+            // sdDebug(180);
             setFlag(&flags, UNHANDLED_PACKET);
         }
     }
@@ -870,47 +857,58 @@ implementation
         uint32_t nav = 0;
         uint8_t level = 0;
         bool isCnt;
-        
-        storeOldState(80);
+#ifdef REDMAC_PERFORMANCE
+        rxStat.duplicate = PERF_UNKNOWN;
+        rxStat.repCounter = 0xff;
+#endif
+        // sdDebug(190);
         if(macState == RX_P) {
-            storeOldState(81);
+            // sdDebug(191);
             if(error == SUCCESS) {
-                storeOldState(82);
+                // sdDebug(192);
                 isCnt = isControl(msg);
                 if(msgIsForMe(msg)) {
                     if(!isCnt) {
-                        storeOldState(83);
+                        // sdDebug(193);
                         if(isNewMsg(msg)) {
-                            storeOldState(84);
-                            if(rssiValue != INVALID_SNR) {
-                                (getMetadata(m))->strength = rssiValue;
-                            }
-                            else {
-                                if(call RssiAdcResource.isOwner()) {
-                                    (getMetadata(m))->strength = call ChannelMonitorData.readSnr();
-                                }
-                                else {
-                                    (getMetadata(m))->strength = 1;
-                                }
-                            }
-                            (getMetadata(msg))->time = calcGeneratedTime((red_mac_header_t*) payload);
+#ifdef REDMAC_PERFORMANCE
+                            rxStat.duplicate = PERF_NEW_MSG;
+#endif
+                            // sdDebug(194);
+                            storeStrength(msg);
+#ifdef DELTATIMEDEBUG
+                            dTrace.sender = getHeader(msg)->src;
+#endif
+                            getMetadata(msg)->sfdtime = rxTime;
+                            getMetadata(msg)->time = calcGeneratedTime((red_mac_header_t*) payload);
+                            getMetadata(msg)->ack = WAS_NOT_ACKED;
                             m = signal MacReceive.receiveDone(msg);
                             // assume a buffer swap -- if buffer is not swapped, assume that the
                             // message was not successfully delivered to upper layers
                             if(m != msg) {
-                                storeOldState(85);
+                                // sdDebug(195);
                                 rememberMsg(msg);
                             } else {
-                                storeOldState(86);
+                                // sdDebug(196);
                                 action = RX;
+#ifdef REDMAC_PERFORMANCE
+                                call Performance.macQueueFull();
+#endif
                             }
                         }
+                        else {
+#ifdef REDMAC_PERFORMANCE
+                            rxStat.duplicate = PERF_REPEATED_MSG;
+#endif
+                        }
                         if(needsAckRx(msg, &level) && (action != RX)) {
-                            storeOldState(87);
                             action = CCA_ACK;
+                            if(level == 2) {
+                                getMetadata(msg)->ack = WAS_ACKED;
+                            }
                         }
                         else {
-                            storeOldState(88);
+                            // sdDebug(198);
                             if(action != RX) {
                                 nav = ((red_mac_header_t*)payload)->repetitionCounter *
                                     (SUB_HEADER_TIME + getHeader(msg)->length*BYTE_TIME +
@@ -920,12 +918,12 @@ implementation
                         }
                     }
                     else {
-                        storeOldState(89);
+                        // sdDebug(199);
                         action = RX;
                     }
                 }
                 else {
-                    storeOldState(90);
+                    // sdDebug(200);
                     action = SLEEP;
                     if(!isCnt) {
                         nav = ((red_mac_header_t*)payload)->repetitionCounter *
@@ -936,64 +934,61 @@ implementation
                 }
             }
             else {
-                storeOldState(91);
-                action = RX;
+                // sdDebug(201);
+                action = SLEEP;
             }
         }
         else if(macState == RX_ACK_P) {
             if(error == SUCCESS) {
                 if(ackIsForMe(msg)) {
-                    storeOldState(92);
-                    if(rssiValue != INVALID_SNR) {
-                        (getMetadata(txBufPtr))->strength = rssiValue;
-                    }
-                    else {
-                        if(call RssiAdcResource.isOwner()) {
-                            (getMetadata(txBufPtr))->strength = call ChannelMonitorData.readSnr();
-                        }
-                        else {
-                            (getMetadata(txBufPtr))->strength = 1;
-                        }
-                    }
-                    (getMetadata(txBufPtr))->ack = WAS_ACKED;
-                    if(isFlagSet(&flags, TEAMGEIST_ACTIVE) && (getHeader(txBufPtr)->type == teamgeistType)) {
+                    // sdDebug(202);
+                    getMetadata(txBufPtr)->ack = WAS_ACKED;
+                    getMetadata(txBufPtr)->repetitions = txMacHdr->repetitionCounter;
+                    if(isFlagSet(&flags, TEAMGEIST_ACTIVE) &&
+                       (getHeader(txBufPtr)->type == teamgeistType))
+                    {
                         signal Teamgeist.gotAck(txBufPtr, getHeader(msg)->src,
                                                 getMetadata(txBufPtr)->strength);
                     }
+                    // sdDebug(203);
                     signalSendDone(SUCCESS);
+                    // sdDebug(30000 + getHeader(msg)->src);
                     action = SLEEP;
                 }
                 else {
-                    updateLongRetryCounters();
-                    action = RX;
+                    // sdDebug(203);
+                    updateLongRetryCounters(); // this will eventually schedule the right backoff
+                    macState = SLEEP;          // so much traffic is going on -- take a nap
+                    setSleepMode();
+                    action = INIT;             // a difficult way to say: do nothing
                 }
             }
             else {
                 if(call Timer.isRunning()) {
-                    storeOldState(94);
+                    // sdDebug(204);
                     action = RX_ACK;
                 }
                 else {
+                    // sdDebug(205);
                     updateLongRetryCounters();
                     action = RX;
                 }
             }
         }
         else {
-            storeOldState(96);
+            // sdDebug(206);
             action = INIT;
         }
         if(action == CCA_ACK) {
-            prepareAck(msg);
             macState = CCA_ACK;
-            if(call Random.rand16() & 4) {
-                call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + (ADDED_DELAY>>level));
-                call UartPhyControl.setNumPreambles(PREAMBLE_SHORT);
+            if(call Random.rand16() & 2) {
+                call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + 16 - level*8 + ADDED_DELAY);
             }
             else {
-                call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME);
-                call UartPhyControl.setNumPreambles(PREAMBLE_LONG);
+                macState = TX_ACK;
+                call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + 16);
             }
+            prepareAck(msg);
         }
         else if(action == RX_ACK) {
             macState = RX_ACK;
@@ -1005,43 +1000,56 @@ implementation
         }
         else if(action == SLEEP) {
             macState = SLEEP;
-            setSleepMode();
             if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                nav = nav*(uint32_t)ADD_NAV/(uint32_t)NAV_FACTOR;
                 if(nav > restLaufzeit) restLaufzeit += nav;
             }
             else {
                 setFlag(&flags, RESUME_BACKOFF);
-                restLaufzeit = nav + backoff(longRetryCounter);
+                restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
             }
+            setSleepMode();
         }
         else if(action == INIT) {
-            if(!isFlagSet(&flags, UNHANDLED_PACKET)) signalFailure(11);
             clearFlag(&flags, UNHANDLED_PACKET);
         }
         else {
-            storeOldState(94);
-            signalFailure(11);
+            // sdDebug(207);
+        }
+#ifdef REDMAC_PERFORMANCE
+        if(error == SUCCESS) {
+            rxStat.type = getHeader(msg)->type;
+            rxStat.from = getHeader(msg)->src;
+            rxStat.to = getHeader(msg)->dest;
+            rxStat.token = getHeader(msg)->token;
+            if(!isControl(msg)) rxStat.repCounter  = ((red_mac_header_t*)payload)->repetitionCounter;
+            rxStat.payloadLength = len;
+            rxStat.strength = rssiValue;
+            rxStat.creationTime = getMetadata(msg)->time;
+            call Performance.macRxStats(&rxStat);
         }
+#endif
         return m;
     }
 
     async event void PacketSend.sendDone(message_t* msg, error_t error) {
         if(macState == TX) {
-            storeOldState(97);
-            if(msg != txBufPtr) signalFailure(12);
-            storeOldState(99);
             macState = RX_ACK;
             setRxMode();
             call Timer.start(RX_ACK_TIMEOUT);
+            // sdDebug(220);
             checkCounter = 0;
         }
         else if(macState == TX_ACK) {
             checkCounter = 0;
-            macState = RX;
-            setRxMode();
-        }
-        else {
-            signalFailure(13);
+            macState = SLEEP;
+            setSleepMode();
+            // macState = RX;
+            // setRxMode();
+            // sdDebug(221);
+#ifdef REDMAC_DEBUG            
+            // sdDebug(40000U + repCounter);
+#endif
         }
     }
     
@@ -1049,41 +1057,28 @@ implementation
     async event void RadioTimeStamping.receivedSFD( uint16_t time ) {
         if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
         if(macState == RX_P) {
-            rxTime = call LocalTime32khz.get();
+            rxTime = call LocalTime32kHz.get();
             call ChannelMonitor.rxSuccess();
         }
     }
     
     async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) {
-        uint32_t now;
-        uint32_t mTime;
         if((macState == TX) && (p_msg == txBufPtr)) {
-            now = call LocalTime32khz.get();
-            mTime = getMetadata(p_msg)->time;
-            if(now >= mTime) {
-                txMacHdr->time = now - mTime;
-            }
-            else {
-                // assume a clock wrap here
-                txMacHdr->time = MAX_TIME_VALUE - mTime + now;
-            }
-        }
-    }
-    
-    async command uint32_t LocalTime32khz.get() {
-        ui32parts_t time;
-        atomic {
-            time.lo = call Counter32khz16.get();
-            time.hi = counter2sec;
+#ifdef DELTATIMEDEBUG
+            dTrace.now = call LocalTime32kHz.get();
+            dTrace.msgTime = getMetadata(p_msg)->time;
+            dTrace.delta = call TimeDiff32.computeDelta(dTrace.now, dTrace.msgTime);
+            txMacHdr->time = dTrace.delta;
+            call DeltaTrace.traceTx(&dTrace);
+            getMetadata(p_msg)->sfdtime = dTrace.now;
+#else
+            getMetadata(p_msg)->sfdtime = call LocalTime32kHz.get();
+            txMacHdr->time =
+                call TimeDiff32.computeDelta(getMetadata(p_msg)->sfdtime,
+                                             getMetadata(p_msg)->time);
+#endif
         }
-        return time.op;
-    }
-    
-    async event void Counter32khz16.overflow() {
-        counter2sec++;
     }
-
-    
     
     /****** Timer ******************************/
 
@@ -1092,9 +1087,12 @@ implementation
         if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
             if(macState == CCA) {
                 computeBackoff();
+#ifdef REDMAC_PERFORMANCE
+                call Performance.macBusyOnCca();
+#endif
             }
             requestAdc();
-            storeOldState(150);
+            // sdDebug(230);
             macState = RX;
             checkCounter = 0;
             call Timer.start(TX_GAP_TIME>>1);
@@ -1105,122 +1103,144 @@ implementation
         if(macState == RX) {
             checkCounter++;
             if(checkCounter >= 3) {
-                storeOldState(153);
+                // sdDebug(240);
                 macState = SLEEP;
                 setSleepMode();
             }
             else {
-                storeOldState(154);
-                call Timer.start(TX_GAP_TIME>>1);
+                // sdDebug(241);
+                call Timer.start(TX_GAP_TIME >> 1);
                 requestAdc();
             }
         }
         else if(macState == CCA) {
             checkCounter++;
             if(checkCounter < 3) {
-                storeOldState(158);                
-                call Timer.start((TX_GAP_TIME + backoff(0))>>1);
+                // sdDebug(242);                
+                call Timer.start(TX_GAP_TIME >> 1);
                 requestAdc();
             }
             else {
-                storeOldState(159);
+                // sdDebug(243);
                 macState = TX;
                 setTxMode();
+#ifdef REDMAC_PERFORMANCE
+                call Performance.macIdleOnCca();
+                txStat.txModeTime = call LocalTime32kHz.get();
+#endif
             }
         }
         else if(macState == CCA_ACK) {
-            storeOldState(160);
+            // sdDebug(244);
             macState = TX_ACK;
             setTxMode();
+            // sdDebug(20000 + getHeader(&ackMsg)->dest);
+#ifdef REDMAC_PERFORMANCE
+            call Performance.macTxAckStats(getHeader(&ackMsg)->type,
+                                          getHeader(&ackMsg)->dest,
+                                          getHeader(&ackMsg)->token);
+#endif
         }
     }
     
     async event void Timer.fired() {
-        storeOldState(100);
+        // sdDebug(250);
         if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
-            if(isFlagSet(&flags, SWITCHING)) signalFailure(14);
             if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) {
                 if(call UartPhyControl.isBusy()) {
-                    storeOldState(101);
+                    // sdDebug(251);
                     checkOnBusy();
                 }
                 else {
-                    storeOldState(102);
+                    // sdDebug(252);
                     checkOnIdle();
                 }
             }
         }
         else if(macState == RX_ACK) {
             if(prepareRepetition()) {
-                storeOldState(156);
+                // sdDebug(253);
                 macState = TX;
                 setTxMode();
             }
             else {
                 if(needsAckTx(txBufPtr)) {
-                    storeOldState(157);
+                    // sdDebug(254);
+#ifdef REDMAC_PERFORMANCE
+                    call Performance.macAckTimeout();
+#endif
                     updateLongRetryCounters();
                 }
                 else {
-                    storeOldState(158);
+                    // sdDebug(255);
                     signalSendDone(SUCCESS);
                 }
                 macState = SLEEP;
                 setSleepMode();
             }
         }
+        else if(macState == TX_ACK) {
+            setTxMode();
+            // sdDebug(10000 + getHeader(&ackMsg)->dest);
+        }
         else if(macState == SLEEP) {
              if(isFlagSet(&flags, SWITCHING)) {
-                 storeOldState(106);
-                 call Timer.start(backoff(0));
+                 // sdDebug(256);
+                 call Timer.start(call Random.rand16() & 0x0f);
              }
              else {
-                 storeOldState(107);
-                 checkSend();
+                 if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                     // sdDebug(261);
+                     clearFlag(&flags, RESUME_BACKOFF);
+                     call Timer.start(restLaufzeit);
+                     restLaufzeit = 0;
+                 }
+                 else {
+                     // sdDebug(262);
+                     checkSend();
+                 }
              }
         }
         else if((macState == RX_ACK_P) || (macState == RX_P)) {
-            storeOldState(108);
+            // sdDebug(258);
         }
         else if(macState == INIT) {
-            storeOldState(109);
+            // sdDebug(259);
             post StartDoneTask();
         }
         else {
-            storeOldState(110);
-            signalFailure(15);
-        }
-    }
-
-    /****** SampleTimer ******************************/
-
-    task void ageMsgsTask() {
-        unsigned i;
-        atomic {
-            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
-                if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age;
-            }
+            // sdDebug(260);
         }
     }
     
+    /****** SampleTimer ******************************/
     async event void SampleTimer.fired() {
-        call SampleTimer.start(sleepTime);
-        storeOldState(111);
+        call SampleTimer.start(localSleeptime);
+        // sdDebug(270);
         if((macState == SLEEP) && (!isFlagSet(&flags, SWITCHING))) {
             clearFlag(&flags, ACTION_DETECTED);
             interruptBackoffTimer();
             macState = RX;
-            storeOldState(112);
+            // sdDebug(271);
             setRxMode();
             call Timer.stop();
         }
-        post ageMsgsTask();
     }
 
-    /***** SleepTime **********************************/
-    async command void SleepTime.setSleepTime(uint16_t sT) {
+    /***** Sleeptime **********************************/
+    async command void Sleeptime.setLocalSleeptime(uint16_t sT) {
+        atomic localSleeptime = sT;
+    }
+
+    async command uint16_t Sleeptime.getLocalSleeptime() {
+        uint16_t st;
+        atomic st = localSleeptime;
+        return st;        
+    }
+
+    async command void Sleeptime.setNetworkSleeptime(uint16_t sT) {
         atomic {
-            sleepTime = sT;
+            networkSleeptime = sT;
             for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sT; ) {
                 MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
             }
@@ -1228,21 +1248,21 @@ implementation
         }
     }
     
-    async command uint16_t SleepTime.getSleepTime() {
+    async command uint16_t Sleeptime.getNetworkSleeptime() {
         uint16_t st;
-        atomic st = sleepTime;
+        atomic st = networkSleeptime;
         return st;
     }
 
     /****** ChannelMonitor events *********************/
 
     async event void ChannelMonitor.channelBusy() {
-        storeOldState(120);
+        // sdDebug(280);
         checkOnBusy();
     }
 
     async event void ChannelMonitor.channelIdle() {
-        storeOldState(121);
+        // sdDebug(281);
         checkOnIdle();
     }
 
@@ -1250,19 +1270,17 @@ implementation
     
     event void ChannelMonitorControl.updateNoiseFloorDone() {
         if(macState == INIT) {
-            storeOldState(130);
-            call Timer.start(call Random.rand16() % DEFAULT_SLEEP_TIME);
+            // sdDebug(290);
+            call Timer.start(call Random.rand16() % localSleeptime);
             setSleepMode();
         } else {
-            storeOldState(131);
-            signalFailure(16);
+            // sdDebug(291);
         }
     }
 
     /***** ChannelMonitorData events ******************/
     
     async event void ChannelMonitorData.getSnrDone(int16_t data) {
-        storeOldState(140);
         atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data;
     }
     
@@ -1271,14 +1289,14 @@ implementation
         macState_t ms;
         atomic ms = macState;
         if(ms < SLEEP) {
-            storeOldState(144);
+            // sdDebug(300);
         }
         else if(ms == INIT) {
-            storeOldState(145);
+            // sdDebug(301);
             call ChannelMonitorControl.updateNoiseFloor();            
         }
         else {
-            storeOldState(146);
+            // sdDebug(302);
             post ReleaseAdcTask();
         }
     }
@@ -1307,23 +1325,29 @@ implementation
     }
     
     default async event void ChannelCongestion.congestionEvent(uint8_t level) {}
+
+    /***** Mac Eval *******************************************/
+#ifdef MAC_EVAL
+    async command void MacEval.setBackoffMask(uint16_t mask) {
+        atomic MIN_BACKOFF_MASK = mask;
+    }
+    async command void MacEval.increaseBackoff(bool value) {
+        atomic INCREASE_BACKOFF = value;
+    }
+    async command void MacEval.addNav(uint8_t value) {
+        atomic ADD_NAV = value;
+    }
+    async command void MacEval.setLongRetry(uint8_t lr) {
+        atomic MAX_LONG_RETRY = lr;
+    }
+    async command void MacEval.setShortRetry(uint8_t sr) {
+        atomic MAX_SHORT_RETRY = sr;
+    }    
+#endif
     
     /***** unused Radio Modes events **************************/
-    
     async event void RadioModes.TimerModeDone() {}
     async event void RadioModes.SelfPollingModeDone() {}
     async event void RadioModes.PWDDDInterrupt() {}
-
-    /** prevent MCU from going into a too low power mode */
-    async command mcu_power_t McuPowerOverride.lowestState() {
-        mcu_power_t mp;
-        if(macState != SLEEP) {
-            mp = MSP430_POWER_LPM1;
-        }
-        else {
-            mp = MSP430_POWER_LPM3;
-        }
-        return mp;
-    }
 }