]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/mac/tkn154/DispatchUnslottedCsmaP.nc
Added a component that accepts beacon request frames and responds with a beacon ...
[tinyos-2.x.git] / tos / lib / mac / tkn154 / DispatchUnslottedCsmaP.nc
index cb00450b9ceb112115b2845f8bd580a68e644eca..adde0792f6040269fdc5ff2d507253f8af072957 100644 (file)
  * not part of the MAC implementation but of the chip-specific radio driver.
  */
 
-#if IEEE154_BEACON_ENABLED_PAN
-#error "The IEEE154_BEACON_ENABLED_PAN macro MUST NOT be set when using this component!"
-#endif
-
 module DispatchUnslottedCsmaP
 {
   provides
@@ -64,13 +60,15 @@ module DispatchUnslottedCsmaP
   uses
   {
     interface Timer<TSymbolIEEE802154> as IndirectTxWaitTimer;
-    interface Resource as Token;
-    interface GetNow<bool> as IsTokenRequested;
+    interface TransferableResource as RadioToken;
+    interface ResourceRequested as RadioTokenRequested;
+    interface GetNow<token_requested_t> as IsRadioTokenRequested;
     interface GetNow<bool> as IsRxEnableActive; 
     interface Set<ieee154_macSuperframeOrder_t> as SetMacSuperframeOrder;
     interface Set<ieee154_macPanCoordinator_t> as SetMacPanCoordinator;     
     interface Get<ieee154_txframe_t*> as GetIndirectTxFrame; 
     interface Notify<bool> as RxEnableStateChange;
+    interface Notify<const void*> as PIBUpdateMacRxOnWhenIdle;
     interface FrameUtility;
     interface UnslottedCsmaCa;
     interface RadioRx;
@@ -100,6 +98,7 @@ implementation
   norace bool m_resume;
   norace ieee154_txframe_t *m_currentFrame;
   norace ieee154_txframe_t *m_lastFrame;
+  norace ieee154_macRxOnWhenIdle_t m_macRxOnWhenIdle;
 
   /* variables for the unslotted CSMA-CA */
   norace ieee154_csma_t m_csma;
@@ -110,10 +109,9 @@ implementation
   norace ieee154_status_t m_txStatus;
   norace uint32_t m_transactionTime;
   norace bool m_indirectTxPending = FALSE;
-  norace ieee154_macMaxFrameTotalWaitTime_t m_macMaxFrameTotalWaitTime;
 
   /* function / task prototypes */
-  next_state_t tryReceive(bool startIndirectTxTimer);
+  next_state_t tryReceive();
   next_state_t tryTransmit();
   next_state_t trySwitchOff();
   void backupCurrentFrame();
@@ -169,12 +167,12 @@ implementation
       call MLME_SET.macPANId(panID);
       call MLME_SET.phyCurrentChannel(logicalChannel);
       call MLME_SET.macBeaconOrder(beaconOrder);
-      call SetMacSuperframeOrder.set(superframeOrder);
       call SetMacPanCoordinator.set(panCoordinator);
       //TODO: check realignment
       post signalStartConfirmTask();
       status = IEEE154_SUCCESS;
     }      
+    dbg_serial("DispatchUnslottedCsmaP", "MLME_START.request -> result: %lu\n", (uint32_t) status);
     return status;
   }
 
@@ -191,21 +189,32 @@ implementation
       return IEEE154_TRANSACTION_OVERFLOW;
     } else {
       setCurrentFrame(frame);
-      call Token.request();
+      if (call RadioToken.isOwner())
+        updateState();
+      else
+        call RadioToken.request();      
       return IEEE154_SUCCESS;
     }
   }
 
-  event void Token.granted()
+  event void RadioToken.granted()
   {
     updateState();
   }
 
   void setCurrentFrame(ieee154_txframe_t *frame)
   {
-    ieee154_macDSN_t dsn = call MLME_GET.macDSN();
-    frame->header->mhr[MHR_INDEX_SEQNO] = dsn++;
-    call MLME_SET.macDSN(dsn);
+    if (frame->header->mhr[MHR_INDEX_FC1] != FC1_FRAMETYPE_BEACON) { 
+      // set the sequence number for command/data frame
+      ieee154_macDSN_t dsn = call MLME_GET.macDSN();
+      frame->header->mhr[MHR_INDEX_SEQNO] = dsn++;
+      call MLME_SET.macDSN(dsn);
+    } else {
+      // set the sequence number for beacon frame
+      ieee154_macBSN_t bsn = call MLME_GET.macBSN(); 
+      frame->header->mhr[MHR_INDEX_SEQNO] = bsn++;
+      call MLME_SET.macBSN(bsn);
+    }    
     m_csma.NB = 0;
     m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs = call MLME_GET.macMaxCSMABackoffs();
     m_csma.macMaxBE = m_macMaxBE = call MLME_GET.macMaxBE();
@@ -226,7 +235,6 @@ implementation
     //  m_transactionTime += call MLME_GET.macMinLIFSPeriod(); 
     // else 
     //  m_transactionTime += call MLME_GET.macMinSIFSPeriod(); 
-    m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
     m_currentFrame = frame;
   }
 
@@ -248,23 +256,24 @@ implementation
       // long atomics are bad... but in this block, once the
       // current state has been determined only one branch will
       // be taken (there are no loops)
