?? mac_beacon_handler.c
字號:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + 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 + -