]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/tda5250/mac/CsmaMacP.nc
added SpeckMac
[tinyos-2.x.git] / tos / chips / tda5250 / mac / CsmaMacP.nc
index e221db75eaf0d707a075139b0dfec113189ca5b6..46c19d3f00ade28edadea12a44a6d46a3bf95847 100644 (file)
@@ -69,6 +69,9 @@ module CsmaMacP {
         interface Resource as RssiAdcResource;
 
         interface Random;
+
+        interface Timer<TMilli> as ReRxTimer;
+        interface Duplicate;
         
         interface Alarm<T32khz, uint16_t> as Timer;
         async command am_addr_t amAddress();
@@ -85,27 +88,26 @@ implementation
 {
 
     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=35,          // 4 Phy Preamble at 38400
+        BYTE_TIME=21,                 // byte at 23405 kBit/s, 4b6b encoded
+        PREAMBLE_BYTE_TIME=14,        // byte at 23405 kBit/s, no coding
+        PHY_HEADER_TIME=84,           // 6 Phy Preamble at 23405 bits/s
+
         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
+        SUB_FOOTER_TIME=2*BYTE_TIME, // 2 bytes crc 
         MAXTIMERVALUE=0xFFFF,        // helps to compute backoff
         DATA_DETECT_TIME=17,
-        RX_SETUP_TIME=111,    // time to set up receiver
-        TX_SETUP_TIME=69,     // time to set up transmitter
+        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 + 4 + 3*ADDED_DELAY,
-        TX_GAP_TIME=RX_ACK_TIMEOUT + TX_SETUP_TIME + 11,
-        MIN_BACKOFF_MASK=0x3F,   // about txrx_turnaround time
+        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,
-        MSG_TABLE_ENTRIES=5,
-        MAX_AGE=2*MAX_LONG_RETRY*MAX_SHORT_RETRY,
+        INVALID_SNR = 0xffff
     };
     
 /**************** Module Global Variables  *****************/
@@ -149,27 +151,10 @@ implementation
     uint8_t flags;
     uint8_t seqNo;
     
-    uint16_t slotMask;
     uint16_t restLaufzeit;
 
-    /* duplicate suppression */
-    typedef struct knownMessage_t {
-        am_addr_t src;
-        uint8_t token;
-        uint8_t age;
-    } knownMessage_t;
+    uint16_t rssiValue = 0;
     
-    knownMessage_t knownMsgTable[MSG_TABLE_ENTRIES];
-
-    task void ageMsgsTask() {
-        unsigned i;
-        atomic {
-            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
-                if(knownMsgTable[i].age <= MAX_AGE) ++knownMsgTable[i].age;
-            }
-        }
-    }
-
     /****** debug vars & defs & functions  ***********************/
 #ifdef MACM_DEBUG
 #define HISTORY_ENTRIES 100
@@ -272,6 +257,7 @@ implementation
     }
     
     void setRxMode() {
+        rssiValue = INVALID_SNR;
         if(call RadioModes.RxMode() == FAIL) {
             post SetRxModeTask();
         }
@@ -306,12 +292,13 @@ implementation
     }
 
     /**************** Helper functions ********/
+
+    task void postponeReRx() {
+        call ReRxTimer.startOneShot(5000);
+    }
+    
     uint16_t backoff(uint8_t counter) {
-        uint16_t mask = MIN_BACKOFF_MASK;
-        unsigned i;
-        for(i = 0; i < counter; i++) {
-            mask = (mask << 1) + 1;
-        }
+        uint16_t mask = BACKOFF_MASK >> (MAX_LONG_RETRY - counter);
         return (call Random.rand16() & mask);
     }
 
@@ -325,12 +312,29 @@ implementation
                 restLaufzeit = restLaufzeit - now;
             }
             else {
-                restLaufzeit +=  MAXTIMERVALUE - now;
+                restLaufzeit =  (uint16_t)(-1) - restLaufzeit + now;
+            }
+            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;
@@ -343,6 +347,7 @@ implementation
             if(isFlagSet(&flags, CANCEL_SEND)) {
                 e = ECANCEL;
             }
+            storeStrength(m);
             clearFlag(&flags, CANCEL_SEND);
         }
         signal MacSend.sendDone(m, e);
@@ -380,36 +385,11 @@ implementation
     }
 
     bool isNewMsg(message_t* msg) {
-        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;
-                return FALSE;
-            }
-        }
-        return TRUE;
-    }
-
-    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)->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)->token) & TOKEN_ACK_MASK);
     }
     
     void checkSend() {
@@ -477,7 +457,6 @@ implementation
     /**************** Init ************************/
     
     command error_t Init.init(){
-        unsigned i;
         atomic {
             txBufPtr = NULL;
             macState = INIT;
@@ -485,10 +464,6 @@ implementation
             shortRetryCounter = 0;
             longRetryCounter = 0;
             flags = 0;
-            slotMask = MIN_BACKOFF_MASK;
-            for(i = 0; i < MSG_TABLE_ENTRIES; i++) {
-                knownMsgTable[i].age = MAX_AGE;
-            }
 #ifdef MACM_DEBUG
             histIndex = 0;
 #endif
@@ -557,7 +532,7 @@ implementation
         return call SubPacket.maxPayloadLength();
     }
     
-    command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+    command void* Packet.getPayload(message_t* msg, uint8_t len) {
         return call SubPacket.getPayload(msg, len);
     }
    
@@ -578,6 +553,7 @@ implementation
     }
 
     async event void RadioModes.RxModeDone() {
+        post postponeReRx();
         atomic {
             if(macState == SW_RX) {
                 storeOldState(21);
@@ -606,6 +582,7 @@ implementation
     }
 
     async event void RadioModes.TxModeDone() {
+        post postponeReRx();
         atomic {
             if(macState == SW_TX) {
                 storeOldState(30);
@@ -680,19 +657,18 @@ implementation
     
     /****** PacketSerializer events **********************/
     async event void PacketReceive.receiveDetected() {
-      if(macState <= RX_ACK) {
+        rssiValue = INVALID_SNR;
+        if(macState <= RX_ACK) {
             storeOldState(60);
             interruptBackoffTimer();
             if(macState == CCA) computeBackoff();
         }
         if(macState <= RX) {
-          post ReleaseAdcTask();  
-          storeOldState(61);
+            storeOldState(61);
             macState = RX_P;
             signalMacState();
         }
         else if(macState <= RX_ACK) {
-            post ReleaseAdcTask();
             storeOldState(62);
             macState = RX_ACK_P;
             signalMacState();
@@ -713,12 +689,11 @@ implementation
         macState_t action = RX;
         if(macState == RX_P) {
             if(error == SUCCESS) {
-                post ageMsgsTask();
                 storeOldState(82);
                 isCnt = isControl(msg);
                 if(msgIsForMe(msg)) {
                     if(!isCnt) {
-                        (getMetadata(m))->strength = 10;
+                        storeStrength(msg);
                         if(isNewMsg(m)) {
                             m = signal MacReceive.receiveDone(msg);
                             rememberMsg(m);   
@@ -746,7 +721,6 @@ implementation
             if(error == SUCCESS) {
                 if(ackIsForMe(msg)) {
                     storeOldState(92);
-                    (getMetadata(txBufPtr))->strength = 10;
                     (getMetadata(txBufPtr))->ack = WAS_ACKED;
                     signalSendDone(SUCCESS);
                 }
@@ -949,18 +923,35 @@ implementation
     /***** ChannelMonitorData events ******************/
     
     async event void ChannelMonitorData.getSnrDone(int16_t 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) call ChannelMonitor.rxSuccess();
     }