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

📄 beaconsynchronizep.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 2 页
字号:
        // "To acquire beacon synchronization, a device shall enable its 
        // receiver and search for at most [aBaseSuperframeDuration * (2^n + 1)]
        // symbols, where n is the value of macBeaconOrder [...] Once the number
        // of missed beacons reaches aMaxLostBeacons, the MLME shall notify the 
        // next higher layer." (Sect. 7.5.4.1)
        m_state = S_RECEIVING;
        dt = (((uint32_t) 1 << m_beaconOrder) + (uint32_t) 1) * 
          (uint32_t) IEEE154_aBaseSuperframeDuration * 
          (uint32_t) IEEE154_aMaxLostBeacons;
        call TrackAlarm.start(dt);
        dbg_serial("BeaconSynchronizeP","Rx enabled, expecting beacon within %lu symbols.\n", dt);
        break;
      case S_PREPARE:
        m_state = S_RECEIVING;
        dt = m_dt + IEEE154_MAX_BEACON_LISTEN_TIME(m_beaconOrder);
        call TrackAlarm.startAt(m_lastBeaconRxTime, dt);
        dbg_serial("BeaconSynchronizeP","Rx enabled, expecting beacon within %lu symbols.\n",
            (uint32_t) ((m_lastBeaconRxTime + dt) - call TrackAlarm.getNow())); 
        break;
      default:
        ASSERT(0);
        break;
    }
  }

  async event void TrackAlarm.fired()
  {
    if (m_state == S_PREPARE) {
      uint32_t maxBeaconJitter = IEEE154_MAX_BEACON_JITTER(m_beaconOrder);
      if (maxBeaconJitter > m_dt)
        maxBeaconJitter = m_dt; // receive immediately
      call BeaconRx.enableRx(m_lastBeaconRxTime, m_dt - maxBeaconJitter);
    } else {
      ASSERT(m_state == S_RECEIVING && call RadioOff.off() == SUCCESS); 
    }
  }

  event message_t* BeaconRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
  {
    if (m_bufferBusy || !call FrameUtility.isBeaconFromCoord(frame))
    {
      if (m_bufferBusy) {
        dbg_serial("BeaconSynchronizeP", "Got another beacon, dropping it.\n");}
      else
        dbg_serial("BeaconSynchronizeP", "Got a beacon, but not from my coordinator.\n");
      return frame;
    } else {
      message_t *tmp = m_beaconPtr;
      m_bufferBusy = TRUE;
      m_beaconPtr = frame;
      if (timestamp != NULL)
        memcpy(&m_lastBeaconRxRefTime, timestamp, sizeof(ieee154_timestamp_t));
      if (m_state == S_RECEIVING) { 
        call TrackAlarm.stop(); // may fail
        call RadioOff.off();    // may fail
      }
      return tmp;
    }
  }

  task void processBeaconTask()
  {
    // if we received a beacon from our coordinator then it is processed now
    if (!m_bufferBusy || !call Frame.isTimestampValid(m_beaconPtr)) {
      // missed a beacon or received a beacon with invalid timestamp
      if (!m_bufferBusy)
        dbg_serial("BeaconSynchronizeP", "No beacon received!\n");
      else
        dbg_serial("BeaconSynchronizeP", "Beacon has invalid timestamp!\n");

      m_numBeaconsLost += 1;
      m_dt += m_beaconInterval;
      m_bufferBusy = FALSE;

      if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons) {
        // lost too many beacons, give up!
        m_tracking = FALSE;
        dbg_serial("BeaconSynchronizeP", "MLME_SYNC_LOSS!\n");
        signal MLME_SYNC_LOSS.indication(
              IEEE154_BEACON_LOSS, 
              call MLME_GET.macPANId(),
              call MLME_GET.phyCurrentChannel(),
              call MLME_GET.phyCurrentPage(), 
              NULL);
      } else
        call RadioToken.request(); // make another request again (before giving the token up)

      call RadioToken.release();
    } else { 
      // got the beacon!
      uint8_t *payload = (uint8_t *) m_beaconPtr->data;
      ieee154_macAutoRequest_t autoRequest = call MLME_GET.macAutoRequest();
      uint8_t pendAddrSpecOffset = 3 + (((payload[2] & 7) > 0) ? 1 + (payload[2] & 7) * 3: 0); // skip GTS
      uint8_t pendAddrSpec = payload[pendAddrSpecOffset];
      uint8_t *beaconPayload = payload + pendAddrSpecOffset + 1;
      uint8_t beaconPayloadSize = call BeaconFrame.getBeaconPayloadLength(m_beaconPtr);
      uint8_t pendingAddrMode = ADDR_MODE_NOT_PRESENT;
      uint8_t coordBeaconOrder;
      uint8_t *mhr = MHR(m_beaconPtr);
      uint8_t frameLen = ((uint8_t*) m_beaconPtr)[0] & FRAMECTL_LENGTH_MASK;
      uint8_t gtsFieldLength;
      uint32_t timestamp = call Frame.getTimestamp(m_beaconPtr);

      dbg_serial("BeaconSynchronizeP", "Got beacon, timestamp: %lu, offset to previous: %lu\n", 
        (uint32_t) timestamp, (uint32_t) (timestamp - m_lastBeaconRxTime));

      m_numGtsSlots = (payload[2] & 7);
      gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
      m_lastBeaconRxTime = timestamp;
      m_numCapSlots = (payload[1] & 0x0F) + 1;
      m_sfSlotDuration = (((uint32_t) 1) << ((payload[0] & 0xF0) >> 4)) * IEEE154_aBaseSlotDuration;
      memcpy(m_gtsField, &payload[2], gtsFieldLength);

      // check for battery life extension
      if (payload[1] & 0x10) {
        // BLE is active; calculate the time offset from slot0
        m_battLifeExtDuration = IEEE154_SHR_DURATION + frameLen * IEEE154_SYMBOLS_PER_OCTET;
        if (frameLen > IEEE154_aMaxSIFSFrameSize)
          m_battLifeExtDuration += call MLME_GET.macMinLIFSPeriod();
        else
          m_battLifeExtDuration += call MLME_GET.macMinSIFSPeriod();
        m_battLifeExtDuration = m_battLifeExtDuration + call MLME_GET.macBattLifeExtPeriods() * 20;
      } else
        m_battLifeExtDuration = 0;

      m_framePendingBit = mhr[MHR_INDEX_FC1] & FC1_FRAME_PENDING ? TRUE : FALSE;
      coordBeaconOrder = (payload[0] & 0x0F); 
      m_dt = m_beaconInterval = ((uint32_t) 1 << coordBeaconOrder) * (uint32_t) IEEE154_aBaseSuperframeDuration; 

      if (m_stopTracking) {
        m_tracking = FALSE;
        dbg_serial("BeaconSynchronizeP", "Stop tracking.\n");
        if (m_updatePending) // there is already a new request ...
          call RadioToken.request();
        call RadioToken.release();
      } else {
        dbg_serial("BeaconSynchronizeP", "Handing over to CAP.\n");
        // we pass on the token now, but make a reservation to get it back 
        // to receive the next beacon (at the start of the next superframe)
        call RadioToken.request();  
        call RadioToken.transferTo(RADIO_CLIENT_DEVICECAP); 
      }
      
      if (pendAddrSpec & PENDING_ADDRESS_SHORT_MASK)
        beaconPayload += (pendAddrSpec & PENDING_ADDRESS_SHORT_MASK) * 2;
      if (pendAddrSpec & PENDING_ADDRESS_EXT_MASK)
        beaconPayload += ((pendAddrSpec & PENDING_ADDRESS_EXT_MASK) >> 4) * 8;

      // check for pending data (once we signal MLME_BEACON_NOTIFY we cannot
      // touch this frame anymore!)
      if (autoRequest)
        pendingAddrMode = call BeaconFrame.isLocalAddrPending(m_beaconPtr);
      if (pendingAddrMode != ADDR_MODE_NOT_PRESENT) {
        // the coord has pending data
        uint8_t CoordAddrMode;
        uint16_t CoordPANId;
        uint8_t *CoordAddress;
        uint8_t SrcAddrMode = pendingAddrMode;
        if ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == FC2_SRC_MODE_SHORT)
          CoordAddrMode = ADDR_MODE_SHORT_ADDRESS;
        else
          CoordAddrMode = ADDR_MODE_EXTENDED_ADDRESS;
        CoordAddress = &(mhr[MHR_INDEX_ADDRESS+2]);
        CoordPANId = *((nxle_uint16_t*) &(mhr[MHR_INDEX_ADDRESS]));
        call DataRequest.poll(CoordAddrMode, CoordPANId, CoordAddress, SrcAddrMode);
      }

      // Beacon Tracking: update state
      m_numBeaconsLost = 0;
      // TODO: check PAN ID conflict here?
      if (!autoRequest || beaconPayloadSize)
        m_beaconPtr = signal MLME_BEACON_NOTIFY.indication(m_beaconPtr);
      m_bufferBusy = FALSE;
    }
    dbg_serial_flush();
  }

  command error_t TrackSingleBeacon.start()
  {
    // Track a single beacon now
    if (!m_tracking && !m_updatePending && !call RadioToken.isOwner()) {
      // find a single beacon now (treat this like a user request)
      m_updateLogicalChannel = call MLME_GET.phyCurrentChannel();
      m_updateTrackBeacon = FALSE;
      m_stopTracking = TRUE;
      m_updatePending = TRUE;
      call RadioToken.request();
    }
    return SUCCESS;
  }

  command error_t TrackSingleBeacon.stop()
  {
    // will stop automatically after beacon was tracked/not found
    return FAIL;
  }
  
  /* -----------------------  SF Structure, etc. ----------------------- */

  async command uint32_t IncomingSF.sfStartTime()
  { 
    return m_lastBeaconRxTime; 
  }

  async command uint16_t IncomingSF.sfSlotDuration()
  { 
    return m_sfSlotDuration;
  }

  async command uint8_t IncomingSF.numCapSlots()
  {
    return m_numCapSlots;
  }

  async command uint8_t IncomingSF.numGtsSlots()
  {
    return m_numGtsSlots;
  }

  async command uint16_t IncomingSF.battLifeExtDuration()
  {
    return m_battLifeExtDuration;
  }

  async command const uint8_t* IncomingSF.gtsFields()
  {
    return m_gtsField;
  }

  async command uint16_t IncomingSF.guardTime()
  {
    return IEEE154_MAX_BEACON_JITTER(m_beaconOrder) + IEEE154_RADIO_RX_DELAY;
  }

  async command const ieee154_timestamp_t* IncomingSF.sfStartTimeRef()
  {
    return &m_lastBeaconRxRefTime;
  }

  async command bool IncomingSF.isBroadcastPending()
  {
    return m_framePendingBit;
  }

  async command bool IsTrackingBeacons.getNow()
  { 
    return m_tracking;
  }

  event void DataRequest.pollDone() {}

  default event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame) {return frame;}
  default event void MLME_SYNC_LOSS.indication (
                          ieee154_status_t lossReason,
                          uint16_t panID,
                          uint8_t logicalChannel,
                          uint8_t channelPage,
                          ieee154_security_t *security) {}

  event message_t* CoordRealignmentRx.received(message_t* frame)
  {
    uint8_t *payload = call Frame.getPayload(frame);
    ieee154_macPANId_t panID = *(nxle_uint16_t*) &payload[1];
    if (panID == call MLME_GET.macPANId())
        signal MLME_SYNC_LOSS.indication(
          IEEE154_REALIGNMENT,   // LossReason
          panID,                 // PANId
          payload[5],            // LogicalChannel,
          call Frame.getPayloadLength(frame) == 9 ? payload[8] : call MLME_GET.phyCurrentPage(),
          NULL);
    return frame;
  }
}

⌨️ 快捷键说明

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