-      if (m_lock || !call Token.isOwner())
+      if (m_lock || !call RadioToken.isOwner())
         return;
       m_lock = TRUE; // lock
 
       // Check 1: was an indirect transmission successfully started 
       // and are we now waiting for a frame from the coordinator?
       if (m_indirectTxPending) {
-        next = tryReceive(TRUE);
+        next = tryReceive();
       }
 
       // Check 2: is some other operation (like MLME-SCAN or MLME-RESET) pending? 
-      else if (call IsTokenRequested.getNow()) {
+      else if (call IsRadioTokenRequested.getNow()) {
         if (call RadioOff.isOff()) {
           // nothing more to do... just release the Token
-          m_lock = FALSE; // unlock
           dbg_serial("DispatchUnslottedCsmaP", "Token requested: releasing it.\n");
-          call Token.release();
+          call RadioToken.request(); // we want it back afterwards ...
+          m_lock = FALSE; // unlock
+          call RadioToken.release();
           return;
         } else 
           next = SWITCH_OFF;
@@ -276,24 +285,23 @@ implementation
       }
 
       // Check 4: should we be in receive mode?
-      else if (call IsRxEnableActive.getNow()) {
-        next = tryReceive(FALSE);
+      else if (call IsRxEnableActive.getNow() || m_macRxOnWhenIdle) {
+        next = tryReceive();
         if (next == DO_NOTHING) {
-          // this means there is an active MLME_RX_ENABLE.request
-          // and the radio was just switched to Rx mode - signal
-          // a notify event to inform the next higher layer
+          // if there was an active MLME_RX_ENABLE.request then we'll
+          // inform the next higher layer that radio is now in Rx mode
           post wasRxEnabledTask();
         }
       }
 
-      // Check 6: just make sure the radio is switched off  
+      // Check 5: just make sure the radio is switched off  
       else {
         next = trySwitchOff();
         if (next == DO_NOTHING) {
           // nothing more to do... just release the Token
           m_lock = FALSE; // unlock
           dbg_serial("DispatchUnslottedCsmaP", "Releasing token\n");
-          call Token.release();
+          call RadioToken.release();
           return;
         }
       }
@@ -329,7 +337,7 @@ implementation
     return next;
   }
 
-  next_state_t tryReceive(bool startIndirectTxTimer)
+  next_state_t tryReceive()
   {
     next_state_t next;
     if (call RadioRx.isReceiving())
@@ -338,8 +346,6 @@ implementation
       next = SWITCH_OFF;
     else {
       call RadioRx.enableRx(0, 0);
-      if (startIndirectTxTimer)
-        post startIndirectTxTimerTask();
       next = WAIT_FOR_RXDONE;
     }
     return next;
@@ -355,9 +361,33 @@ implementation
     return next;
   }
 
-  async event void RadioOff.offDone() { m_lock = FALSE; updateState();}
-  async event void RadioRx.enableRxDone() { m_lock = FALSE; updateState();}
-  event void RxEnableStateChange.notify(bool whatever) { updateState();}
+  async event void RadioOff.offDone() 
+  { 
+    m_lock = FALSE; 
+    updateState();
+  }
+
+  async event void RadioRx.enableRxDone() 
+  { 
+    if (m_indirectTxPending) // indirect transmission, now waiting for data
+      post startIndirectTxTimerTask();
+    m_lock = FALSE; 
+    updateState();
+  }
+
+  event void RxEnableStateChange.notify(bool whatever) 
+  { 
+    if (!call RadioToken.isOwner())
+      call RadioToken.request();
+    else
+      updateState();
+  }
+
+  event void PIBUpdateMacRxOnWhenIdle.notify( const void* val ) 
+  {
+    atomic m_macRxOnWhenIdle = *((ieee154_macRxOnWhenIdle_t*) val);
+    signal RxEnableStateChange.notify(TRUE);
+  }
 
   event void IndirectTxWaitTimer.fired() 
   { 
@@ -371,7 +401,7 @@ implementation
 
   task void startIndirectTxTimerTask()
   {
-    call IndirectTxWaitTimer.startOneShot(m_macMaxFrameTotalWaitTime); 
+    call IndirectTxWaitTimer.startOneShot(call MLME_GET.macMaxFrameTotalWaitTime()); 
   }
 
   async event void UnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame, 
@@ -458,8 +488,11 @@ implementation
     uint8_t *payload = (uint8_t *) frame->data;
     uint8_t *mhr = MHR(frame);
     uint8_t frameType = mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK;
+
     if (frameType == FC1_FRAMETYPE_CMD)
       frameType += payload[0];
+    dbg("DispatchUnslottedCsmaP", "Received frame, DSN: %lu, type: 0x%lu\n", 
+        (uint32_t) mhr[MHR_INDEX_SEQNO], (uint32_t) frameType);
     atomic {
       if (m_indirectTxPending) {
         message_t* frameBuf;
@@ -494,4 +527,7 @@ implementation
   command error_t WasRxEnabled.enable() {return FAIL;}
   command error_t WasRxEnabled.disable() {return FAIL;}
   default event void MLME_START.confirm(ieee154_status_t status) {}
+  async event void RadioToken.transferredFrom(uint8_t fromClientID) {ASSERT(0);}
+  async event void RadioTokenRequested.requested(){ updateState(); }
+  async event void RadioTokenRequested.immediateRequested(){ updateState(); }
 }