]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/tda5250/mac/CsmaMacP.nc
update to new debug if
[tinyos-2.x.git] / tos / chips / tda5250 / mac / CsmaMacP.nc
index aba1739608d4b919e4867ffadef8026d09559901..7f17e4145d0ef57d8fd763f2ceea178dd0d0cac0 100644 (file)
  */
 
 
+
 #include "radiopacketfunctions.h"
 #include "flagfunctions.h"
+#include "PacketAck.h"
 
  /**
   * An implementation of a Csma Mac.
   * @author: Kevin Klues (klues@tkn.tu-berlin.de)
   * @author Philipp Huppertz (huppertz@tkn.tu-berlin.de)
 */
+
+// #define MACM_DEBUG                 // debug...
 module CsmaMacP {
     provides {
-        interface Init;
         interface SplitControl;
         interface MacSend;
         interface MacReceive;
+        interface Packet;
     }
     uses {
         interface StdControl as CcaStdControl;
         interface PhySend as PacketSend;
         interface PhyReceive as PacketReceive;
+        interface RadioTimeStamping;
         
         interface Tda5250Control as RadioModes;  
+        interface ResourceRequested as RadioResourceRequested;
 
         interface UartPhyControl;
-      
+        interface Packet as SubPacket;
+        
         interface ChannelMonitor;
         interface ChannelMonitorControl;  
         interface ChannelMonitorData;
+        interface Resource as RssiAdcResource;
 
         interface Random;
+
+        interface Timer<TMilli> as ReRxTimer;
+        interface Duplicate;
+        interface TimeDiff16;
         
         interface Alarm<T32khz, uint16_t> as Timer;
-
-        interface GeneralIO as Led0;
-        interface GeneralIO as Led1;
-        interface GeneralIO as Led2;
-        interface GeneralIO as Led3;
+        async command am_addr_t amAddress();
+        interface LocalTime<T32khz> as LocalTime32kHz;
+        
+#ifdef MACM_DEBUG
+        interface SerialDebug;
+#endif
     }
 }
 implementation
 {
-#define CSMA_ACK 100
-#define BYTE_TIME 17
-// #define MACM_DEBUG                    // debug...
-#define MAX_LONG_RETRY 3              // Missing acks, or short retry limit hits -> increase long retry 
-#define MAX_SHORT_RETRY 5             // busy channel -> increase short retry
-#define DIFS 165                      // 5ms to get an ACK started
-#define ACK_TIMEOUT 20*BYTE_TIME
-#define MIN_BACKOFF_MASK 0x7F         // roughly 4ms for Rx/Tx turnaround defines this value
-#define CHECK_RX_LIVENESS_INTERVALL 165
+    /****** debug vars & defs & functions  ***********************/
+#ifdef MACM_DEBUG
+    void sdDebug(uint16_t p) {
+        call SerialDebug.putPlace(p);
+    };
+#else
+    void sdDebug(uint16_t p) {};
+#endif
+
+    /******* constants and type definitions *********************/
+    enum {
+
+        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(tda5250_header_t)*BYTE_TIME,
+        SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 
+        MAXTIMERVALUE=0xFFFF,        // helps to compute backoff
+        DATA_DETECT_TIME=17,
+        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 + 2*ADDED_DELAY,
+        TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 33,
+        MAX_SHORT_RETRY=7,
+        MAX_LONG_RETRY=4,
+        BACKOFF_MASK=0xFFF,  // minimum time around one packet time
+        MIN_PREAMBLE_BYTES=2,
+        TOKEN_ACK_FLAG = 64,
+        TOKEN_ACK_MASK = 0x3f,
+        INVALID_SNR = 0xffff
+    };
     
 /**************** Module Global Variables  *****************/
     
     /* state vars & defs */
     typedef enum {
-        SW_CCA,          // switch to CCA
-        CCA,             // clear channel assessment     
+        CCA,             // clear channel assessment
+        CCA_ACK,
         SW_RX,           // switch to receive
         RX,              // rx mode done, listening & waiting for packet
         SW_RX_ACK,
         RX_ACK,
+        RX_ACK_P,
         RX_P,
         SW_TX,
         TX,
@@ -102,123 +142,87 @@ implementation
     /* flags */
     typedef enum {
         RSSI_STABLE = 1,
-        BUSY_DETECTED_VIA_RSSI = 2,
-        CHECK_RX_LIVENESS = 4,
-        DIFS_TIMER_FIRED = 8
+        RESUME_BACKOFF = 2,
+        CANCEL_SEND = 4,
+        CCA_PENDING = 8
     } flags_t;
 
     /* Packet vars */
-    message_t* txBufPtr;
+    message_t* txBufPtr = NULL;
     message_t ackMsg;
 
     uint8_t txLen;
-    int16_t rssiValue;
-    uint8_t shortRetryCounter;
-    uint8_t longRetryCounter;
+    uint8_t shortRetryCounter = 0;
 
-    macState_t macState;
-    uint8_t flags;
-
-    uint16_t slotMask;
+    uint8_t longRetryCounter = 0;
+    unsigned checkCounter;
     
-    /****** debug vars & defs & functions  ***********************/
-#ifdef MACM_DEBUG
-#define HISTORY_ENTRIES 40
-    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;
-        }
-    }
-#else
-    void storeOldState(int p) {};
-#endif
-
-    void signalFailure(uint8_t place) {
-#ifdef MACM_DEBUG
-        unsigned long i;
-        atomic {
-            for(;;) {
-                call Led0.set();
-                call Led1.clr();
-                call Led2.clr();
-                call Led3.clr();
-                
-                for(i = 0; i < 1000000; i++) {
-                    ;
-                }
-
-                (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();
+    macState_t macState = INIT;
+    uint8_t flags = 0;
+    uint8_t seqNo;
+    
+    uint16_t restLaufzeit;
 
-                for(i = 0; i < 1000000; i++) {
-                    ;
-                }
-            }
-        }
-#endif
-    }
+    uint16_t rssiValue = 0;
 
-    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();
-#endif
-    }
+    uint32_t rxTime = 0;
     
     /****** Secure switching of radio modes ***/
     
     task void SetRxModeTask();
     task void SetTxModeTask();
