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

📄 mac_beacon_handler.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************************************
 *                                                                                                     *
 *        **********                                                                                   *
 *       ************                                                                                  *
 *      ***        ***                                                                                 *
 *      ***   +++   ***                                                                                *
 *      ***   + +   ***                                                                                *
 *      ***   +                         CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY                 *
 *      ***   + +   ***                        Beacon TX and Tracking + Related                        *
 *      ***   +++   ***                                                                                *
 *      ***        ***                                                                                 *
 *       ************                                                                                  *
 *        **********                                                                                   *
 *                                                                                                     *
 *******************************************************************************************************
 * CONFIDENTIAL                                                                                        *
 * The use of this file is restricted by the signed MAC software license agreement.                    *
 *                                                                                                     *
 * Copyright Chipcon AS, 2005                                                                          *
 *******************************************************************************************************
 * This module contains functions the functions responsible for receiving and transmitting beacons,    *
 * and related functions, such as synchronization and coordinator realignment.                         *
 *******************************************************************************************************/
#include "mac_headers.h"


//-------------------------------------------------------------------------------------------------------
// Beacon-related variables
MAC_BEACON_INFO mbcnInfo;
//-------------------------------------------------------------------------------------------------------




/*******************************************************************************************************
 *******************************************************************************************************
 **************************                 BEACON RECEPTION                  **************************
 *******************************************************************************************************
 *******************************************************************************************************/




//-------------------------------------------------------------------------------------------------------
//  void mbcnRxPeriodicalBeacon(void)
//
//  DESCRIPTION:
//      Creates the task that handles reception of periodical beacons (in a beacon-enabled PAN)
//-------------------------------------------------------------------------------------------------------
void mbcnRxPeriodicalBeacon(void) NEAR {
    mschAddTask(mbcnInfo.rxTaskNumber, MAC_TASK_PRI_HIGHEST, mbcnRxPeriodicalBeaconTask, NULL);
} // mbcnRxPeriodicalBeacon




//-------------------------------------------------------------------------------------------------------
//  void mbcnRxPeriodicalBeaconTask(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      Handles configuration of timers related to beacon reception (including starting RX and the
//      timeout to be generated when no beacon is received). It also handles beacon loss.
//
//      Note: When a beacon is received, the current mbcnRxPeriodicalBeacon callback must be cancelled,
//      and a new callback must be set up.
//
//  TASK DATA:
//      0
//-------------------------------------------------------------------------------------------------------
void mbcnRxPeriodicalBeaconTask(MAC_TASK_INFO *pTask) NEAR {

    // Beacon loss?
    if (!mbcnInfo.noBcnCountdown) {

        // Stop the search/tracking
        if (mbcnInfo.findBeacon) mrxDecrOnCounter();

        mbcnInfo.findBeacon = FALSE;
        mbcnInfo.trackBeacon = FALSE;

        // Update buffered PIB attributes
        mbcnUpdateBufferedPibAttributes();

        // Remove and release the task
        mschRemoveTask(pTask->priority, 0);
        mbcnInfo.rxTaskNumber = NO_TASK;

        // Make the call to the higher layer
        mlmeSyncLossIndication(BEACON_LOSS);

    } else {
        mrxIncrOnCounter();

        // Update buffered PIB attributes
        mbcnUpdateBufferedPibAttributes();

        // Schedule the next beacon handler, including XTAL error margin (the startup margin is cumulative when missing beacons)
        mtimSetCallback(mbcnRxPeriodicalBeacon, msupCalcBeaconInterval() - mbcnGetBeaconMargin());

        // Set the RF channel (but don't mess up scanning)
        if (!(macInfo.state & MAC_STATE_SCAN_BM)) msupSetChannel(ppib.phyCurrentChannel, FALSE);

        // Set the off-timer (the off-time is also cumulative)
        mtimSetCallback(mbcnRxBeaconTimeout, (UINT16) 2 * ((UINT16) aMaxLostBeacons - (UINT16) mbcnInfo.noBcnCountdown + (UINT16) 1) * (UINT16) mbcnGetBeaconMargin() + (UINT16) MBCN_RX_STARTUP_OVERHEAD);

        // Finish this task, but keep the reservation!
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM);
    }

} // mbcnRxPeriodicalBeaconTask




//-------------------------------------------------------------------------------------------------------
//  void mbcnRxBeaconTimeout(void)
//
//  DESCRIPTION:
//      Called when no beacon has been received. Decrements the counter which will give "beacon loss"
//      when it reaches zero. This timeout is set up in mbcnRxPeriodicalBeaconTask().
//-------------------------------------------------------------------------------------------------------
void mbcnRxBeaconTimeout(void) NEAR {

    // The beacon reception interval is over (mbcnRxBeacon)
    mrxDecrOnCounter();

    // Update the tracking counter...
    mbcnInfo.noBcnCountdown--;

} // mbcnRxBeaconTimeout




