⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispatchunslottedcsmap.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2008, Technische Universitaet Berlin
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright 
 *   notice, this list of conditions and the following disclaimer in the 
 *   documentation and/or other materials provided with the distribution.
 * - Neither the name of the Technische Universitaet Berlin nor the names 
 *   of its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * - Revision -------------------------------------------------------------
 * $Revision: 1.10 $
 * $Date: 2009/05/18 12:54:10 $
 * @author Jan Hauer <hauer@tkn.tu-berlin.de>
 * ========================================================================
 */

#include "TKN154_PHY.h"
#include "TKN154_MAC.h"

/** 
 * This module is responsible for the transmission/reception of DATA and
 * COMMAND frames in a nonbeacon-enabled PAN. Its main tasks are initialization
 * of the parameters of the unslotted CSMA-CA algorithm (NB, BE, etc.),
 * initiating retransmissions and managing requests for enabling the receiver
 * for a finite period of time. It does not implement the actual CSMA-CA
 * algorithm, because due to its timing requirements the CSMA-CA algorithm is
 * not part of the MAC implementation but of the chip-specific radio driver.
 */

module DispatchUnslottedCsmaP
{
  provides
  {
    interface Init as Reset;
    interface MLME_START;
    interface FrameTx as FrameTx;
    interface FrameRx as FrameRx[uint8_t frameType];
    interface FrameExtracted as FrameExtracted[uint8_t frameType];
    interface Notify<bool> as WasRxEnabled;
  }
  uses
  {
    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;
    interface RadioOff;
    interface MLME_GET;
    interface MLME_SET;
    interface TimeCalc;
    interface Leds;
  }
}
implementation
{
  typedef enum {
    SWITCH_OFF,       
    WAIT_FOR_RXDONE,  
    WAIT_FOR_TXDONE,  
    DO_NOTHING,       
  } next_state_t; 

  typedef enum {
    INDIRECT_TX_ALARM,
    NO_ALARM,
  } rx_alarm_t;

  /* state / frame management */
  norace bool m_lock;
  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;
  norace ieee154_macMaxBE_t m_BE;
  norace ieee154_macMaxCSMABackoffs_t m_macMaxCSMABackoffs;
  norace ieee154_macMaxBE_t m_macMaxBE;
  norace ieee154_macMaxFrameRetries_t m_macMaxFrameRetries;
  norace ieee154_status_t m_txStatus;
  norace uint32_t m_transactionTime;
  norace bool m_indirectTxPending = FALSE;

  /* function / task prototypes */
  next_state_t tryReceive();
  next_state_t tryTransmit();
  next_state_t trySwitchOff();
  void backupCurrentFrame();
  void restoreFrameFromBackup();  
  void updateState();
  void setCurrentFrame(ieee154_txframe_t *frame);
  void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error);
  task void signalTxDoneTask();
  task void wasRxEnabledTask();
  task void startIndirectTxTimerTask();
  task void signalStartConfirmTask();

  command error_t Reset.init()
  {
    if (m_currentFrame)
      signal FrameTx.transmitDone(m_currentFrame, IEEE154_TRANSACTION_OVERFLOW);
    if (m_lastFrame)
      signal FrameTx.transmitDone(m_lastFrame, IEEE154_TRANSACTION_OVERFLOW);
    m_currentFrame = m_lastFrame = NULL;
    call IndirectTxWaitTimer.stop();
    return SUCCESS;
  }

  command ieee154_status_t MLME_START.request  (
                          uint16_t panID,
                          uint8_t logicalChannel,
                          uint8_t channelPage,
                          uint32_t startTime,
                          uint8_t beaconOrder,
                          uint8_t superframeOrder,
                          bool panCoordinator,
                          bool batteryLifeExtension,
                          bool coordRealignment,
                          ieee154_security_t *coordRealignSecurity,
                          ieee154_security_t *beaconSecurity)
  {
    ieee154_status_t status;
    ieee154_macShortAddress_t shortAddress = call MLME_GET.macShortAddress();

    // check parameters
    if ((coordRealignSecurity && coordRealignSecurity->SecurityLevel) ||
        (beaconSecurity && beaconSecurity->SecurityLevel))
      status = IEEE154_UNSUPPORTED_SECURITY;
    else if (shortAddress == 0xFFFF) 
      status = IEEE154_NO_SHORT_ADDRESS;
    else if (logicalChannel > 26 ||
        (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) ||
        !(IEEE154_SUPPORTED_CHANNELS & ((uint32_t) 1 << logicalChannel)))
      status =  IEEE154_INVALID_PARAMETER;
    else if (beaconOrder != 15) 
      status = IEEE154_INVALID_PARAMETER;
    else {
      call MLME_SET.macPANId(panID);
      call MLME_SET.phyCurrentChannel(logicalChannel);
      call MLME_SET.macBeaconOrder(beaconOrder);
      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;
  }

  task void signalStartConfirmTask()
  {
    signal MLME_START.confirm(IEEE154_SUCCESS);
  }

  command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
  {
    if (m_currentFrame != NULL) {
      // we've not finished transmitting the current frame yet
      dbg_serial("DispatchUnslottedCsmaP", "Overflow\n");
      return IEEE154_TRANSACTION_OVERFLOW;
    } else {
      setCurrentFrame(frame);
      if (call RadioToken.isOwner())
        updateState();
      else
        call RadioToken.request();      
      return IEEE154_SUCCESS;
    }
  }

  event void RadioToken.granted()
  {
    updateState();
  }

  void setCurrentFrame(ieee154_txframe_t *frame)
  {
    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();
    m_csma.BE = call MLME_GET.macMinBE();
    if (call MLME_GET.macBattLifeExt() && m_csma.BE > 2)
      m_csma.BE = 2;
    m_BE = m_csma.BE;
    if (call GetIndirectTxFrame.get() == frame)
      m_macMaxFrameRetries =  0; // this is an indirect transmissions (never retransmit)
    else
      m_macMaxFrameRetries =  call MLME_GET.macMaxFrameRetries();
    m_transactionTime = IEEE154_SHR_DURATION + 
      (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET; // extra 2 for CRC
    if (frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST)
      m_transactionTime += (IEEE154_aTurnaroundTime + IEEE154_aUnitBackoffPeriod + 
          11 * IEEE154_SYMBOLS_PER_OCTET); // 11 byte for the ACK PPDU
    // if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize) 
    //  m_transactionTime += call MLME_GET.macMinLIFSPeriod(); 
    // else 
    //  m_transactionTime += call MLME_GET.macMinSIFSPeriod(); 
    m_currentFrame = frame;
  }

  /** 
   * The updateState() function is called whenever some event happened that
   * might require a state transition; it implements a lock mechanism (m_lock)
   * to prevent race conditions. Whenever the lock is set a "done"-event (from
   * a RadioTx/RadioRx/RadioOff interface) is pending and will "soon" unset the
   * lock (and then updateState() will called again).  The updateState()
   * function decides about the next state by checking a list of possible
   * current states ordered by priority. Calling this function more than
   * necessary can do no harm.
   */ 

  void updateState()
  {
    next_state_t next;
    atomic {
      // 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 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();
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -