]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/mac/tkn154/BeaconTransmitP.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / lib / mac / tkn154 / BeaconTransmitP.nc
index 3d0dd438868e2ffc290d7b6aa36890e5ed3b52f5..7ddc5a284746da7e24372e5a2d1378fa4d4e43f4 100644 (file)
  * ========================================================================
  */
 
+/** 
+ * This module is responsible for periodic beacon transmission in a 
+ * beacon-enabled PAN.
+ */
+
 #include "TKN154_MAC.h"
 #include "TKN154_PHY.h"
 module BeaconTransmitP
@@ -41,36 +46,20 @@ module BeaconTransmitP
   {
     interface Init as Reset;
     interface MLME_START;
-    interface WriteBeaconField as SuperframeSpecWrite;
-    interface Get<bool> as IsSendingBeacons;
-    interface GetNow<uint32_t> as CapStart; 
-    interface GetNow<ieee154_reftime_t*> as CapStartRefTime; 
-    interface GetNow<uint32_t> as CapLen; 
-    interface GetNow<uint32_t> as CapEnd; 
-    interface GetNow<uint32_t> as CfpEnd; 
-    interface GetNow<uint32_t> as CfpLen; 
-    interface GetNow<bool> as IsBLEActive; 
-    interface GetNow<uint16_t> as BLELen; 
-    interface GetNow<uint8_t*> as GtsField; 
-    interface GetNow<uint32_t> as SfSlotDuration; 
-    interface GetNow<uint32_t> as BeaconInterval; 
-    interface GetNow<uint8_t> as FinalCapSlot;
-    interface GetNow<uint8_t> as NumGtsSlots;
-    interface GetNow<bool> as BeaconFramePendingBit;
     interface IEEE154TxBeaconPayload;
+    interface SuperframeStructure as OutgoingSF;
+    interface GetNow<bool> as IsSendingBeacons;
   } uses {
     interface Notify<bool> as GtsSpecUpdated;
     interface Notify<bool> as PendingAddrSpecUpdated;
     interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
-    interface Alarm<TSymbolIEEE802154,uint32_t> as BeaconTxAlarm;
+    interface Alarm<TSymbolIEEE802154,uint32_t> as BeaconSendAlarm;
     interface Timer<TSymbolIEEE802154> as BeaconPayloadUpdateTimer;
     interface RadioOff;
-    interface Get<bool> as IsBeaconEnabledPAN;
     interface RadioTx as BeaconTx;
     interface MLME_GET;
     interface MLME_SET;
-    interface Resource as Token;
-    interface ResourceTransfer as TokenToBroadcast;
+    interface TransferableResource as RadioToken;
     interface FrameTx as RealignmentBeaconEnabledTx;
     interface FrameTx as RealignmentNonBeaconEnabledTx;
     interface FrameRx as BeaconRequestRx;
@@ -78,20 +67,63 @@ module BeaconTransmitP
     interface WriteBeaconField as PendingAddrWrite;
     interface FrameUtility;
     interface GetNow<bool> as IsTrackingBeacons;
-    interface GetNow<uint32_t> as LastBeaconRxTime;
-    interface GetNow<ieee154_reftime_t*> as LastBeaconRxRefTime; 
-    interface Ieee802154Debug as Debug;
+    interface SuperframeStructure as IncomingSF;
     interface Set<ieee154_macSuperframeOrder_t> as SetMacSuperframeOrder;
     interface Set<ieee154_macBeaconTxTime_t> as SetMacBeaconTxTime;
     interface Set<ieee154_macPanCoordinator_t> as SetMacPanCoordinator;
     interface GetSet<ieee154_txframe_t*> as GetSetRealignmentFrame;
     interface GetNow<bool> as IsBroadcastReady; 
     interface TimeCalc;
+    interface Random;
     interface Leds;
   }
 }
 implementation
 {
+  /* state variables */
+  norace uint8_t m_requestBitmap;
+  norace uint8_t m_txState;
+  uint8_t m_payloadState;
+  norace bool m_txOneBeaconImmediately;
+
+  /* variables that describe the current superframe configuration */
+  norace uint32_t m_startTime;
+  norace uint8_t m_beaconOrder;
+  norace uint8_t m_superframeOrder;
+  norace uint32_t m_beaconInterval;
+  norace uint32_t m_previousBeaconInterval;
+  norace uint32_t m_dt;
+  norace uint32_t m_lastBeaconTxTime;
+  norace ieee154_timestamp_t m_lastBeaconTxRefTime;
+  norace ieee154_macBattLifeExtPeriods_t m_battLifeExtPeriods;
+
+  /* variables that describe the latest superframe */
+  norace uint32_t m_sfSlotDuration;
+  norace bool m_framePendingBit;
+  norace uint8_t m_numCapSlots;
+  norace uint8_t m_numGtsSlots;
+  norace uint16_t m_battLifeExtDuration;
+  uint8_t m_gtsField[1+1+3*7];
+
+  /* variables that describe the beacon (payload) */
+  norace ieee154_txframe_t m_beaconFrame;
+  ieee154_header_t m_header; 
+  ieee154_metadata_t m_metadata; 
+  void *m_updateBeaconPayload;
+  uint8_t m_updateBeaconOffset;
+  uint8_t m_updateBeaconLength;
+  uint8_t m_beaconPayloadLen;
+  uint8_t m_pendingAddrLen;
+  uint8_t m_pendingGtsLen;
+
+  /* buffers for the parameters of the MLME-START request */
+  uint16_t m_updatePANId;
+  uint8_t m_updateLogicalChannel;
+  uint32_t m_updateStartTime;
+  norace uint8_t m_updateBeaconOrder;
+  uint8_t m_updateSuperframeOrder;
+  bool m_updatePANCoordinator;
+  bool m_updateBatteryLifeExtension;
 
   enum {
     MAX_BEACON_PAYLOAD_SIZE =  IEEE154_aMaxBeaconOverhead + IEEE154_aMaxBeaconPayloadLength,
@@ -114,87 +146,46 @@ implementation
     S_TX_LOCKED = 1,
     S_TX_WAITING = 2,
   };
-
-  norace ieee154_txframe_t m_beaconFrame;
-  ieee154_header_t m_header; 
   uint8_t m_payload[MAX_BEACON_PAYLOAD_SIZE]; 
-  ieee154_metadata_t m_metadata; 
-  uint8_t m_gtsField[1+1+3*7];
-
-  void *m_updateBeaconPayload;
-  uint8_t m_updateBeaconOffset;
-  uint8_t m_updateBeaconLength;
-  uint8_t m_beaconPayloadLen;
-  uint8_t m_pendingAddrLen;
-  uint8_t m_pendingGtsLen;
-
-  norace uint8_t m_requests; // TODO: check why norace?
-  norace uint8_t m_txState;
-  uint8_t m_payloadState;
-  norace bool m_txOneBeaconImmediately;
-
-  uint16_t m_PANId;
-  norace uint32_t m_startTime;
-  uint8_t m_logicalChannel;
-  norace uint8_t m_beaconOrder;
-  norace uint8_t m_superframeOrder;
-  ieee154_macBattLifeExt_t m_batteryLifeExtension;
-  bool m_PANCoordinator;
-  norace uint32_t m_beaconInterval;
-  norace uint32_t m_previousBeaconInterval;
-  norace uint32_t m_dt;
-  norace uint8_t m_bsn;
-  norace uint32_t m_lastBeaconTxTime;
-  norace ieee154_reftime_t m_lastBeaconTxRefTime;
-  norace uint32_t m_coordCapLen;
-  norace uint32_t m_coordCfpEnd;
-  norace uint32_t m_sfSlotDuration;
-  norace uint8_t m_finalCAPSlot;
-  norace uint8_t m_numGtsSlots;
-  norace uint16_t m_BLELen;
-  norace ieee154_macBattLifeExtPeriods_t m_battLifeExtPeriods;
-  norace bool m_framePendingBit;
-
-  uint16_t m_updatePANId;
-  uint8_t m_updateLogicalChannel;
-  uint32_t m_updateStartTime;
-  uint8_t m_updateBeaconOrder;
-  uint8_t m_updateSuperframeOrder;
-  bool m_updatePANCoordinator;
-  bool m_updateBatteryLifeExtension;
 
+  /* function/task prototypes */
   task void txDoneTask();
   task void signalStartConfirmSuccessTask();
-  void prepareNextBeaconTransmission();
+  void nextRound();
+  void prepareBeaconTransmission();
   void continueStartRequest();
   void finishRealignment(ieee154_txframe_t *frame, ieee154_status_t status);
 
   command error_t Reset.init()
   {
+    // reset this component, will only be called while we're not owning the token
+    // TODO: check to signal MLME_START.confirm ?
+
+    call MLME_SET.macBSN(call Random.rand16());
     m_beaconFrame.header = &m_header;
     m_beaconFrame.headerLen = 0;
     m_beaconFrame.payload = m_payload;
     m_beaconFrame.payloadLen = 0;
     m_beaconFrame.metadata = &m_metadata;
-    m_updateBeaconPayload = 0;
+    m_updateBeaconPayload = NULL;
     m_updateBeaconLength = 0;
-    m_requests = m_payloadState = m_txState = 0;
-    m_PANCoordinator = FALSE;
+    m_requestBitmap = m_payloadState = m_txState = 0;
     m_beaconPayloadLen = m_pendingAddrLen = m_pendingGtsLen = 0;
     m_gtsField[0] = 0;
-    m_finalCAPSlot = 15;
+    m_numCapSlots = 0;
+    m_numGtsSlots = 0;
     m_beaconOrder = 15;
     call BeaconPayloadUpdateTimer.stop();
-    call BeaconTxAlarm.stop();
+    call BeaconSendAlarm.stop();
     return SUCCESS;
   }
 
-/* ----------------------- MLME-START ----------------------- */
-/* "The MLME-START.request primitive allows the PAN coordinator to initiate a
- * new PAN or to begin using a new superframe configuration. This primitive may
- * also be used by a device already associated with an existing PAN to begin
- * using a new superframe configuration." (IEEE 802.15.4-2006 Sect. 7.1.14.1)
- **/
+  /* ----------------------- MLME-START ----------------------- */
+  /* "The MLME-START.request primitive allows the PAN coordinator to initiate a
  * new PAN or to begin using a new superframe configuration. This primitive may
  * also be used by a device already associated with an existing PAN to begin
  * using a new superframe configuration." (IEEE 802.15.4-2006 Sect. 7.1.14.1)
  **/
 
   command ieee154_status_t MLME_START.request  (
                           uint16_t panID,
@@ -209,9 +200,10 @@ implementation
                           ieee154_security_t *coordRealignSecurity,
                           ieee154_security_t *beaconSecurity)
   {
-    ieee154_macShortAddress_t shortAddress = call MLME_GET.macShortAddress();
     ieee154_status_t status = IEEE154_SUCCESS;
+    ieee154_macShortAddress_t shortAddress = call MLME_GET.macShortAddress();
 
+    // check parameters
     if ((coordRealignSecurity && coordRealignSecurity->SecurityLevel) ||
         (beaconSecurity && beaconSecurity->SecurityLevel))
       status = IEEE154_UNSUPPORTED_SECURITY;
@@ -224,23 +216,18 @@ implementation
       status =  IEEE154_INVALID_PARAMETER;
     else if (startTime && !call IsTrackingBeacons.getNow())
       status = IEEE154_TRACKING_OFF;
-    else if (startTime && 0xFF000000)
+    else if (startTime & 0xFF000000)
       status = IEEE154_INVALID_PARAMETER;
-    else if (m_requests & (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF))
+    else if (m_requestBitmap & (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF))
       status = IEEE154_TRANSACTION_OVERFLOW;
-    else if ((call IsBeaconEnabledPAN.get() && beaconOrder > 14) ||
-              (!call IsBeaconEnabledPAN.get() && beaconOrder < 15))
-      status = IEEE154_INVALID_PARAMETER;
     else {
-      // new configuration *will* be put in operation
-      status = IEEE154_SUCCESS;
+
+      // New configuration *will* be put in operation, we'll buffer
+      // the parameters now, and continue once we get the token.
       if (panCoordinator)
-        startTime = 0; // start immediately
-      call Debug.log(LEVEL_INFO, StartP_REQUEST, logicalChannel, beaconOrder, superframeOrder);
-      if (beaconOrder == 15){
-        // beaconless PAN
-        superframeOrder = 15;
-      }
+        startTime = 0;        // start immediately
+      if (beaconOrder == 15)
+        superframeOrder = 15; // beaconless PAN 
       m_updatePANId = panID;
       m_updateLogicalChannel = logicalChannel;
       m_updateStartTime = startTime;
@@ -248,12 +235,18 @@ implementation
       m_updateSuperframeOrder = superframeOrder;
       m_updatePANCoordinator = panCoordinator;
       m_updateBatteryLifeExtension = batteryLifeExtension;   
-      m_requests = (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF); // lock
+      m_requestBitmap = (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF); // lock
+
       if (coordRealignment)
-        m_requests |= REQUEST_REALIGNMENT;
-      if (!call IsSendingBeacons.get())
-        call Token.request();
+        m_requestBitmap |= REQUEST_REALIGNMENT;
+      if (m_beaconOrder == 15) {
+        // We're not already transmitting beacons, i.e. we have to request the token
+        // (otherwise we'd get the token "automatically" for the next scheduled beacon).
+        call RadioToken.request();
+      }
+      // We'll continue the MLME_START operation in continueStartRequest() once we have the token
     }
+    dbg_serial("BeaconTransmitP", "MLME_START.request -> result: %lu\n", (uint32_t) status);
     return status;
   }
 
@@ -264,12 +257,12 @@ implementation
     bool isShortAddr;
 
     // (1) coord realignment?
-    if (m_requests & REQUEST_REALIGNMENT){
+    if (m_requestBitmap & REQUEST_REALIGNMENT) {
       ieee154_txframe_t *realignmentFrame = call GetSetRealignmentFrame.get();
-      m_requests &= ~REQUEST_REALIGNMENT;
-      if (realignmentFrame == NULL){
+      m_requestBitmap &= ~REQUEST_REALIGNMENT;
+      if (realignmentFrame == NULL) {
         // allocation failed!
-        m_requests = 0;
+        m_requestBitmap = 0;
         signal MLME_START.confirm(IEEE154_TRANSACTION_OVERFLOW);
         return;
       }
@@ -282,11 +275,11 @@ implementation
       *((nxle_uint16_t*) &realignmentFrame->payload[6]) = 0xFFFF;
       realignmentFrame->payloadLen = 8;
       
-      if (call IsSendingBeacons.get()){
+      if (m_beaconOrder < 15) {
         // we're already transmitting beacons; the realignment frame
         // must be sent (broadcast) after the next beacon
-        if (call RealignmentBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS){
-          m_requests = 0;
+        if (call RealignmentBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS) {
+          m_requestBitmap = 0;
           call GetSetRealignmentFrame.set(realignmentFrame);
           signal MLME_START.confirm(IEEE154_TRANSACTION_OVERFLOW);
         } else {
@@ -294,12 +287,12 @@ implementation
           // the next beacon - the result will be signalled in 
           // RealignmentBeaconEnabledTx.transmitDone(). Only then the superframe
           // structure is updated and MLME_START.confirm signalled.
-          m_requests |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
+          m_requestBitmap |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
         }
       } else {
         // send realignment frame in unslotted csma-ca now
-        if (call RealignmentNonBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS){
-          m_requests = 0;
+        if (call RealignmentNonBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS) {
+          m_requestBitmap = 0;
           call GetSetRealignmentFrame.set(realignmentFrame);
           signal MLME_START.confirm(IEEE154_TRANSACTION_OVERFLOW);
         } else {
@@ -307,7 +300,7 @@ implementation
           // be signalled in RealignmentNonBeaconEnabledTx.transmitDone(). Only 
           // then the superframe structure is updated and MLME_START.confirm 
           // signalled.
-          m_requests |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
+          m_requestBitmap |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
         }
       }
       return; 
@@ -317,52 +310,48 @@ implementation
     m_startTime = m_updateStartTime;
     m_txOneBeaconImmediately = FALSE;
     m_previousBeaconInterval = 0;
-    if (m_startTime){
-      m_lastBeaconTxRefTime = *call LastBeaconRxRefTime.getNow();
-      m_lastBeaconTxTime = call LastBeaconRxTime.getNow();
+    if (m_startTime) {
+      memcpy(&m_lastBeaconTxRefTime, call IncomingSF.sfStartTimeRef(), sizeof(ieee154_timestamp_t));
+      m_lastBeaconTxTime = call IncomingSF.sfStartTime();
     } else {
       // no StartTime defined by next higher layer - but
       // if a realignment frame was transmitted, the next
       // beacon tx time must take the old BI into consideration
-      if (m_requests & REQUEST_REALIGNMENT_DONE_PENDING)
+      if (m_requestBitmap & REQUEST_REALIGNMENT_DONE_PENDING)
         m_previousBeaconInterval = m_beaconInterval;
       else
         m_txOneBeaconImmediately = TRUE;
     }
-    m_PANId = m_updatePANId;
-    m_logicalChannel = m_updateLogicalChannel;
     m_beaconOrder = m_updateBeaconOrder; 
     m_superframeOrder = m_updateSuperframeOrder;
-    m_PANCoordinator = m_updatePANCoordinator;
-    if (m_beaconOrder < 15){
-      m_batteryLifeExtension = m_updateBatteryLifeExtension;   
+    if (m_beaconOrder < 15) {
       m_beaconInterval = ((uint32_t) 1 << m_updateBeaconOrder) * IEEE154_aBaseSuperframeDuration;
     } else {
-      m_batteryLifeExtension = FALSE;   
       m_beaconInterval = 0;
     }
+    m_dt = m_beaconInterval;
     m_txState = S_TX_IDLE;
-    m_bsn = call MLME_GET.macBSN()+1;
     m_battLifeExtPeriods = call MLME_GET.macBattLifeExtPeriods();
 
     // (3) update PIB
     call MLME_SET.macBeaconOrder(m_beaconOrder);
     call SetMacSuperframeOrder.set(m_superframeOrder);
-    call MLME_SET.macPANId(m_PANId);
-    call MLME_SET.phyCurrentChannel(m_logicalChannel);
+    call MLME_SET.macPANId(m_updatePANId);
+    call MLME_SET.phyCurrentChannel(m_updateLogicalChannel);
     if (m_beaconOrder < 15)
-      call MLME_SET.macBattLifeExt(m_batteryLifeExtension);
-    call SetMacPanCoordinator.set(m_PANCoordinator);
+      call MLME_SET.macBattLifeExt(m_updateBatteryLifeExtension);
+    call SetMacPanCoordinator.set(m_updatePANCoordinator);
 
     // (4) assemble beacon header and payload
     shortAddress = call MLME_GET.macShortAddress();
     isShortAddr = (shortAddress != 0xFFFE);
     m_beaconFrame.header->mhr[MHR_INDEX_FC1] = FC1_FRAMETYPE_BEACON;
     m_beaconFrame.header->mhr[MHR_INDEX_FC2] = isShortAddr ? FC2_SRC_MODE_SHORT : FC2_SRC_MODE_EXTENDED;
+    m_beaconFrame.header->mhr[MHR_INDEX_SEQNO] = call MLME_GET.macBSN() + 1;
     offset = MHR_INDEX_ADDRESS;
-    *((nxle_uint16_t*) &m_beaconFrame.header->mhr[offset]) = m_PANId;
+    *((nxle_uint16_t*) &m_beaconFrame.header->mhr[offset]) = m_updatePANId;
     offset += sizeof(ieee154_macPANId_t);
-    if (isShortAddr){
+    if (isShortAddr) {
       *((nxle_uint16_t*) &m_beaconFrame.header->mhr[offset]) = shortAddress;
       offset += sizeof(ieee154_macShortAddress_t);
     } else {
@@ -373,190 +362,228 @@ implementation
     m_payloadState |= MODIFIED_SPECS_MASK;    // update beacon payload
     signal BeaconPayloadUpdateTimer.fired();  // assemble initial beacon payload
 
-    if (m_beaconOrder < 15){
+    if (m_beaconOrder < 15) {
       // beacon-enabled PAN, signal confirm after next 
       // beacon has been transmitted (see MSC, Fig. 38)
-      m_requests = REQUEST_CONFIRM_PENDING;
+      m_requestBitmap = REQUEST_CONFIRM_PENDING;
     } else {
       // beaconless PAN, we're done
-      m_requests = 0;
+      m_requestBitmap = 0;
       signal MLME_START.confirm(IEEE154_SUCCESS);
     }
   }
 
-  task void grantedTask()
+  task void signalGrantedTask()
   {
-    signal Token.granted();
+    signal RadioToken.granted();
   }
 
-  event void Token.granted()
+  event void RadioToken.granted()
   {
-    call Debug.flush();
-    call Debug.log(LEVEL_INFO, StartP_GOT_RESOURCE, m_lastBeaconTxTime, m_beaconInterval, m_requests);
-    if (m_requests & REQUEST_REALIGNMENT_DONE_PENDING){
-      // unlikely to occur: we have not yet received a done()
+    dbg_serial("BeaconSynchronizeP","Token granted.\n");
+    if (m_requestBitmap & REQUEST_REALIGNMENT_DONE_PENDING) {
+      // very unlikely: we have not yet received a done()
       // event after sending out a realignment frame 
-      post grantedTask(); // spin
+      dbg_serial("BeaconTransmitP", "Realignment pending (request: %lu) !\n", (uint32_t) m_requestBitmap);
+      post signalGrantedTask(); // spin
       return;
-    }
-    if (m_requests & REQUEST_UPDATE_SF){
-      m_requests &= ~REQUEST_UPDATE_SF;
+    } else if (m_requestBitmap & REQUEST_UPDATE_SF) {
+      dbg_serial("BeaconTransmitP","Putting new superframe spec into operation\n"); 
+      m_requestBitmap &= ~REQUEST_UPDATE_SF;
       continueStartRequest();
-      call Debug.log(LEVEL_INFO, StartP_UPDATE_STATE, 0, 0, 0);
     }
+    nextRound();
+  }
+
+  void nextRound()
+  {
     if (call RadioOff.isOff())
-      prepareNextBeaconTransmission();
+      prepareBeaconTransmission();
     else
-      call RadioOff.off();
+      ASSERT(call RadioOff.off() == SUCCESS); // will continue in prepareBeaconTransmission()
   }
 
+  async event void RadioToken.transferredFrom(uint8_t fromClientID)
+  {
+    dbg_serial("BeaconSynchronizeP","Token transferred, will Tx beacon in %lu\n",
+        (uint32_t) ((m_lastBeaconTxTime + m_dt) - call BeaconSendAlarm.getNow())); 
+    if (m_requestBitmap & (REQUEST_REALIGNMENT_DONE_PENDING | REQUEST_UPDATE_SF))
+      post signalGrantedTask(); // need to be in sync context
+    else
+      nextRound();
+  }  
+
   async event void RadioOff.offDone()
   {
-    prepareNextBeaconTransmission();
+    prepareBeaconTransmission();
   }
 
-  void prepareNextBeaconTransmission()
+  void prepareBeaconTransmission()
   {
-    if (m_txState == S_TX_LOCKED){
+    if (m_txState == S_TX_LOCKED) {
       // have not had time to finish processing the last sent beacon
-      post grantedTask();
-      call Debug.log(LEVEL_CRITICAL, StartP_OWNER_TOO_FAST, 0, 0, 0);
-      return;
-    } else if (m_beaconOrder > 14){
-      call Token.release();
+      dbg_serial("BeaconTransmitP", "Token was returned too fast!\n");
+      post signalGrantedTask();
+    } else if (m_beaconOrder == 15) {
+      // we're not sending any beacons!?
+      dbg_serial("BeaconTransmitP", "Stop sending beacons.\n");
+      call RadioToken.release();
     } else {
+      // get ready for next beacon transmission
       atomic {
+        uint32_t delay = IEEE154_RADIO_TX_DELAY; 
         m_txState = S_TX_WAITING;
-        if (m_txOneBeaconImmediately){
-          signal BeaconTxAlarm.fired();
+        if (m_txOneBeaconImmediately) {
+          // transmit the beacon now
+          dbg_serial("BeaconTransmitP", "Sending a beacon immediately.\n");
+          signal BeaconSendAlarm.fired();
           return;
-        } else if (m_startTime != 0){
-          // a new sf spec was put into operation, with a user-defined StartTime 
+        } else if (m_startTime != 0) {
+          // a new sf spec was put into operation, with a user-defined StartTime    
           // here m_lastBeaconTxTime is actually the last time a beacon was received
+
+          dbg_serial("BeaconTransmitP", "First beacon to be sent at %lu.\n", m_startTime);
           m_dt = m_startTime;
           m_startTime = 0;
-        } else if (m_previousBeaconInterval != 0){
-          // a new sf spec was put into operation, after a realignment frame was
+        } else if (m_previousBeaconInterval != 0) {
+          // a new sf spec was put into operation, after a realignment frame 
           // broadcast; the next beacon time should still be calculated using the
           // old BI (one last time)
+
+          dbg_serial("BeaconTransmitP", "Sending beacon after realignment dt=%lu.\n", m_previousBeaconInterval);
           m_dt = m_previousBeaconInterval;
           m_previousBeaconInterval = 0;
-          if (m_requests & REQUEST_CONFIRM_PENDING){
+          if (m_requestBitmap & REQUEST_CONFIRM_PENDING) {
             // only now the next higher layer is to be informed 
-            m_requests &= ~REQUEST_CONFIRM_PENDING;
+            m_requestBitmap &= ~REQUEST_CONFIRM_PENDING;
             post signalStartConfirmSuccessTask();
           }
-        } else {
-          // the usual case: next beacon tx time = last time + BI
-          m_dt = m_beaconInterval;
         }
-        while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)){ // missed sending a beacon
-          call Debug.log(LEVEL_INFO, StartP_SKIPPED_BEACON, m_lastBeaconTxTime, m_dt, 0);
+
+        // The next beacon should be transmitted at time m_lastBeaconTxTime + m_dt, where m_dt
+        // is typically the beacon interval. First we check if we're still in time.
+        while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)) { 
+          // too late, we need to skip a beacon!
+          dbg_serial("BeaconTransmitP", "Skipping a beacon: scheduled=%lu, now=%lu.\n", 
+              (uint32_t) m_lastBeaconTxTime + m_dt, (uint32_t) call BeaconSendAlarm.getNow());
           m_dt += m_beaconInterval;
         }
-        if (m_dt < IEEE154_RADIO_TX_PREPARE_DELAY)
-          m_dt = IEEE154_RADIO_TX_PREPARE_DELAY;
-        // don't call BeaconTx.load just yet, otherwise the next
-        // higher layer cannot modify the beacon payload anymore;
-        // rather, set an alarm 
-        call BeaconTxAlarm.startAt(m_lastBeaconTxTime, m_dt - IEEE154_RADIO_TX_PREPARE_DELAY);
+        if (!call TimeCalc.hasExpired(m_lastBeaconTxTime - delay, m_dt)) {
+          // don't load the beacon frame in the radio just yet - rather set a timer and
+          // give the next higher layer the chance to modify the beacon payload 
+          call BeaconSendAlarm.startAt(m_lastBeaconTxTime - delay, m_dt);
+        } else
+          signal BeaconSendAlarm.fired();
       }
     }
   }
 
-  async event void BeaconTxAlarm.fired()
+  task void signalStartConfirmSuccessTask()
   {
-    atomic {
-      switch (m_txState)
-      {
-        case S_TX_WAITING: 
-          m_txState = S_TX_LOCKED;
-          if (call IsBroadcastReady.getNow())
-            m_beaconFrame.header->mhr[MHR_INDEX_FC1] |= FC1_FRAME_PENDING;
-          else
-            m_beaconFrame.header->mhr[MHR_INDEX_FC1] &= ~FC1_FRAME_PENDING;
-          m_beaconFrame.header->mhr[MHR_INDEX_SEQNO] = m_bsn; // update beacon seqno
-          call Debug.log(LEVEL_INFO, StartP_PREPARE_TX, 0, m_lastBeaconTxTime, 0);
-          call BeaconTx.load(&m_beaconFrame); 
-          break;
-        case S_TX_LOCKED: 
-          call Debug.log(LEVEL_INFO, StartP_TRANSMIT, m_lastBeaconTxTime, m_dt, ((uint32_t)m_lastBeaconTxRefTime));
-          call BeaconTx.transmit(&m_lastBeaconTxRefTime, m_dt, 0, FALSE);
-          break;
-      }
-    }
+    signal MLME_START.confirm(SUCCESS);
   }
 
-  async event void BeaconTx.loadDone()
+  async event void BeaconSendAlarm.fired()
   {
-    atomic {
-      call Debug.log(LEVEL_INFO, StartP_PREPARE_TXDONE, 0, m_lastBeaconTxTime, 0);
-      if (m_txOneBeaconImmediately){
-        m_txOneBeaconImmediately = FALSE;
-        call BeaconTx.transmit(0, 0, 0, FALSE); // now!
-      } else 
-        call BeaconTxAlarm.startAt(m_lastBeaconTxTime, m_dt - IEEE154_RADIO_TX_SEND_DELAY);
+    // start/schedule beacon transmission
+    ieee154_timestamp_t *timestamp = &m_lastBeaconTxRefTime;
+    m_txState = S_TX_LOCKED;
+
+    if (call IsBroadcastReady.getNow())
+      m_beaconFrame.header->mhr[MHR_INDEX_FC1] |= FC1_FRAME_PENDING;
+    else
+      m_beaconFrame.header->mhr[MHR_INDEX_FC1] &= ~FC1_FRAME_PENDING;
+
+    if (m_txOneBeaconImmediately) {
+      m_txOneBeaconImmediately = FALSE;
+      timestamp = NULL;
     }
+    call BeaconTx.transmit(&m_beaconFrame, timestamp, m_dt);
+    dbg_serial("BeaconTransmitP","Beacon Tx scheduled for %lu.\n", (uint32_t) (*timestamp + m_dt));
   }
-    
-  async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool pendingFlag, error_t error)
+
+  async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result)
   {
-    // Coord CAP has just started...
+    // The beacon frame was transmitted, i.e. the CAP has just started
+    // update the state then pass the token on to the next component 
+
     uint8_t gtsFieldLength;
-    // Sec. 7.5.1.1: "start of slot 0 is defined as the point at which 
-    // the first symbol of the beacon PPDU is transmitted" 
-    call Debug.log(LEVEL_INFO, StartP_BEACON_TRANSMITTED, frame->metadata->timestamp, m_lastBeaconTxTime, m_dt);
-    m_lastBeaconTxTime = frame->metadata->timestamp;
-    memcpy(&m_lastBeaconTxRefTime, referenceTime, sizeof(ieee154_reftime_t));
-    m_numGtsSlots = (frame->payload[2] & 0x07);
+
+    ASSERT(result == SUCCESS); // must succeed, we're sending without CCA or ACK request
+    if (timestamp != NULL) {
+      m_lastBeaconTxTime = frame->metadata->timestamp;
+      memcpy(&m_lastBeaconTxRefTime, timestamp, sizeof(ieee154_timestamp_t));
+      m_dt = m_beaconInterval; // transmit the next beacon at m_lastBeaconTxTime + m_dt 
+      dbg_serial("BeaconTransmitP", "Beacon Tx success at %lu\n", (uint32_t) m_lastBeaconTxTime);
+    } else {
+      // Timestamp is invalid; this is bad. We need the beacon timestamp for the 
+      // slotted CSMA-CA, because it defines the slot reference time. We can't use this superframe
+      // TODO: check if this was the initial beacon (then m_lastBeaconTxRefTime is invalid)
+      dbg_serial("BeaconTransmitP", "Invalid timestamp!\n");
+      m_dt += m_beaconInterval;
+      call RadioToken.request();
+      call RadioToken.release();      
+      return;
+    }
+
+    // update superframe-related variables
+    m_numGtsSlots = 
+      (frame->payload[BEACON_INDEX_GTS_SPEC] & GTS_DESCRIPTOR_COUNT_MASK) >> GTS_DESCRIPTOR_COUNT_OFFSET;
     gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
-    m_finalCAPSlot = (frame->payload[1] & 0x0F);
-    m_sfSlotDuration = (((uint32_t) 1) << ((frame->payload[0] & 0xF0) >> 4)) * IEEE154_aBaseSlotDuration;
-    if (frame->header->mhr[0] & FC1_FRAME_PENDING)
+    m_numCapSlots = 
+      ((frame->payload[BEACON_INDEX_SF_SPEC2] & SF_SPEC2_FINAL_CAPSLOT_MASK) >> SF_SPEC2_FINAL_CAPSLOT_OFFSET) + 1;
+    m_sfSlotDuration = 
+      (((uint32_t) 1) << ((frame->payload[BEACON_INDEX_SF_SPEC1] & SF_SPEC1_SO_MASK) >> SF_SPEC1_SO_OFFSET)) * 
+      IEEE154_aBaseSlotDuration;
+
+    if (frame->header->mhr[MHR_INDEX_FC1] & FC1_FRAME_PENDING)
       m_framePendingBit = TRUE;
     else
       m_framePendingBit = FALSE;
-    memcpy(m_gtsField, &frame->payload[2], gtsFieldLength);
-    if (frame->payload[1] & 0x10){
-      // BLE is active; calculate the time offset from slot0
-      m_BLELen = IEEE154_SHR_DURATION + 
-        (frame->headerLen + frame->payloadLen) * IEEE154_SYMBOLS_PER_OCTET; 
-      if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
-        m_BLELen += IEEE154_MIN_LIFS_PERIOD;
+    memcpy(m_gtsField, &frame->payload[BEACON_INDEX_GTS_SPEC], gtsFieldLength);
+    if (frame->payload[BEACON_INDEX_SF_SPEC2] & SF_SPEC2_BATT_LIFE_EXT) {
+      // BLE is active; calculate the time offset from slot 0
+      m_battLifeExtDuration = IEEE154_SHR_DURATION + 
+        (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET; 
+      if (frame->headerLen + frame->payloadLen + 2 > IEEE154_aMaxSIFSFrameSize)
+        m_battLifeExtDuration += IEEE154_MIN_LIFS_PERIOD;
       else
-        m_BLELen += IEEE154_MIN_SIFS_PERIOD;
-      m_BLELen += m_battLifeExtPeriods;
+        m_battLifeExtDuration += IEEE154_MIN_SIFS_PERIOD;
+      m_battLifeExtDuration = m_battLifeExtDuration + m_battLifeExtPeriods * 20;
     } else
-      m_BLELen = 0;
-    call Token.request();             // register another request, before ...
-    call TokenToBroadcast.transfer(); // ... we let Broadcast module take over
+      m_battLifeExtDuration = 0;
+
+    // we pass on the token now, but make a reservation to get it back 
+    // to transmit the next beacon (at the start of the next superframe)
+    call RadioToken.request();  
+    call RadioToken.transferTo(RADIO_CLIENT_COORDBROADCAST); 
     post txDoneTask();
   }
 
   task void txDoneTask()
   {
-    call MLME_SET.macBSN(m_bsn++);
+    call MLME_SET.macBSN(m_beaconFrame.header->mhr[MHR_INDEX_SEQNO]);
+    m_beaconFrame.header->mhr[MHR_INDEX_SEQNO] += 1; // may be overwritten by the next higher layer
     call SetMacBeaconTxTime.set(m_lastBeaconTxTime); // start of slot0, ie. first preamble byte of beacon
     call BeaconPayloadUpdateTimer.startOneShotAt(m_lastBeaconTxTime, 
         (m_beaconInterval>BEACON_PAYLOAD_UPDATE_INTERVAL) ? (m_beaconInterval - BEACON_PAYLOAD_UPDATE_INTERVAL): 0);
-    if (m_requests & REQUEST_CONFIRM_PENDING){
-      m_requests &= ~REQUEST_CONFIRM_PENDING;
+    if (m_requestBitmap & REQUEST_CONFIRM_PENDING) {
+      m_requestBitmap &= ~REQUEST_CONFIRM_PENDING;
       signal MLME_START.confirm(IEEE154_SUCCESS);
     }
     m_txState = S_TX_IDLE;
     signal IEEE154TxBeaconPayload.beaconTransmitted();
-    call Debug.flush();
+    dbg_serial_flush();
   }
 
 
-/* ----------------------- Beacon Payload ----------------------- */
-/*
- * All access to the payload fields in the beacon happen
- * through a set of temporary variables/flags, and just before 
- * the frame is loaded into the radio these changes are 
* propagated into the actual payload portion of the beacon frame.
- */
+  /* ----------------------- Beacon Payload ----------------------- */
+  /*
  * All access to the payload fields in the beacon happen
  * through a set of temporary variables/flags, and just before 
  * the frame is loaded into the radio these changes are 
  * written into the actual payload portion of the beacon frame.
  */
 
   command error_t IEEE154TxBeaconPayload.setBeaconPayload(void *beaconPayload, uint8_t length)
   {
@@ -628,7 +655,7 @@ implementation
   uint8_t getNumGtsSlots(uint8_t *gtsInfoField)
   {
     uint8_t i, num=0;
-    for (i=0; i<(gtsInfoField[0] & GTS_DESCRIPTOR_COUNT_MASK); i++)
+    for (i=0; i<((gtsInfoField[0] & GTS_DESCRIPTOR_COUNT_MASK) >> GTS_DESCRIPTOR_COUNT_OFFSET); i++)
       num += ((gtsInfoField[4+i*3] & GTS_LENGTH_MASK) >> GTS_LENGTH_OFFSET);
     return num;
   }
@@ -638,56 +665,72 @@ implementation
     // in this order the MAC payload is updated:
     // (1) pending addresses
     // (2) GTS spec
-    // (3) sf spec
+    // (3) SF spec
     // (4) beacon payload (if there's enough time)
     uint8_t len=0, *beaconSpecs = &m_payload[IEEE154_aMaxBeaconOverhead]; // going backwards
-    uint8_t beaconPayloadUpdated = 0, numGtsSlots = 15 - m_finalCAPSlot;
+    uint8_t beaconPayloadUpdated = 0, numGtsSlots = m_numGtsSlots;
 
     atomic {
       if (m_txState == S_TX_LOCKED) 
       {
-        call Debug.log(LEVEL_INFO, StartP_BEACON_UPDATE, 0, 0, m_txState);
+        dbg_serial("BeaconTransmitP", "BeaconPayloadUpdateTimer fired too late!\n");
         return; // too late !
       }
-      if (m_payloadState & MODIFIED_PENDING_ADDR_FIELD){
+
+      // (1) update pending addresses
+      if (m_payloadState & MODIFIED_PENDING_ADDR_FIELD) {
         len = call PendingAddrWrite.getLength();
         beaconSpecs -= len;
         call PendingAddrWrite.write(beaconSpecs, len);
-        if (len != m_pendingAddrLen){
+        if (len != m_pendingAddrLen) {
           m_pendingAddrLen = len;
           m_payloadState |= MODIFIED_SPECS_MASK; // need to rewrite specs before
         }
       } else 
         beaconSpecs -= m_pendingAddrLen;
-      if (m_payloadState & MODIFIED_GTS_FIELD){
+      
+      // (2) update GTS spec
+      if (m_payloadState & MODIFIED_GTS_FIELD) {
         len = call GtsInfoWrite.getLength();
         beaconSpecs -= len;
         call GtsInfoWrite.write(beaconSpecs, len);
         numGtsSlots = getNumGtsSlots(beaconSpecs);
-        if (len != m_pendingGtsLen || ((15-numGtsSlots) != m_finalCAPSlot)){
+        if (len != m_pendingGtsLen || ((15-numGtsSlots) != m_numCapSlots-1)) {
           m_pendingGtsLen = len;
           m_payloadState |= MODIFIED_SPECS_MASK; // need to rewrite specs before
         }
       } else 
         beaconSpecs -= m_pendingGtsLen;
+
+      // (3) update SF spec
       beaconSpecs -= 2; // sizeof SF Spec
-      if (m_payloadState & MODIFIED_SF_SPEC){
-        call SuperframeSpecWrite.write(beaconSpecs, 2);
-        beaconSpecs[1] &= 0xF0; // clear FinalCAPSlot field
-        beaconSpecs[1] |= ((15-numGtsSlots) & 0x0F); // update FinalCAPSlot field
+      if (m_payloadState & MODIFIED_SF_SPEC) {
+        beaconSpecs[BEACON_INDEX_SF_SPEC1] = 
+          (m_beaconOrder << SF_SPEC1_BO_OFFSET) | (m_superframeOrder << SF_SPEC1_SO_OFFSET);
+        beaconSpecs[BEACON_INDEX_SF_SPEC2] = 0;
+        if (call MLME_GET.macAssociationPermit())
+          beaconSpecs[BEACON_INDEX_SF_SPEC2] |= SF_SPEC2_ASSOCIATION_PERMIT;        
+        if (call MLME_GET.macPanCoordinator())
+          beaconSpecs[BEACON_INDEX_SF_SPEC2] |= SF_SPEC2_PAN_COORD;
+        beaconSpecs[BEACON_INDEX_SF_SPEC2] |= 
+          ((15-numGtsSlots) & SF_SPEC2_FINAL_CAPSLOT_MASK);
       }
       m_beaconFrame.payloadLen = (m_pendingAddrLen + m_pendingGtsLen + 2) + m_beaconPayloadLen;
       m_beaconFrame.payload = beaconSpecs;
       m_payloadState &= ~MODIFIED_SPECS_MASK; // clear flags
-    } // end atomic (give BeaconTxAlarm.fired() the chance to execute)
+    } // end atomic (give BeaconSendAlarm.fired() the chance to execute)
+
     signal IEEE154TxBeaconPayload.aboutToTransmit();
+    m_beaconFrame.header->mhr[MHR_INDEX_SEQNO] = call MLME_GET.macBSN() + 1;
+
     atomic {
+      // (4) try to update beacon payload 
       if (m_txState == S_TX_LOCKED) 
       {
-        call Debug.log(LEVEL_INFO, StartP_BEACON_UPDATE_2, 0, 0, m_txState);
+        dbg_serial("BeaconTransmitP", "Not enough time for beacon payload update!\n");
         return; // too late !
       }
-      if (m_payloadState & MODIFIED_BEACON_PAYLOAD){
+      if (m_payloadState & MODIFIED_BEACON_PAYLOAD) {
         memcpy(&m_payload[IEEE154_aMaxBeaconOverhead + m_updateBeaconOffset], 
             m_updateBeaconPayload, m_updateBeaconLength);
         beaconPayloadUpdated = (m_payloadState & MODIFIED_BEACON_PAYLOAD_MASK);
@@ -697,7 +740,7 @@ implementation
       m_beaconFrame.payloadLen = (m_pendingAddrLen + m_pendingGtsLen + 2) + m_beaconPayloadLen;
       m_payloadState &= ~MODIFIED_BEACON_PAYLOAD_MASK;
     }
-    if (beaconPayloadUpdated){
+    if (beaconPayloadUpdated) {
       if ((beaconPayloadUpdated & MODIFIED_BEACON_PAYLOAD_NEW))
         signal IEEE154TxBeaconPayload.setBeaconPayloadDone(m_updateBeaconPayload, m_updateBeaconLength);
       else
@@ -706,32 +749,12 @@ implementation
     }
   }
 
-/* -----------------------  SuperframeSpec ----------------------- */
-
-  command uint8_t SuperframeSpecWrite.write(uint8_t *superframeSpecField, uint8_t maxlen)
-  {
-    if (call SuperframeSpecWrite.getLength() > maxlen)
-      return 0;
-    superframeSpecField[0] = m_beaconOrder | (m_superframeOrder << 4);
-    superframeSpecField[1] = m_finalCAPSlot;
-    if (m_PANCoordinator)
-      superframeSpecField[1] |= SF_SPEC2_PAN_COORD;
-    if (call MLME_GET.macAssociationPermit())
-      superframeSpecField[1] |= SF_SPEC2_ASSOCIATION_PERMIT;
-    return 2;
-  }
-
-  command uint8_t SuperframeSpecWrite.getLength()
-  {
-    return 2;
-  }
-
-/* ----------------------- Realignment ----------------------- */
-/* In beacon-enabled mode a realignment frame was broadcast in the CAP
- * immediately after the beacon was transmitted.  In non-beacon-enabled mode a
- * realignment frame was sent using unslotted CSMA. In both cases, if the
- * transmission was successful, the superframe spec must be updated now.
- **/
+  /* ----------------------- Realignment ----------------------- */
+  /* In beaconenabled mode a realignment frame is broadcast in the CAP
+   * immediately after the beacon was transmitted.  In non-beaconenabled mode a
+   * realignment frame is sent using unslotted CSMA. In both cases, if the
+   * transmission was successful, the superframe spec should be updated now.
+   **/
 
   event void RealignmentBeaconEnabledTx.transmitDone(ieee154_txframe_t *frame, ieee154_status_t status)
   {
@@ -746,71 +769,83 @@ implementation
   void finishRealignment(ieee154_txframe_t *frame, ieee154_status_t status)
   {
     call GetSetRealignmentFrame.set(frame);
-    if (status == IEEE154_SUCCESS){
+    if (status == IEEE154_SUCCESS) {
       continueStartRequest();
-      m_requests &= ~REQUEST_REALIGNMENT_DONE_PENDING; // unlock
+      m_requestBitmap &= ~REQUEST_REALIGNMENT_DONE_PENDING; // unlock
       // signal confirm where we calculate the next beacon transmission time
     } else {
-      m_requests = 0;
+      m_requestBitmap = 0;
       signal MLME_START.confirm(status);
     }
   }
 
-/* ----------------------- BeaconRequest ----------------------- */
+  /* ----------------------- BeaconRequest ----------------------- */
 
   event message_t* BeaconRequestRx.received(message_t* frame)
   {
-    if (!call IsSendingBeacons.get()){
+    if (m_beaconOrder == 15) {
       // transmit the beacon frame using unslotted CSMA-CA
       // TODO
     }
     return frame;
   }
 
-/* -----------------------  Defaults, etc. ----------------------- */
+  /* -----------------------  SF Structure, etc. ----------------------- */
 
-  task void signalStartConfirmSuccessTask()
-  {
-    signal MLME_START.confirm(SUCCESS);
+  async command uint32_t OutgoingSF.sfStartTime()
+  { 
+    return m_lastBeaconTxTime; 
   }
 
-  command bool IsSendingBeacons.get(){ return m_beaconOrder < 15;}
+  async command uint16_t OutgoingSF.sfSlotDuration()
+  { 
+    return m_sfSlotDuration;
+  }
 
-  async command uint32_t BeaconInterval.getNow() { return m_beaconInterval; }
-  async command uint32_t CapStart.getNow() { return m_lastBeaconTxTime; }
-  async command ieee154_reftime_t* CapStartRefTime.getNow() { return &m_lastBeaconTxRefTime; }
-  async command uint32_t CapLen.getNow() { return call SfSlotDuration.getNow() * (call FinalCapSlot.getNow() + 1);}
-  async command uint32_t CapEnd.getNow() 
+  async command uint8_t OutgoingSF.numCapSlots()
   {
-    return call CapStart.getNow() + call CapLen.getNow();
+    return m_numCapSlots;
   }
-  async command uint32_t CfpEnd.getNow() 
+
+  async command uint8_t OutgoingSF.numGtsSlots()
   {
-    return call CapStart.getNow() + call SfSlotDuration.getNow() * IEEE154_aNumSuperframeSlots;
+    return m_numGtsSlots;
   }
-  async command uint32_t CfpLen.getNow()
+
+  async command uint16_t OutgoingSF.battLifeExtDuration()
   {
-    return call SfSlotDuration.getNow() * (15 - call FinalCapSlot.getNow());
+    return m_battLifeExtDuration;
   }
-  async command bool IsBLEActive.getNow(){ return m_BLELen>0;}
-  async command uint16_t BLELen.getNow(){ return m_BLELen;}
-  async command bool BeaconFramePendingBit.getNow(){ return m_framePendingBit;}
 
-  async command uint8_t* GtsField.getNow() { return m_gtsField; }
-  async command uint32_t SfSlotDuration.getNow() { return m_sfSlotDuration; }
-  async command uint8_t FinalCapSlot.getNow() { return m_finalCAPSlot; }
-  async command uint8_t NumGtsSlots.getNow() { return m_numGtsSlots; }
+  async command const uint8_t* OutgoingSF.gtsFields()
+  {
+    return m_gtsField;
+  }
 
-  default event void MLME_START.confirm    (
-                          ieee154_status_t status
-                        ){}
+  async command uint16_t OutgoingSF.guardTime()
+  {
+    return IEEE154_MAX_BEACON_JITTER(m_beaconOrder) + IEEE154_RADIO_TX_DELAY;
+  }
 
-  default event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length){}
+  async command const ieee154_timestamp_t* OutgoingSF.sfStartTimeRef()
+  {
+    return &m_lastBeaconTxRefTime;
+  }
 
-  default event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength){}
+  async command bool OutgoingSF.isBroadcastPending()
+  {
+    return m_framePendingBit;
+  }
 
-  default event void IEEE154TxBeaconPayload.aboutToTransmit(){}
+  async command bool IsSendingBeacons.getNow()
+  { 
+    return (m_beaconOrder < 15) || ((m_requestBitmap & REQUEST_CONFIRM_PENDING) && m_updateBeaconOrder < 15);
+  }
 
-  default event void IEEE154TxBeaconPayload.beaconTransmitted(){}
+  default event void MLME_START.confirm(ieee154_status_t status) {}
+  default event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length) {}
+  default event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength) {}
+  default event void IEEE154TxBeaconPayload.aboutToTransmit() {}
+  default event void IEEE154TxBeaconPayload.beaconTransmitted() {}
 
 }