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

📄 dispatchslottedcsmap.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 2 页
字号:
      else if (DEVICE_ROLE && m_broadcastRxPending) {
        // receive a broadcast from coordinator
        dbg_push_state(2);
        next = tryReceive();
      } else if (COORD_ROLE && m_bcastFrame) {
        dbg_push_state(2);
        next = tryTransmit();
      }

      // Check 3: was an indirect transmission successfully started 
      // and are we now waiting for a frame from the coordinator?
      else if (DEVICE_ROLE && m_indirectTxPending) {
        dbg_push_state(3);
        next = tryReceive();
      }

      // Check 4: is some other operation (like MLME-SCAN or MLME-RESET) pending? 
      else if (call IsRadioTokenRequested.getNow()) {
        dbg_push_state(4);
        if (call RadioOff.isOff()) {
          stopAllAlarms();  // may still fire, but is locked through isOwner()
          // nothing more to do... just release the Token
          m_lock = FALSE; // unlock
          dbg_serial("DispatchSlottedCsmaP", "Token requested: Handing over to CFP.\n");
          call RadioToken.release();
          return;
        } else 
          next = SWITCH_OFF;
      }

      // Check 5: is battery life extension (BLE) active and 
      // has the BLE period expired?
      else if (call SuperframeStructure.battLifeExtDuration() > 0 &&
          call TimeCalc.hasExpired(call SuperframeStructure.sfStartTime(), 
            call SuperframeStructure.battLifeExtDuration()) &&
          !call IsRxEnableActive.getNow() && !macRxOnWhenIdle) {
        dbg_push_state(5);
        next = trySwitchOff();
      }

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

      // Check 7: should we be in receive mode?
      else if (COORD_ROLE || call IsRxEnableActive.getNow() || macRxOnWhenIdle) {
        dbg_push_state(7);
        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 8: just make sure the radio is switched off  
      else {
        dbg_push_state(8);
        next = trySwitchOff();
      }

      // 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
    uint32_t capDuration = (uint32_t) call SuperframeStructure.numCapSlots() * 
      (uint32_t) call SuperframeStructure.sfSlotDuration();
    next_state_t next;

    if (!call RadioOff.isOff())
      next = SWITCH_OFF;
    else {
      uint32_t dtMax = capDuration - call SuperframeStructure.guardTime() - m_transactionTime;
      // round to backoff boundary
      dtMax = dtMax + (IEEE154_aUnitBackoffPeriod - (dtMax % IEEE154_aUnitBackoffPeriod));
      if (dtMax > capDuration)
        dtMax = 0;
      if (call SuperframeStructure.battLifeExtDuration() > 0) {
        // battery life extension
        uint16_t bleLen = call SuperframeStructure.battLifeExtDuration();
        if (bleLen < dtMax)
          dtMax = bleLen;
      }
      if (call TimeCalc.hasExpired(call SuperframeStructure.sfStartTime(), dtMax))
        next = DO_NOTHING; // frame doesn't fit in the remaining CAP
      else {
        error_t res;
        res = call SlottedCsmaCa.transmit(m_currentFrame, &m_csma, 
                   call SuperframeStructure.sfStartTimeRef(), dtMax, m_resume, m_remainingBackoff);
        dbg("DispatchSlottedCsmaP", "SlottedCsmaCa.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 (DEVICE_ROLE && (m_indirectTxPending || m_broadcastRxPending))
      call RxWaitAlarm.start(m_macMaxFrameTotalWaitTime);
    m_lock = FALSE; 
    updateState();
  }

  async event void CapEndAlarm.fired() { 
    dbg_serial("DispatchSlottedCsmaP", "CapEndAlarm.fired()\n");
    updateState();
  }
  async event void BLEAlarm.fired() { updateState();}
  event void RxEnableStateChange.notify(bool whatever) { updateState();}
  event void PIBUpdateMacRxOnWhenIdle.notify( const void* val ) {
    atomic macRxOnWhenIdle = *((ieee154_macRxOnWhenIdle_t*) val);
    updateState();
  }

  async event void RxWaitAlarm.fired() 
  { 
    if (DEVICE_ROLE && (m_indirectTxPending || m_broadcastRxPending))
      atomic {
        if (m_indirectTxPending) {
          m_indirectTxPending = FALSE; 
          post signalTxDoneTask(); 
        } else if (m_broadcastRxPending) {
          m_broadcastRxPending = FALSE;
          updateState();
        }
      }
  }

  async event void SlottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma, 
      bool ackPendingFlag,  uint16_t remainingBackoff, error_t result)
  {
    bool done = TRUE;
    dbg("DispatchSlottedCsmaP", "SlottedCsmaCa.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 (DEVICE_ROLE && 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;
      case EINVAL: // DEBUG!!!
        dbg_serial("DispatchSlottedCsmaP", "EINVAL returned by transmitDone()!\n");
        // fall through
      case ERETRY:
        // frame was not transmitted, because the transaction does not
        // fit in the remaining CAP (in beacon-enabled PANs only)
        dbg_serial("DispatchSlottedCsmaP", "Transaction didn't fit, current BE: %lu\n", (uint32_t) csma->BE);
        m_resume = TRUE;
        m_remainingBackoff = remainingBackoff;
        done = FALSE;
        m_lock = FALSE; // debug! problem: if CAP endalarm has fired it's a deadlock!
        if (!call CapEndAlarm.isRunning())
          updateState();
        return;
        break;
      default: 
        ASSERT(0);
        break;
    }

    if (COORD_ROLE && frame == m_bcastFrame) {
      // always signal result of broadcast transmissions immediately 
      restoreFrameFromBackup();
      signalTxBroadcastDone(m_bcastFrame, (!done) ? IEEE154_CHANNEL_ACCESS_FAILURE : m_txStatus);
      m_bcastFrame = NULL;
    } else 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 can the next transmission can begin 
    if (lastFrame) {
      dbg("DispatchSlottedCsmaP", "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("DispatchSlottedCsmaP", "Received frame, DSN: %lu, type: 0x%lu\n", 
        (uint32_t) mhr[MHR_INDEX_SEQNO], (uint32_t) frameType);
    atomic {
      if (DEVICE_ROLE && (m_indirectTxPending || m_broadcastRxPending)) {
        message_t* frameBuf;
        call RxWaitAlarm.stop();
        // TODO: check the following: 
        // 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;
        if (m_indirectTxPending)
          frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame); // indirect tx from coord
        else
          frameBuf = signal FrameRx.received[frameType](frame); // broadcast from coordinator
        signal RxWaitAlarm.fired();
        return frameBuf;
      } else
        return signal FrameRx.received[frameType](frame);
    }
  }

  void backupCurrentFrame()
  {
    ieee154_cap_frame_backup_t backup = {m_currentFrame, m_csma, m_transactionTime};
    call FrameBackup.setNow(&backup);
  }

  void restoreFrameFromBackup()
  {
    ieee154_cap_frame_backup_t *backup = call FrameRestore.getNow();
    if (backup != NULL) {
      m_currentFrame = backup->frame;
      memcpy(&m_csma, &backup->csma, sizeof(ieee154_csma_t));
      m_transactionTime = backup->transactionTime;
    }
  }

  async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame) 
  {
    // if this command is called then it is (MUST be) called only just before
    // the token is transferred to this component and it is then called
    // only once per CAP (max. one broadcast is allowed after a beacon
    // transmission)
    atomic {
      if (!call RadioToken.isOwner() && m_bcastFrame == NULL) {
        m_bcastFrame = frame;
        return IEEE154_SUCCESS;
      } else {
        ASSERT(0);
        return IEEE154_TRANSACTION_OVERFLOW;
      }
    }
  }

  void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error)
  {
    signal BroadcastTx.transmitNowDone(frame, error);
  }

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

  event void RadioToken.granted()
  {
    ASSERT(0); // should never happen
  }

  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 async command void RxWaitAlarm.start(uint32_t dt) {ASSERT(0);}
  default async command void RxWaitAlarm.stop() {ASSERT(0);}
  default async command void RxWaitAlarm.startAt(uint32_t t0, uint32_t dt) {ASSERT(0);}
  
  default async command bool SuperframeStructure.isBroadcastPending() { return FALSE;}
  default async event void BroadcastTx.transmitNowDone(ieee154_txframe_t *frame, ieee154_status_t status) {}
  default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame) {return msg;}
  default async command error_t FrameBackup.setNow(ieee154_cap_frame_backup_t* val) {return FAIL;}
  default async command ieee154_cap_frame_backup_t* FrameRestore.getNow() {return NULL;}
  default command error_t TrackSingleBeacon.start() {return FAIL;}

  command error_t WasRxEnabled.enable() {return FAIL;}
  command error_t WasRxEnabled.disable() {return FAIL;}
  async event void RadioTokenRequested.requested(){ updateState(); }
  async event void RadioTokenRequested.immediateRequested(){ updateState(); }
}

⌨️ 快捷键说明

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