+
+    task void ReleaseAdcTask() {
+        macState_t ms;
+        atomic ms = macState;
+        if(isFlagSet(&flags, CCA_PENDING)) {
+          post ReleaseAdcTask(); 
+        }
+        else {
+               if((ms > CCA)  && (ms != INIT) && call RssiAdcResource.isOwner()) {
+                 call RssiAdcResource.release();
+               }       
+        }
+    }
     
     void setRxMode();
     void setTxMode();
 
+    void requestAdc() {
+        if(macState != INIT) {
+          call RssiAdcResource.immediateRequest();
+        }
+        else {
+            call RssiAdcResource.request();
+        }
+    }
+    
     void setRxMode() {
+        rssiValue = INVALID_SNR;
         if(call RadioModes.RxMode() == FAIL) {
             post SetRxModeTask();
         }
+        if(macState == INIT) {
+          requestAdc();
+        } else {
+          post ReleaseAdcTask();
+        }
     }
     
     task void SetRxModeTask() {
         atomic {
             if((macState == SW_RX) ||
                (macState == SW_RX_ACK) ||
-               (macState == SW_CCA) ||
                (macState == INIT)) setRxMode();
         }
     }
 
     void setTxMode() {
         clearFlag(&flags, RSSI_STABLE);
-        clearFlag(&flags, BUSY_DETECTED_VIA_RSSI);
         if(call RadioModes.TxMode() == FAIL) {
             post SetTxModeTask();
         }
+        post ReleaseAdcTask();
     }
     
     task void SetTxModeTask() {
@@ -229,25 +233,67 @@ implementation
     }
 
     /**************** Helper functions ********/
-    uint16_t backoff() {
-        uint16_t mask = slotMask;
-        unsigned i;
-        for(i = 0; i < longRetryCounter; i++) {
-            mask = (mask << 1) + 1;
-        }
+
+    task void postponeReRx() {
+        call ReRxTimer.startOneShot(5000);
+    }
+
+    uint16_t backoff(uint8_t counter) {
+        uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter);
         return (call Random.rand16() & mask);
     }
