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

📄 dispatchunslottedcsmap.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 2 页
字号:

      // 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
          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 
          next = SWITCH_OFF;
      }

      // Check 3: is there a frame ready to transmit?
      else if (m_currentFrame != NULL) {
        next = tryTransmit();
      }

      // Check 4: should we be in receive mode?
      else if (call IsRxEnableActive.getNow() || m_macRxOnWhenIdle) {
        next = tryReceive();
        if (next == DO_NOTHING) {
          // 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 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 RadioToken.release();
          return;
        }
      }

      // if there is nothing to do, then we must clear the lock
      if (next == DO_NOTHING)
        m_lock = FALSE;
    } // atomic

    // put next state in operation (possibly keeping the lock)
    switch (next)
    {
      case SWITCH_OFF: ASSERT(call RadioOff.off() == SUCCESS); break;
      case WAIT_FOR_RXDONE: break;
      case WAIT_FOR_TXDONE: break;
      case DO_NOTHING: break;
    }
  }
  
  next_state_t tryTransmit()
  {
    // tries to transmit m_currentFrame
    next_state_t next;

    if (!call RadioOff.isOff())
      next = SWITCH_OFF;
    else {
      error_t res;
      res = call UnslottedCsmaCa.transmit(m_currentFrame, &m_csma);
      dbg("DispatchUnslottedCsmaP", "UnslottedCsmaCa.transmit() -> %lu\n", (uint32_t) res);
      next = WAIT_FOR_TXDONE; // this will NOT clear the lock
    }
    return next;
  }

  next_state_t tryReceive()
  {
    next_state_t next;
    if (call RadioRx.isReceiving())
      next = DO_NOTHING;
    else if (!call RadioOff.isOff())
      next = SWITCH_OFF;
    else {
      call RadioRx.enableRx(0, 0);
      next = WAIT_FOR_RXDONE;
    }
    return next;
  }

  next_state_t trySwitchOff()
  {
    next_state_t next;
    if (call RadioOff.isOff())
      next = DO_NOTHING;
    else
      next = SWITCH_OFF;
    return next;
  }

  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 {
      if (m_indirectTxPending) {
        m_indirectTxPending = FALSE; 
        post signalTxDoneTask(); 
      }
    }
  }

  task void startIndirectTxTimerTask()
  {
    call IndirectTxWaitTimer.startOneShot(call MLME_GET.macMaxFrameTotalWaitTime()); 
  }

  async event void UnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame, 
      ieee154_csma_t *csma, bool ackPendingFlag, error_t result)
  {
    bool done = TRUE;
    dbg("DispatchUnslottedCsmaP", "UnslottedCsmaCa.transmitDone() -> %lu\n", (uint32_t) result);
    m_resume = FALSE;

    switch (result)
    {
      case SUCCESS:
        // frame was successfully transmitted, if ACK was requested
        // then a matching ACK was successfully received as well   
        m_txStatus = IEEE154_SUCCESS;
        if (frame->payload[0] == CMD_FRAME_DATA_REQUEST &&
            ((frame->header->mhr[MHR_INDEX_FC1]) & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD) {
          // this was a data request frame
          m_txStatus = IEEE154_NO_DATA; // pessimistic 
          if (ackPendingFlag) {
            // the coordinator has data for us; switch to Rx 
            // to complete the indirect transmission         
            m_indirectTxPending = TRUE;
            m_lastFrame = m_currentFrame;
            m_currentFrame = NULL;
            ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS);
            return;
          }
        }
        break;
      case FAIL:
        // The CSMA-CA algorithm failed: the frame was not transmitted,
        // because channel was never idle                              
        m_txStatus = IEEE154_CHANNEL_ACCESS_FAILURE;
        break;
      case ENOACK:
        // frame was transmitted, but we didn't receive an ACK (although
        // we requested an one). note: coordinator never retransmits an 
        // indirect transmission (see above) 
        if (m_macMaxFrameRetries > 0) {
          // retransmit: reinitialize CSMA-CA parameters
          done = FALSE;
          m_csma.NB = 0;
          m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs;
          m_csma.macMaxBE = m_macMaxBE;
          m_csma.BE = m_BE;
          m_macMaxFrameRetries -= 1;
        } else
          m_txStatus = IEEE154_NO_ACK;
        break;
      default: 
        ASSERT(0);
        break;
    }

    if (done) {
      m_lastFrame = m_currentFrame;
      m_currentFrame = NULL;
      post signalTxDoneTask();
    }  

    m_lock = FALSE;
    updateState();
  }

  task void signalTxDoneTask()
  {
    ieee154_txframe_t *lastFrame = m_lastFrame;
    ieee154_status_t status = m_txStatus;
    m_indirectTxPending = FALSE;
    m_lastFrame = NULL; // only now the next transmission can begin 
    if (lastFrame) {
      dbg("DispatchUnslottedCsmaP", "Transmit done, DSN: %lu, result: 0x%lx\n", 
          (uint32_t) MHR(lastFrame)[MHR_INDEX_SEQNO], (uint32_t) status);
      signal FrameTx.transmitDone(lastFrame, status);
    }
    updateState();
  }

  event message_t* RadioRx.received(message_t* frame, const ieee154_timestamp_t *timestamp)
  {
    // received a frame -> find out frame type and
    // signal it to responsible client component
    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;
        call IndirectTxWaitTimer.stop();
        // TODO: check!
        //if (frame->payloadLen)
          // is this frame from our coordinator? hmm... we cannot say
          // with certainty, because we might only know either the 
          // coordinator extended or short address (and the frame could
          // have been sent with the other addressing mode) ??
          m_txStatus = IEEE154_SUCCESS;
        frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame);
        signal IndirectTxWaitTimer.fired();
        return frameBuf;
      } else
        return signal FrameRx.received[frameType](frame);
    }
  }

  task void wasRxEnabledTask()
  {
    signal WasRxEnabled.notify(TRUE);
  }


  default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status) {}
  default event message_t* FrameRx.received[uint8_t client](message_t* data) {return data;}
  default async command bool IsRxEnableActive.getNow() {return FALSE;}

  default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame) {return msg;}

  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(); }
}

⌨️ 快捷键说明

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