/*******************************************************************************************************
 *******************************************************************************************************
 **************************                BEACON TRANSMISSION                **************************
 *******************************************************************************************************
 *******************************************************************************************************/


#if MAC_OPT_FFD

//-------------------------------------------------------------------------------------------------------
//  void mbcnTxPeriodicalBeacon(void)
//
//  DESCRIPTION:
//      Creates the task that handles transmission of periodical beacons (in a beacon-enabled PAN)
//-------------------------------------------------------------------------------------------------------
void mbcnTxPeriodicalBeacon(void) NEAR {
    mschAddTask(mbcnInfo.txTaskNumber, MAC_TASK_PRI_HIGHEST, mbcnTxPeriodicalBeaconTask, NULL);
} // mbcnTxPeriodicalBeacon




//-------------------------------------------------------------------------------------------------------
//  void mbcnTxPeriodicalBeaconTask(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task is responsible for beacon transmission, and a few other housekeeping procedures (see
//      the function comments. When finished, this task will continue in the mtxStartTransmission
//      function (the task function pointer and the state is modified.
//
//  TASK DATA:
//      0
//-------------------------------------------------------------------------------------------------------
void mbcnTxPeriodicalBeaconTask(MAC_TASK_INFO *pTask) NEAR {
    static UINT32 oldBeaconInterval;
    MAC_TX_PACKET   *pPacket = mbcnInfo.pTxPacket;

    switch (pTask->state) {
    case MBCN_SET_NEXT_CALLBACK_PREPTX:

        // Set the RF channel
        msupSetChannel(ppib.phyCurrentChannel, FALSE);

        // Update buffered PIB attributes
        oldBeaconInterval = msupCalcBeaconInterval();
        mbcnUpdateBufferedPibAttributes();

        // Transmit the beacon, unless we're in scan mode (just increment the sequence number)
        if (macInfo.state & MAC_STATE_SCAN_BM) {
            mpib.macBSN++;
            mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);

        } else {

            // TBD: Set mpib.macBeaconTxTime (here?)

            // Unrequest all indirect packets, and decrement timeToLive
            miqUnrequestAll();
            miqDecrTimeToLive();

            // Create the task that later on will remove expired packets
            mschAddTask(mschReserveTask(), MAC_TASK_PRI_MEDIUM, miqExpireIndirectPacketsTask, NULL);

            // Generate the beacon frame
            mbcnPrepareBeacon(pPacket);
            pPacket->slotted = TRUE;
            pTask->state = MBCN_START_TRANSMISSION;
        }
        break;

    case MBCN_START_TRANSMISSION:

        // Remain in this state until the beacon transmission can begin
        if (T2_GET_OVERFLOW_COUNTER() == (oldBeaconInterval - MBCN_TX_STARTUP_OVERHEAD)) {

            // Schedule backoff slot counter reset (which in turn schedules the next mbcnTxPeriodicalBeacon)
            mtimSetCallback(mtxResetBosCounter, MBCN_TX_STARTUP_OVERHEAD);

            // Resume transmission of direct packets after the beacon transmission
            if (mtxInfo.waitForBeacon)
                mtimSetCallback(mtxResumeAfterBeaconCallback, (INT32)(pPacket->duration + MBCN_TX_STARTUP_OVERHEAD));

            // Set the RX interval (if any)
            if (mpib.macSuperframeOrder != 15) {
                if (mpib.macRxOnWhenIdle) {

                    // On:
                    mrxAutoIncrOnCounter();

                    // TBD: Move this stuff to mtxResetBosCounter?
                    // Off:
                    if (mpib.macBattLifeExt) {
                        // Soft off
                        mtimSetCallback(mrxDecrOnCounter, (INT32) pPacket->duration + mpib.macBattLifeExtPeriods + MBCN_TX_STARTUP_OVERHEAD);
                    } else {
                        // Force when the superframe is shorter than the beacon interval
                        mtimSetCallback((mpib.macBeaconOrder == mpib.macSuperframeOrder) ? mrxDecrOnCounter : mrxForceRxOff, (INT32) msupCalcSuperframeDuration() + MBCN_TX_STARTUP_OVERHEAD);
                    }
                }
            }

            // Transform this task into an mtxStartTransmission()
            pTask->state = MTX_STATE_PREPARE_PACKET;
            pTask->taskData = (WORD) pPacket;
            pTask->pTaskFunc = mtxStartTransmission;
            mtxInfo.beaconTransmissionInProgress = TRUE;
            mtxInfo.cspTimeout = CSP_TIMEOUT_RUN_FOREVER;

        // Disaster :(
        // The prepare time was too short!!! (DEBUG: Add a breakpoint here if beacons are missing)
        } else if (T2_GET_OVERFLOW_COUNTER() > oldBeaconInterval) {

            // Schedule backoff slot counter reset (which in turn schedules the next mbcnTxPeriodicalBeacon)
            mtimSetCallback(mtxResetBosCounter, MBCN_TX_STARTUP_OVERHEAD);

            // Don't transmit the beacon
            mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_RESERVED_BM | MSCH_KEEP_TASK_IN_PROGRESS_BM);
        }
        break;
    }

} // mbcnTxPeriodicalBeaconTask