-    
+
+    void interruptBackoffTimer() {
+        if(call Timer.isRunning()) {
+            restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());
+            call Timer.stop();
+            if(restLaufzeit > BACKOFF_MASK) {
+                restLaufzeit = call Random.rand16() & 0xFF;
+            }
+            setFlag(&flags, RESUME_BACKOFF);
+        }
+    }
+
+    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;
+            }
+        }
+    }
+
     void signalSendDone(error_t error) {
         message_t *m;
+        error_t e = error;
         atomic {
             m = txBufPtr;
             txBufPtr = 0;
             txLen  = 0;
             longRetryCounter = 0;
             shortRetryCounter = 0;
+            if(isFlagSet(&flags, CANCEL_SEND)) {
+                e = ECANCEL;
+            }
+            storeStrength(m);
+            clearFlag(&flags, CANCEL_SEND);
+        }
+        signal MacSend.sendDone(m, e);
+    }
+
+    void updateLongRetryCounters() {
+        longRetryCounter++;
+        shortRetryCounter = 1;
+        if(longRetryCounter > MAX_LONG_RETRY) {
+            sdDebug(13);
+            getMetadata(txBufPtr)->ack = WAS_NOT_ACKED;
+            signalSendDone(FAIL);
         }
-        signal MacSend.sendDone(m, error);
     }
 
     void updateRetryCounters() {
@@ -256,63 +302,100 @@ implementation
             longRetryCounter++;
             shortRetryCounter = 1;
             if(longRetryCounter > MAX_LONG_RETRY) {
+                getMetadata(txBufPtr)->ack = WAS_NOT_ACKED;
                 signalSendDone(FAIL);
             }
         }
     }
     
-    void checkSend() {
-        if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) {
-            clearFlag(&flags, CHECK_RX_LIVENESS);
-            clearFlag(&flags, DIFS_TIMER_FIRED);
-            /*           if(!call UartPhyControl.isBusy()) { */
-                if(isFlagSet(&flags, RSSI_STABLE)) {
-                    macState = CCA;
-                    signalMacState();
-                    call Timer.start(DIFS);
-                    call ChannelMonitor.start();
-                    storeOldState(130);
-                } else {
-                    macState = SW_CCA;
-                    signalMacState();
-                    storeOldState(131);
-                }
- /*           }
-            else {
-                storeOldState(132);
-                updateRetryCounters();
-                setFlag(&flags, CHECK_RX_LIVENESS);
-                call Timer.start(backoff());
-            }
-                */
-      }
+    void computeBackoff() {
+        if(!isFlagSet(&flags, RESUME_BACKOFF)) {
+            setFlag(&flags, RESUME_BACKOFF);
+            restLaufzeit = backoff(longRetryCounter);
+            updateRetryCounters();
+            sdDebug(92);
+        }
+    }
+
+    bool isNewMsg(message_t* msg) {
+        return call Duplicate.isNew(getHeader(msg)->src, getHeader(msg)->dest,
+                                    (getHeader(msg)->token) & TOKEN_ACK_MASK);
     }
     
-    bool needsAck(message_t* msg) {
-        return FALSE;  // (getHeader(msg)->addr != AM_BROADCAST_ADDR);
+    void rememberMsg(message_t* msg) {
+        call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest,
+                                (getHeader(msg)->token) & TOKEN_ACK_MASK);
     }
     
-    /**************** Init ************************/
+    void checkSend() {
+        if((txBufPtr != NULL) && (macState == RX) && (!call Timer.isRunning())) {
+            macState = CCA;
+            checkCounter = 0;
+            requestAdc();
+            call Timer.start(DATA_DETECT_TIME);
+            sdDebug(170);
+        }
+        else {
+            sdDebug(171);
+            post ReleaseAdcTask();
+        }
+    }
     
-    command error_t Init.init(){
-        atomic {
-            txBufPtr = NULL;
-            macState = INIT;
-            signalMacState();
-            shortRetryCounter = 0;
-            longRetryCounter = 0;
-            flags = 0;
-            slotMask = MIN_BACKOFF_MASK;
-#ifdef MACM_DEBUG
-            histIndex = 0;
-#endif
+    bool needsAckRx(message_t* msg) {
+        bool rVal = FALSE;
+        uint8_t token;
+        if(getHeader(msg)->dest < AM_BROADCAST_ADDR) {
+            token = getHeader(msg)->token;
+            if(isFlagSet(&token, ACK_REQUESTED)) rVal = TRUE;
         }
-        return SUCCESS;
+        return rVal;
+    }
+
+    bool needsAckTx(message_t* msg) {
+        bool rVal = FALSE;
+        if(getHeader(msg)->dest < AM_BROADCAST_ADDR) {
+            if((getMetadata(msg)->ack == ACK_REQUESTED) || (getMetadata(msg)->ack != NO_ACK_REQUESTED)) {
+                rVal = TRUE;
+            }
+        }
+        return rVal;
+    }
+
+    void prepareAck(message_t* msg) {
+        uint8_t rToken = getHeader(msg)->token & TOKEN_ACK_MASK;
+        setFlag(&rToken, TOKEN_ACK_FLAG);
+        getHeader(&ackMsg)->token = rToken;
+        getHeader(&ackMsg)->src = call amAddress();
+        getHeader(&ackMsg)->dest = getHeader(msg)->src;
+        getHeader(&ackMsg)->type = getHeader(msg)->type;
+    }
+
+    bool msgIsForMe(message_t* msg) {
+        if(getHeader(msg)->dest == AM_BROADCAST_ADDR) return TRUE;
+        if(getHeader(msg)->dest == call amAddress()) return TRUE;
+        return FALSE;
     }
 
+    bool ackIsForMe(message_t* msg) {
+        uint8_t localToken = seqNo;
+        setFlag(&localToken, TOKEN_ACK_FLAG);
+        if((getHeader(msg)->dest == call amAddress()) && (localToken == getHeader(msg)->token)) return TRUE;
+        return FALSE;
+    }
+    
+    bool isControl(message_t* m) {
+        uint8_t token = getHeader(m)->token;
+        return isFlagSet(&token, TOKEN_ACK_FLAG);
+    }
+    
     /****************  SplitControl  *****************/
 
     task void StartDoneTask() {
+        atomic {
+            macState = RX;
+            call UartPhyControl.setNumPreambles(MIN_PREAMBLE_BYTES);
+        }
+        post ReleaseAdcTask();
         signal SplitControl.startDone(SUCCESS);
     }
 
@@ -320,9 +403,9 @@ implementation
         call CcaStdControl.start();
         atomic {
             macState = INIT;
-            signalMacState();
+            
             setRxMode();
-            storeOldState(1);
+            sdDebug(1);
         }
         return SUCCESS;
     }
@@ -331,11 +414,15 @@ implementation
         atomic {
             if (macState != RX) {
                 post StopDone();
-                storeOldState(2);
+                sdDebug(2);
             } else {
-                storeOldState(3);
+                sdDebug(3);
                 call Timer.stop();
-                call Init.init();
+                txBufPtr = NULL;
+                macState = INIT;
+                shortRetryCounter = 0;
+                longRetryCounter = 0;
+                flags = 0;
                 signal SplitControl.stopDone(SUCCESS); 
             }
         }
@@ -343,75 +430,100 @@ implementation
     
     command error_t SplitControl.stop() {
         call CcaStdControl.stop();
-        storeOldState(4);
+        sdDebug(4);
         post StopDone();
         return SUCCESS;
     }
     
+    /****** Packet interface ********************/
+    command void Packet.clear(message_t* msg) {
+        call SubPacket.clear(msg);
+    }
+    
+    command uint8_t Packet.payloadLength(message_t* msg) {
+        return call SubPacket.payloadLength(msg);
+    }
+    
+    command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+        call SubPacket.setPayloadLength(msg,len);
+    }
+    
+    command uint8_t Packet.maxPayloadLength() {
+        return call SubPacket.maxPayloadLength();
+    }
+    
+    command void* Packet.getPayload(message_t* msg, uint8_t len) {
+        return call SubPacket.getPayload(msg, len);
+    }
+   
     /****** Radio(Mode) events *************************/
     async event void RadioModes.RssiStable() {
         atomic  {
             setFlag(&flags, RSSI_STABLE);
-            if(macState == SW_CCA)  {
-                storeOldState(10);
-                macState = CCA;
-                signalMacState();
-                call Timer.start(DIFS);
-                call ChannelMonitor.start();
-            } else if(macState == INIT) {
-                storeOldState(11);
-                call ChannelMonitorControl.updateNoiseFloor();
-            } else {
-                storeOldState(13);
+            if(macState == INIT) {
+                sdDebug(11);
+                if(call RssiAdcResource.isOwner()) {
+                    call ChannelMonitorControl.updateNoiseFloor();
+                }
+            }
+            else {
+                sdDebug(12);
             }
         }
     }
 
     async event void RadioModes.RxModeDone() {
+        post postponeReRx();
         atomic {
             if(macState == SW_RX) {
-                storeOldState(21);
+                sdDebug(21);
                 macState = RX;
-                signalMacState();
-                call Timer.start(backoff());
+                
+                if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                    clearFlag(&flags, RESUME_BACKOFF);
+                    call Timer.start(restLaufzeit);
+                } else {
+                    call Timer.start(backoff(longRetryCounter));
+                }
             }
             else if(macState == SW_RX_ACK) {
-                storeOldState(22);
+                sdDebug(22);
                 macState = RX_ACK;
-                signalMacState();
-                call Timer.start(ACK_TIMEOUT);
-            }
-            else if(macState == SW_CCA) {
-                storeOldState(23);
             }
             else if(macState == INIT) {
-                storeOldState(24);
+                sdDebug(24);
             }
             else {
-                storeOldState(25);
-                signalFailure(1);
+                sdDebug(25);
             }
         }
     }
 
     async event void RadioModes.TxModeDone() {
+        post postponeReRx();
         atomic {
             if(macState == SW_TX) {
-                storeOldState(30);
+                sdDebug(30);
                 if(txBufPtr) {
                     macState = TX;
-                    signalMacState();
                     if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
-                        storeOldState(31);
+                        sdDebug(31);
                     } else {
-                        storeOldState(32);
-                        signalFailure(2);
+                        sdDebug(32);
                     }
                 }
             }
+            else if(macState == SW_TX_ACK) {
+                macState = TX_ACK;
+                
+                if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
+                    sdDebug(53);
+                } else {
+                    sdDebug(54);
+                }
+            }
             else {
-                storeOldState(33);
-                signalFailure(3);
+                sdDebug(33);
             }
         }
     }
