]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/mac/tkn154/DispatchUnslottedCsmaP.nc
bugfix: radio token was not properly transferred when MLME_SCAN/_RX_ENABLE was called...
[tinyos-2.x.git] / tos / lib / mac / tkn154 / DispatchUnslottedCsmaP.nc
index b323dcefd45e7b3eb0553d8886c5fc5517041d2d..6be52f45ea6417af89c5037532b0a4c4f1a3aa83 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
@@ -65,12 +61,14 @@ module DispatchUnslottedCsmaP
   {
     interface Timer<TSymbolIEEE802154> as IndirectTxWaitTimer;
     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,7 +167,6 @@ 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();
@@ -230,7 +227,6 @@ implementation
     //  m_transactionTime += call MLME_GET.macMinLIFSPeriod(); 
     // else 
     //  m_transactionTime += call MLME_GET.macMinSIFSPeriod(); 
-    m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
     m_currentFrame = frame;
   }
 
@@ -259,15 +255,16 @@ implementation
       // 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 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 RadioToken.request(); // we want it back afterwards ...
+          m_lock = FALSE; // unlock
           call RadioToken.release();
           return;
         } else 
@@ -280,12 +277,11 @@ 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();
         }
       }
@@ -333,7 +329,7 @@ implementation
     return next;
   }
 
-  next_state_t tryReceive(bool startIndirectTxTimer)
+  next_state_t tryReceive()
   {
     next_state_t next;
     if (call RadioRx.isReceiving())
@@ -342,8 +338,6 @@ implementation
       next = SWITCH_OFF;
     else {
       call RadioRx.enableRx(0, 0);
-      if (startIndirectTxTimer)
-        post startIndirectTxTimerTask();
       next = WAIT_FOR_RXDONE;
     }
     return next;
@@ -359,15 +353,34 @@ 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) { 
+  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() 
   { 
     atomic {
@@ -380,7 +393,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, 
@@ -507,4 +520,6 @@ implementation
   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(); }
 }