//-------------------------------------------------------------------------------------------------------
//  void mbcnPrepareCoordinatorRealignment(MAC_TX_PACKET *pPacket, ADDRESS *pDestAddr, WORD ...)
//
//  DESCRIPTION:
//      This function prepares a coordinator realignment frame. If the pDestAddr argument points to an
//      extended address, the packet will be transmitted to a single device (doing orphan scanning). If
//      NULL, the packet will be broadcasted to all devices.
//
//  ARGUMENTS:
//      MAC_TX_PACKET *pPacket
//          A pointer to the packet to be transmitted
//      ADDRESS *pDestAddr
//          A pointer to the extended address of a specific device (mlmeOrphanResponse), or NULL if the
//          coordinator realignment is to be broadcasted (mlmeStartRequest)
//      WORD shortAddr
//          The short address of the orphaned device, or 0xFFFF when the coordinator realignment is
//          broadcasted
//      BOOL securityEnable
//          TBD
//      WORD newPanId
//          The PAN ID to be used in the future
//      UINT8 logicalChannel
//          The logical channel (11-26) to be used in the future
//-------------------------------------------------------------------------------------------------------
void mbcnPrepareCoordinatorRealignment(MAC_TX_PACKET *pPacket, ADDRESS *pDestAddr, WORD shortAddr, BOOL securityEnable, WORD newPanId, UINT8 logicalChannel) NEAR {
    WORD broadcast = 0xFFFF;
    BYTE txOptions;
    UINT8 temp;
    BYTE   *pPayload;

    if (securityEnable == TRUE)
      securityEnable = FALSE;

    // TX mode
    pPacket->txMode = MTX_MODE_USE_CSMACA_BM;

    // Set the TX options
    txOptions = TX_OPT_NONE;

#if MAC_OPT_SECURITY
    if (securityEnable) txOptions |= TX_OPT_SECURITY_ENABLE;
#endif

    // Generate the packet header
    if (pDestAddr) {
        pPacket->retriesLeft = aMaxFrameRetries;
        txOptions |= TX_OPT_ACK_REQ;
        msupPrepareHeader(pPacket, FT_MAC_COMMAND, SRC_ADDR_EXT | DEST_ADDR_EXT, mpib.macPANId, (ADDRESS   *) &aExtendedAddress, broadcast, pDestAddr, txOptions);
    } else {
        // pPacket->retriesLeft will be ignored (no ack)
        pPacket->txMode |= MTX_MODE_MAC_INTERNAL_BM;
        shortAddr = broadcast;
        msupPrepareHeader(pPacket, FT_MAC_COMMAND, SRC_ADDR_EXT | DEST_ADDR_SHORT, mpib.macPANId,(ADDRESS   *) &aExtendedAddress, broadcast, (ADDRESS   *) &broadcast, txOptions);
    }

    // Store the command type
    pPacket->commandType = CMD_COORDINATOR_REALIGNMENT;

    // Command frame identifier
    pPayload = pPacket->pPayload;
    *(pPayload++) = CMD_COORDINATOR_REALIGNMENT;

#if MAC_OPT_SECURITY
    // #bytes in frame counter + key sequence counter (0 or 5)
    temp = msecProcessSecurityCounters(pPacket, pPayload);

    // In case of frame counter overflow or missing key
    // Generate error with FAILED_SECURITY_CHECK or UNAVAILABLE_KEY

    // Increment payload pointer when counters inserted
    pPayload += temp;

    // Include command payload length and optional MIC (integrity code) length
    temp += CMD_COORDINATOR_REALIGNMENT_PAYLOAD_LENGTH + pPacket->securitySetup.micLength;

#else
    // No security material included, set MAC payload length
    temp = CMD_COORDINATOR_REALIGNMENT_PAYLOAD_LENGTH;
#endif

    // Set the packet length (four bytes of payload)
    pPacket->length = (BYTE)(pPacket->headerLength + temp + MAC_FCS_LENGTH);

    // Generate the packet payload
    *(pPayload++) = (BYTE) newPanId;

⌨️ 快捷键说明

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