@@ -420,15 +532,22 @@ implementation
     async command error_t MacSend.send(message_t* msg, uint8_t len) {
         error_t err = SUCCESS;
         atomic {
-            if((shortRetryCounter == 0) && (txBufPtr == NULL)) {
-                storeOldState(40);
+            if((shortRetryCounter == 0) && (txBufPtr == NULL) && (macState != INIT)) { 
+              sdDebug(40);
                 shortRetryCounter = 1;
+                longRetryCounter = 1;
                 txBufPtr = msg;
                 txLen = len;
-                if((macState != RX_P) && (macState != RX_ACK)) checkSend();
+                sdDebug(10);
+                sdDebug(len);
+                seqNo++;
+                if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
+                getHeader(msg)->token = seqNo;
+                if(needsAckTx(msg)) getHeader(msg)->token |= ACK_REQUESTED;
+                if(macState != RX_P) checkSend();
             }
             else {
-                storeOldState(41);
+                sdDebug(41);
                 err = EBUSY;
             }
         }
@@ -439,14 +558,14 @@ implementation
         error_t err = SUCCESS;
         if((shortRetryCounter != 0) && (txBufPtr == msg) &&
            (macState != TX) && (macState != RX_ACK) && (macState != SW_RX_ACK)) {
-            storeOldState(50);
+            sdDebug(50);
             shortRetryCounter = 0;
             txBufPtr = NULL;
             txLen = 0;
             signal MacSend.sendDone(msg, ECANCEL);
         }
         else {
-            storeOldState(51);
+            sdDebug(51);
             err = FAIL;
         }
         return err;
@@ -454,178 +573,250 @@ implementation
     
     /****** PacketSerializer events **********************/
     async event void PacketReceive.receiveDetected() {
+        rssiValue = INVALID_SNR;
         if(macState <= RX_ACK) {
-            storeOldState(60);
-            rssiValue = 0xFFFF;
-            call Timer.stop();
-            clearFlag(&flags, CHECK_RX_LIVENESS);
-            if(isFlagSet(&flags, BUSY_DETECTED_VIA_RSSI)) call ChannelMonitor.rxSuccess();
-            call  ChannelMonitorData.getSnr();
+            sdDebug(60);
+            interruptBackoffTimer();
+            if(macState == CCA) computeBackoff();
         }
         if(macState <= RX) {
-            storeOldState(61);
+            sdDebug(61);
             macState = RX_P;
-            signalMacState();
+            
+            requestAdc();
         }
         else if(macState <= RX_ACK) {
-            storeOldState(62);
-            macState = RX_ACK;
-            signalMacState();
+            sdDebug(62);
+            macState = RX_ACK_P;
+            
         }
         else if(macState == INIT) {
-            storeOldState(63);
+            sdDebug(63);
         }
         else {
-            storeOldState(64);
-            signalFailure(4);
+          post ReleaseAdcTask();  
+          sdDebug(64);
         } 
     }
     
     async event message_t* PacketReceive.receiveDone(message_t* msg, void* payload, uint8_t len, error_t error) {
         message_t* m = msg;
+        bool isCnt;
+        macState_t action = RX;
         if(macState == RX_P) {
-            storeOldState(70);
-            if (error == SUCCESS) {
-                storeOldState(71);
-                (getMetadata(msg))->strength = rssiValue;
-                m = signal MacReceive.receiveDone(msg);
+            if(error == SUCCESS) {
+                sdDebug(82);
+                isCnt = isControl(msg);
+                if(msgIsForMe(msg)) {
+                    if(!isCnt) {
+                        storeStrength(msg);
+                        if(isNewMsg(m)) {
+                            m = signal MacReceive.receiveDone(msg);
+                            rememberMsg(m);   
+                        }
+                        if(needsAckRx(msg)) {
+                            sdDebug(87);
+                            action = CCA_ACK;
+                        } else {
+                            sdDebug(88);
+                        }
+                    }
+                    else {
+                        sdDebug(89);
+                    }
+                }
+                else {
+                    sdDebug(90);
+                }
+            }
+            else {
+                sdDebug(91);
             }
-            macState = RX;
-            signalMacState();
-            call Timer.start(backoff());
         }
-        else if(macState == RX_ACK) {
-            storeOldState(72);
-            if(txBufPtr == NULL) signalFailure(5);
-            if((error == SUCCESS) &&
-               getFooter(msg)->crc &&
-               (getHeader(msg)->type == CSMA_ACK) &&
-               (*((uint16_t*)(msg->data)) == TOS_NODE_ID))
-            {
-                storeOldState(73);
-                getMetadata(txBufPtr)->ack = 1;
-                signalSendDone(SUCCESS);
+        else if(macState == RX_ACK_P) {
+            if(error == SUCCESS) {
+                if(ackIsForMe(msg)) {
+                    sdDebug(92);
+                    (getMetadata(txBufPtr))->ack = WAS_ACKED;
+                    signalSendDone(SUCCESS);
+                }
+                else {
+                    sdDebug(93);
+                    updateLongRetryCounters();
+                }
             }
             else {
-                storeOldState(74);
-                updateRetryCounters();
+                if(call Timer.isRunning()) {
+                    sdDebug(94);
+                    action = RX_ACK;
+                }
+                else {
+                    sdDebug(95);
+                    if(needsAckTx(txBufPtr)) {
+                        updateLongRetryCounters();
+                    }
+                    else {
+                        signalSendDone(SUCCESS);
+                    }
+                }
             }
+        }
+        else if(macState == INIT) {
+            action = INIT;
+        }
+        if(action == CCA_ACK) {
+            prepareAck(msg);
+            macState = CCA_ACK;
+            
+            call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + ADDED_DELAY);
+        }
+        else if(action == RX_ACK) {
+            macState = RX_ACK;
+            
+        }
+        else if(action == RX) {
             macState = RX;
-            signalMacState();
-            call Timer.start(backoff());
-        } else {
-            storeOldState(76);
+            
+            if(isFlagSet(&flags, RESUME_BACKOFF)) {
+                clearFlag(&flags, RESUME_BACKOFF);
+                call Timer.start(restLaufzeit);
+            }
+            else {
+                call Timer.start(backoff(longRetryCounter));
+            }
+        }
+        else if(action == TX) {
+            macState = SW_TX;
+            
+            setTxMode();
+        }
+        else if(action == INIT) {
+            
+        }
+        else {
+            sdDebug(94);
         }
-        return m;
+        post ReleaseAdcTask();
+        return m;        
     }
 
     async event void PacketSend.sendDone(message_t* msg, error_t error) {
         if(macState == TX) {
-            if(msg != txBufPtr) signalFailure(7);            
-            if(needsAck(msg)) {
-                if(error == SUCCESS) {
-                    storeOldState(80);
-                    macState = SW_RX_ACK;
-                    signalMacState();
-                } else {
-                    storeOldState(81);
-                    macState = SW_RX;
-                    signalMacState();
-                }
+            if(needsAckTx(msg)) {
+                sdDebug(97);
+                macState = SW_RX_ACK;
+                
+                call Timer.start(RX_ACK_TIMEOUT);
             } else {
-                macState = SW_RX;
-                signalMacState();
+                sdDebug(99);
                 signalSendDone(error);
+                macState = SW_RX;
+                
             }
+            setRxMode();
         }
         else if(macState == TX_ACK) {
-            storeOldState(83);
-            if(msg != &ackMsg) signalFailure(8);
             macState = SW_RX;
-            signalMacState();
-        }
-        else {
-            storeOldState(84);
-            signalFailure(9);
+            
+            setRxMode();
         }
-        setRxMode();
+        post ReleaseAdcTask();
     }
        
     
     /****** Timer ******************************/
+    void checkOnBusy() {
+        if(macState == CCA) {
+            computeBackoff();
+            macState = RX;
+            requestAdc();
+            sdDebug(150);
+            
+            if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME >> 1);
+        } else if(macState == RX) {
+            if(!call Timer.isRunning()) call Timer.start(TX_GAP_TIME + backoff(0));
+        }
+    }
+
+    void checkOnIdle()  {
+        if(macState == RX) {
+            checkSend();
+        }
+        else if(macState == CCA) {
+            checkCounter++;
+            if(checkCounter < 3) {
+                sdDebug(158);                
+                call Timer.start((TX_GAP_TIME + backoff(0))>>1);
+                requestAdc();
+            }
+            else {
+                call Timer.stop();
+                sdDebug(159);
+                macState = SW_TX;
+                
+                setTxMode();
+            }
+        }
+    }
     
     async event void Timer.fired() {
-        if(macState == RX) {
-            storeOldState(90);
-            if(isFlagSet(&flags, CHECK_RX_LIVENESS)) {
-                /* if(call UartPhyControl.isBusy()) {
-                    call Timer.start(CHECK_RX_LIVENESS_INTERVALL);
+        sdDebug(100);
+        if(macState == CCA) {
+            if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) {
+                if(call UartPhyControl.isBusy()) {
+                    sdDebug(101);
+                    checkOnBusy();
                 }
                 else {
-                */
-                    call ChannelMonitor.start();
-                    /*} */
+                    sdDebug(102);
+                    checkOnIdle();
+                }
             } else {
-                checkSend();
+              setFlag(&flags, CCA_PENDING);
             }
         }
         else if(macState == RX_ACK) {
-            storeOldState(91);
-            updateRetryCounters();
-            macState = RX;
-            signalMacState();
-            call Timer.start(backoff());
+            if(needsAckTx(txBufPtr)) {
+                sdDebug(103);
+                updateLongRetryCounters();
+                macState = RX;
+                call Timer.start(backoff(longRetryCounter));
+            }
+            else {
+                sdDebug(104);
+            }
         }
-        else if(macState == CCA) {
-            storeOldState(92);
-            setFlag(&flags, DIFS_TIMER_FIRED);
-            call ChannelMonitor.start();
+        else if(macState == CCA_ACK) {
+            sdDebug(160);
+            macState = SW_TX_ACK;
+            
+            setTxMode();
+        }
+        else if((macState == RX_ACK_P) || (macState == RX_P)) {
+            sdDebug(108);
+        }
+        else if(macState == INIT) {
+            sdDebug(109);
+            post StartDoneTask();
         }
         else {
-            storeOldState(93);
-            signalFailure(10);
+            sdDebug(110);
+            checkSend();
         }
     }
     
     /****** ChannelMonitor events *********************/
 
     async event void ChannelMonitor.channelBusy() {
-        atomic {
-            if(macState == CCA) {
-                storeOldState(100);
-                macState = RX;
-                signalMacState();
-                setFlag(&flags, BUSY_DETECTED_VIA_RSSI);
-                updateRetryCounters();
-                call Timer.start(backoff());
-            }
-            else if(macState == RX_P) {
-                storeOldState(101);
-                setFlag(&flags, BUSY_DETECTED_VIA_RSSI);
-            }
-            else if((macState == RX) && (isFlagSet(&flags, CHECK_RX_LIVENESS))) {
-                storeOldState(102);
-                call Timer.start(CHECK_RX_LIVENESS_INTERVALL);
-            }
-        }
+      clearFlag(&flags, CCA_PENDING);  
+      sdDebug(120);
+        checkOnBusy();
     }
 
     async event void ChannelMonitor.channelIdle() {
-        storeOldState(110);
-        if((macState == RX) && (isFlagSet(&flags, CHECK_RX_LIVENESS))) {
-                storeOldState(111);
-                clearFlag(&flags, CHECK_RX_LIVENESS);
-                call Timer.start(backoff());
-        }
-        else if(macState == CCA) {
-          if(isFlagSet(&flags, DIFS_TIMER_FIRED)) {    
-            clearFlag(&flags, DIFS_TIMER_FIRED);
-            storeOldState(112);
-            macState = SW_TX;
-            signalMacState();
-            setTxMode();
-          }
-        }
+      clearFlag(&flags, CCA_PENDING);  
+      sdDebug(121);
+        checkOnIdle();
     }
 
 
@@ -633,28 +824,82 @@ implementation
     
     event void ChannelMonitorControl.updateNoiseFloorDone() {
         if(macState == INIT) {
-            storeOldState(120);
-            macState = RX;
-            signalMacState();
+            sdDebug(122);
             post StartDoneTask();
         } else {
-            storeOldState(121);
-            signalFailure(11);
+            sdDebug(124);
         }
     }
 
     /***** ChannelMonitorData events ******************/
     
     async event void ChannelMonitorData.getSnrDone(int16_t data) {
-        atomic if(macState == RX_P) rssiValue = data;
+        atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data;
+        post ReleaseAdcTask();  
     }
-
     
     /***** unused Radio Modes events **************************/
     
     async event void RadioModes.TimerModeDone() {}
-    async event void RadioModes.SleepModeDone() {}
+
+    async event void RadioModes.SleepModeDone() {
+        atomic setRxMode();
+    }
+    
     async event void RadioModes.SelfPollingModeDone() {}
     async event void RadioModes.PWDDDInterrupt() {}
+
+    event void ReRxTimer.fired() {
+        atomic {
+            if((macState == RX) && (call RadioModes.SleepMode() == SUCCESS)) {
+                // ok 
+            }
+            else {
+                post postponeReRx();
+            }
+        }
+    }
+    
+    /***** abused TimeStamping events **************************/
+    async event void RadioTimeStamping.receivedSFD( uint16_t time ) {
+        if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
+        if(macState == RX_P) {
+            rxTime = call LocalTime32kHz.get();
+            call ChannelMonitor.rxSuccess();
+        }
+    }
+    
+    async event void RadioTimeStamping.transmittedSFD( uint16_t time, message_t* p_msg ) {
+        if((macState == TX) && (p_msg == txBufPtr)) {
+            // to do
+        }
+    }
+
+    /***** Rssi Resource events ******************/
+    event void RssiAdcResource.granted() {
+        macState_t ms;
+        atomic ms = macState;
+        if((ms == INIT) && isFlagSet(&flags, RSSI_STABLE)) {
+            sdDebug(145);
+            call ChannelMonitorControl.updateNoiseFloor();            
+        }
+        else {
+            sdDebug(146);
+            call RssiAdcResource.release();
+        }
+    }
+    
+    /***** RadioData Resource events **************/
+    async event void RadioResourceRequested.requested() {
+      atomic {
+        /* This gives other devices the chance to get the Resource
+           because RxMode implies a new arbitration round.  */
+        if (macState == RX) setRxMode();
+      }
+    }
+    
+    // we don't care about urgent Resource requestes
+    async event void RadioResourceRequested.immediateRequested() {}
 }
 
+