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

📄 scanp.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 2 页
字号:
        for (i=0; i<4; i++) // broadcast dest PAN ID + broadcast dest addr
          m_txFrame->header->mhr[MHR_INDEX_ADDRESS + i] = 0xFF;
        call FrameUtility.copyLocalExtendedAddressLE((uint8_t*) &(m_txFrame->header->mhr[MHR_INDEX_ADDRESS + i]));
        m_txFrame->headerLen = 15;
        m_payload[0] = CMD_FRAME_ORPHAN_NOTIFICATION;
        m_txFrame->payloadLen = 1;
        break;
    }
    nextIteration();
  }

  void nextIteration()
  {
    ieee154_phyChannelsSupported_t supportedChannels = call MLME_GET.phyChannelsSupported();
    uint32_t currentChannelBit = (uint32_t) 1 << m_currentChannelNum;
    error_t radioStatus = SUCCESS;

    if (!m_terminateScan){
      while (m_currentChannelNum <= LAST_CHANNEL &&  
          !(m_scanChannels & currentChannelBit & supportedChannels)){
        m_currentChannelNum++;
        currentChannelBit <<= 1;
      }
    }

    if (m_currentChannelNum <= LAST_CHANNEL && !m_terminateScan) {
      // scan the next channel
      call MLME_SET.phyCurrentChannel(m_currentChannelNum);
      dbg_serial("ScanP", "Scanning channel %lu...\n", (uint32_t) m_currentChannelNum);
      switch (m_scanType) {
        case PASSIVE_SCAN:
          radioStatus = call RadioRx.enableRx(0, 0);
          break;
        case ACTIVE_SCAN: // fall through
        case ORPHAN_SCAN:
          radioStatus = call RadioTx.transmit(m_txFrame, NULL, 0);
          break;
        case ENERGY_DETECTION_SCAN:
          radioStatus = call EnergyDetection.start(m_scanDuration);
          break;
      }
      ASSERT(radioStatus == SUCCESS);
    } else {
      // we're done
      ieee154_status_t result = IEEE154_SUCCESS;
      uint32_t unscannedChannels = 0;

      if (m_terminateScan){
        // Scan operation terminated because the max. 
        // number of PAN descriptors/ED samples was reached.
        // Check if there are channels that were unscanned.
        // In active/passive scan we consider a channel 
        // unscanned if it was not completely scanned.
        if (m_scanType == PASSIVE_SCAN || m_scanType == ACTIVE_SCAN) 
          currentChannelBit >>= 1; // last (partially) scanned channel
        while (!(currentChannelBit & INVALID_CHANNEL_BITMASK) &&
               (m_scanChannels & currentChannelBit)){
          unscannedChannels |= currentChannelBit;
          currentChannelBit <<= 1;
        }
        if (unscannedChannels) // some channels were not (completely) scanned
          result = IEEE154_LIMIT_REACHED;
      } else if (m_scanType != ENERGY_DETECTION_SCAN && !m_resultIndex)
        result = IEEE154_NO_BEACON;

      if (m_scanType == PASSIVE_SCAN || m_scanType == ACTIVE_SCAN) 
        call MLME_SET.macPANId(m_PANID);
      if (m_txFrame != NULL) {
        call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) m_txFrame->header - offsetof(ieee154_txcontrol_t, header)));
        call TxFramePool.put(m_txFrame);
      }
      m_txFrame = NULL;
      if (call RadioToken.isOwner())
        call RadioToken.release();
      m_busy = FALSE;
      dbg_serial("ScanP", "MLME_SCAN.confirm()\n");
      signal MLME_SCAN.confirm (
          result,
          m_scanType,
          IEEE154_SUPPORTED_CHANNELPAGE,
          unscannedChannels,
          (m_scanType == ENERGY_DETECTION_SCAN) ? m_resultIndex : 0,
          (m_scanType == ENERGY_DETECTION_SCAN) ? (int8_t*) m_resultList : NULL,
          ((m_scanType == ACTIVE_SCAN ||
           m_scanType == PASSIVE_SCAN) && call MLME_GET.macAutoRequest()) ? m_resultIndex : 0,
          ((m_scanType == ACTIVE_SCAN ||
           m_scanType == PASSIVE_SCAN) && call MLME_GET.macAutoRequest()) ? (ieee154_PANDescriptor_t*) m_resultList : NULL);
    }
    dbg_serial_flush();
  }
  
  async event void RadioRx.enableRxDone()
  {
    post startTimerTask();
  }

  /* ----------------------- EnergyDetection ----------------------- */

  event void EnergyDetection.done(error_t status, int8_t EnergyLevel)
  {
    if (status == SUCCESS && m_resultListNumEntries)
      ((uint8_t*) m_resultList)[m_resultIndex++] = EnergyLevel;
    if (m_resultIndex == m_resultListNumEntries)
      m_terminateScan = TRUE; // done
    if (call RadioOff.off() == EALREADY)
      signal RadioOff.offDone();
  }

  /* ----------------------- Active/Orphan scan ----------------------- */
  
  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result)
  {
    ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS);
  }

  /* -------- Receive events (for  Active/Passive/Orphan scan) -------- */

  event message_t* RadioRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
  {
    if (!m_busy)
      return frame;

    if (m_scanType == ORPHAN_SCAN) {
      uint8_t *payload = call Frame.getPayload(frame);
      if (!m_resultIndex)
        if ((MHR(frame)[0] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD &&
            payload[0] == CMD_FRAME_COORDINATOR_REALIGNMENT) {

          // Sect. 7.5.4.3: "the device shall update its MAC PIB with the PAN  
          // information contained in the coordinator realignment command"
           
          call MLME_SET.macPANId( *((nxle_uint16_t*) &payload[1]) );
          call MLME_SET.macCoordShortAddress( *((nxle_uint16_t*) &payload[3]) );
          call MLME_SET.phyCurrentChannel( *((nxle_uint16_t*) &payload[5]) );
          call MLME_SET.macShortAddress( *((nxle_uint16_t*) &payload[6]) );
          m_resultIndex++; 
          dbg_serial("ScanP", "Received coordinator realignment frame.\n");
          m_terminateScan = TRUE;
          call RadioOff.off();
        }
    } else if ((((ieee154_header_t*) frame->header)->mhr[0] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_BEACON) {

      // PASSIVE_SCAN / ACTIVE_SCAN:
      // A beacon frame containing a non-empty payload is always signalled
      // to the next higher layer (regardless of the value of macAutoRequest);
      // when macAutoRequest is set to TRUE, then the beacon is always 
      // stored in the PAN Descriptor list (see 7.1.11.2.1 - Table 68)

      if (!call MLME_GET.macAutoRequest())
        return signal MLME_BEACON_NOTIFY.indication (frame);
      else if (m_resultIndex >= m_resultListNumEntries) {
        m_terminateScan = TRUE;
        call RadioOff.off();
      } else if (call BeaconFrame.parsePANDescriptor(
            frame, 
            m_currentChannelNum, 
            IEEE154_SUPPORTED_CHANNELPAGE,
            &((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex]) == SUCCESS) {

        // check uniqueness: PAN ID and source address must 
        // not be found in a previously received beacon
        uint8_t i;
        ieee154_PANDescriptor_t* descriptor = (ieee154_PANDescriptor_t*) m_resultList;

        dbg_serial("ScanP", "Received beacon, source: 0x%lx, channel: %lu.\n", 
            (uint32_t) descriptor[m_resultIndex].CoordAddress.shortAddress, (uint32_t) m_currentChannelNum);
        for (i=0; i<m_resultIndex; i++)
          if (descriptor[i].CoordPANId == descriptor[m_resultIndex].CoordPANId &&
              descriptor[i].CoordAddrMode == descriptor[m_resultIndex].CoordAddrMode)
            if ((descriptor[i].CoordAddrMode == ADDR_MODE_SHORT_ADDRESS &&
                  descriptor[i].CoordAddress.shortAddress ==
                  descriptor[m_resultIndex].CoordAddress.shortAddress) ||
                (descriptor[i].CoordAddrMode == ADDR_MODE_EXTENDED_ADDRESS &&
                 descriptor[i].CoordAddress.extendedAddress ==
                 descriptor[m_resultIndex].CoordAddress.extendedAddress))
              break; // not unique
        if (i == m_resultIndex)
          m_resultIndex++; // was unique
      }
      if (call BeaconFrame.getBeaconPayloadLength(frame) > 0)
        return signal MLME_BEACON_NOTIFY.indication (frame);
    } //  PASSIVE_SCAN / ACTIVE_SCAN
    return frame;
  }

  /* ----------------------- Common ----------------------- */

  task void startTimerTask() 
  { 
    call ScanTimer.startOneShot(m_scanDuration); 
  }

  event void ScanTimer.fired()
  {
    call RadioOff.off();
  }

  async event void RadioOff.offDone()
  {
    if (m_currentChannelNum == 0)
      post continueScanRequestTask();
    else {
      m_currentChannelNum++;    
      post nextIterationTask();
    }
  }

  task void nextIterationTask()
  {
    nextIteration();
  }

  async command token_requested_t IsRadioTokenRequested.getNow(){ return m_busy;}
  async event void RadioToken.transferredFrom(uint8_t id){ ASSERT(0);}
  default event message_t* MLME_BEACON_NOTIFY.indication (message_t *beaconFrame) {return beaconFrame;}
  default event void MLME_SCAN.confirm    (
                          ieee154_status_t status,
                          uint8_t ScanType,
                          uint8_t ChannelPage,
                          uint32_t UnscannedChannels,
                          uint8_t EnergyDetectListNumEntries,
                          int8_t* EnergyDetectList,
                          uint8_t PANDescriptorListNumEntries,
                          ieee154_PANDescriptor_t* PANDescriptorList) {}
}

⌨️ 快捷键说明

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