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

📄 beaconsynchronizep.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/10/16 12:25:45 $
 * @author Jan Hauer <hauer@tkn.tu-berlin.de>
 * ========================================================================
 */

/** 
 * This module is responsible for periodic beacon tracking in a 
 * beacon-enabled PAN.
 */

#include "TKN154_MAC.h"

module BeaconSynchronizeP
{
  provides
  {
    interface Init as Reset;
    interface MLME_SYNC;
    interface MLME_BEACON_NOTIFY;
    interface MLME_SYNC_LOSS;
    interface SuperframeStructure as IncomingSF;
    interface GetNow<bool> as IsTrackingBeacons;
    interface StdControl as TrackSingleBeacon;
  }
  uses
  {
    interface MLME_GET;
    interface MLME_SET;
    interface FrameUtility;
    interface IEEE154BeaconFrame as BeaconFrame;
    interface Alarm<TSymbolIEEE802154,uint32_t> as TrackAlarm;
    interface RadioRx as BeaconRx;
    interface RadioOff;
    interface DataRequest;
    interface FrameRx as CoordRealignmentRx;
    interface TransferableResource as RadioToken;
    interface TimeCalc;
    interface IEEE154Frame as Frame;
    interface Leds;
  }
}
implementation
{
  /* state variables */
  norace bool m_tracking;
  bool m_stopTracking ;
  norace uint8_t m_numBeaconsLost;
  norace uint8_t m_state;
  norace bool m_bufferBusy;

  /* buffers for the parameters of the MLME-SYNC request */
  norace bool m_updatePending;
  uint8_t m_updateLogicalChannel;
  bool m_updateTrackBeacon;

  /* variables that describe the current configuration */
  norace uint32_t m_beaconInterval;
  norace uint32_t m_dt;
  norace uint32_t m_lastBeaconRxTime;
  norace ieee154_timestamp_t m_lastBeaconRxRefTime;
  norace uint8_t m_beaconOrder;
  message_t m_beacon;
  norace message_t *m_beaconPtr = &m_beacon;

  /* variables that describe the latest superframe */
  norace uint32_t m_sfSlotDuration;
  norace bool m_framePendingBit;
  norace uint8_t m_numCapSlots;
  norace uint8_t m_numGtsSlots;
  norace uint16_t m_battLifeExtDuration;
  uint8_t m_gtsField[1+1+3*7];
  
  enum {
    S_PREPARE = 0,
    S_RECEIVING = 1,
    S_RADIO_OFF = 2,
    S_INITIAL_SCAN= 3,

  };


  /* function/task prototypes */
  task void processBeaconTask();
  void trackNextBeacon();
  task void signalGrantedTask();

  command error_t Reset.init()
  {
    // reset this component. will only be called 
    // while we're not owning the token           
    if (m_tracking || m_updatePending)
      signal MLME_SYNC_LOSS.indication(
          IEEE154_BEACON_LOSS,
          call MLME_GET.macPANId(),
          call MLME_GET.phyCurrentChannel(),
          call MLME_GET.phyCurrentPage(),
          NULL);
    m_updatePending = m_stopTracking = m_tracking = FALSE;
    return SUCCESS;
  }  

  /* ----------------------- MLME-SYNC ----------------------- */
  /*
   * Allows to synchronize with the beacons from a coordinator.
   */

  command ieee154_status_t MLME_SYNC.request  (
      uint8_t logicalChannel,
      uint8_t channelPage,
      bool trackBeacon)
  {
    error_t status = IEEE154_SUCCESS;
    uint32_t supportedChannels = IEEE154_SUPPORTED_CHANNELS;
    uint32_t currentChannelBit = 1;

    currentChannelBit <<= logicalChannel;
    if (!(currentChannelBit & supportedChannels) || (call MLME_GET.macPANId() == 0xFFFF) ||
        (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !IEEE154_BEACON_ENABLED_PAN)
      status = IEEE154_INVALID_PARAMETER;
    else {
      if (!trackBeacon && m_tracking) {
        // stop tracking after next received beacon
        m_stopTracking = TRUE;
      } else {
        m_stopTracking = FALSE;
        m_updateLogicalChannel = logicalChannel;
        m_updateTrackBeacon = trackBeacon;
        m_updatePending = TRUE;
        atomic {
          // if we are tracking then we'll get the RadioToken automatically,
          // otherwise request it now
          if (!m_tracking && !call RadioToken.isOwner())
            call RadioToken.request();  
        }
      }
    }
    dbg_serial("BeaconSynchronizeP", "MLME_SYNC.request -> result: %lu\n", (uint32_t) status);
    return status;
  }

  event void RadioToken.granted()
  {
    dbg_serial("BeaconSynchronizeP","Got token, expecting beacon in %lu\n",
        (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow())); 
    if (m_updatePending) {
      dbg_serial("BeaconSynchronizeP", "Preparing initial scan\n"); 
      m_state = S_INITIAL_SCAN;
      m_updatePending = FALSE;      
      m_beaconOrder = call MLME_GET.macBeaconOrder();
      if (m_beaconOrder >= 15)
        m_beaconOrder = 14;
      call MLME_SET.phyCurrentChannel(m_updateLogicalChannel);
      m_tracking = m_updateTrackBeacon;
      m_beaconInterval = ((uint32_t) 1 << m_beaconOrder) * (uint32_t) IEEE154_aBaseSuperframeDuration; 
      m_dt = m_beaconInterval;
      m_numBeaconsLost = IEEE154_aMaxLostBeacons;  // will be reset when beacon is received
    }
    trackNextBeacon();
  }

  async event void RadioToken.transferredFrom(uint8_t clientFrom)
  {
    dbg_serial("BeaconSynchronizeP","Token.transferred(), expecting beacon in %lu symbols.\n",
        (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow())); 
    if (m_updatePending)
      post signalGrantedTask();
    else
      trackNextBeacon();
  }


  task void signalGrantedTask()
  {
    signal RadioToken.granted();
  }

  void trackNextBeacon()
  {
    bool missed = FALSE;

    if (m_state != S_INITIAL_SCAN) {

      if (!m_tracking) {
        // nothing to do, just give up the token
        dbg_serial("BeaconSynchronizeP", "Stop tracking.\n");
        call RadioToken.release();
        return;
      }

      // we have received at least one previous beacon
      m_state = S_PREPARE;
      while (call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt)) { // missed a beacon!
        dbg_serial("BeaconSynchronizeP", "Missed a beacon, expected it: %lu, now: %lu\n", 
            m_lastBeaconRxTime + m_dt, call TrackAlarm.getNow());
        missed = TRUE;
        m_dt += m_beaconInterval;
        m_numBeaconsLost++;
      }

      if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons) {
        dbg_serial("BeaconSynchronizeP", "Missed too many beacons.\n");
        post processBeaconTask();
        return;
      }

      if (missed) {
        // let other components get a chance to use the radio
        call RadioToken.request();
        dbg_serial("BeaconSynchronizeP", "Allowing other components to get the token.\n");
        call RadioToken.release();
        return;
      }
    }

    if (call RadioOff.isOff())
      signal RadioOff.offDone();
    else if (call RadioOff.off() != SUCCESS) 
      ASSERT(0);
  }

  async event void RadioOff.offDone()
  {
    uint32_t delay = IEEE154_RADIO_RX_DELAY + IEEE154_MAX_BEACON_JITTER(m_beaconOrder);

    if (m_state == S_INITIAL_SCAN) {
      // initial scan
      call BeaconRx.enableRx(0, 0);
    } else if (m_state == S_PREPARE) {
      if (!call TimeCalc.hasExpired(m_lastBeaconRxTime - delay, m_dt))
        call TrackAlarm.startAt(m_lastBeaconRxTime - delay, m_dt);
      else
        signal TrackAlarm.fired();
    } else {
      post processBeaconTask();
    }
  }

  async event void BeaconRx.enableRxDone()
  {
    uint32_t dt;

    switch (m_state)
    {
      case S_INITIAL_SCAN: 

⌨️ 快捷键说明

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