📄 mac_beacon_handler.c
字号:
// Remain in this state until the beacon transmission can begin
if ((mtimInfo.bosCounter - bacupBosCounter) == MBCN_TX_PREPARE_TIME) {
// Resume transmission of direct packets after the beacon transmission
mtimSetCallback(mtxResumeAfterBeaconCallback, (pPacket->duration + MBCN_TX_STARTUP_OVERHEAD ));
// Set the RX interval (if any)
if (mpib.macSuperframeOrder != 15) {
if (mpib.macRxOnWhenIdle) {
// On:
mrxAutoIncrOnCounter();
// Off:
if (mpib.macBattLifeExt) {
// Soft off
mtimSetCallback(mrxDecrOnCounter, pPacket->duration + mpib.macBattLifeExtPeriods - MBCN_TX_PREPARE_TIME);
} else {
// Force when the superframe is shorter than the beacon interval
mtimSetCallback((mpib.macBeaconOrder == mpib.macSuperframeOrder) ? mrxDecrOnCounter : mrxForceRxOff, msupCalcSuperframeDuration() - MBCN_TX_PREPARE_TIME);
}
}
}
// Transform this task into an mtxStartTransmission()
pTask->state = MTX_STATE_TURN_ON_RX;
pTask->taskData = (WORD) pPacket;
pTask->pTaskFunc = mtxStartTransmission;
// Disaster :(
// The prepare time was too short!!! (DEBUG: Add a breakpoint here if beacons are missing)
} else if ((mtimInfo.bosCounter - bacupBosCounter) > MBCN_TX_PREPARE_TIME) {
// 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, QWORD *pDestAddr, WORD shortAddr, ...)
//
// 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
// QWORD *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, QWORD *pDestAddr, WORD shortAddr, BOOL securityEnable, WORD newPanId, UINT8 logicalChannel) {
WORD broadcast = 0xFFFF;
BYTE txOptions;
UINT8 temp;
BYTE *pPayload;
// 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, (ADDRESS*) 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->mc.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 = pPacket->headerLength + temp + MAC_FCS_LENGTH;
// Generate the packet payload
*(pPayload++) = (BYTE) newPanId;
*(pPayload++) = (BYTE) ((newPanId & 0xFF00) >> 8);
*(pPayload++) = (BYTE) mpib.macShortAddress;
*(pPayload++) = (BYTE) ((mpib.macShortAddress & 0xFF00) >> 8);
*(pPayload++) = logicalChannel;
*(pPayload++) = (BYTE) shortAddr;
*(pPayload) = (BYTE) ((shortAddr & 0xFF00) >> 8);
// Calculate the packet duration (including ack. and IFS)
pPacket->duration = msupCalcPacketDuration(pPacket->length, txOptions & TX_OPT_ACK_REQ);
} // mbcnPrepareCoordinatorRealignment
//-------------------------------------------------------------------------------------------------------
// void mbcnPrepareBeacon(void)
//
// DESCRIPTION:
// Prepares a valid beacon frame which can be transmitted using the TX engine.
//
// ARGUMENTS:
// MAC_TX_PACKET *pPacket
// A pointer to the packet to be transmitted
//-------------------------------------------------------------------------------------------------------
void mbcnPrepareBeacon(MAC_TX_PACKET *pPacket) {
BYTE srcAddrMode;
WORD superframeSpec;
BYTE *pMacBeaconPayload;
BYTE pendAddrSpec;
MAC_TX_PACKET *pIndirectPacket;
UINT8 n, pendShortAddrCount, pendExtAddrCount;
BYTE *pPayload = pPacket->pPayload;
// TX mode
pPacket->txMode = 0;
// pPacket->retriesLeft will be ignored (no ack)
// Header
srcAddrMode = (mpib.macShortAddress < 0xFFFE) ? SRC_ADDR_SHORT : SRC_ADDR_EXT;
msupPrepareHeader(pPacket, FT_BEACON, srcAddrMode, mpib.macPANId, (srcAddrMode == SRC_ADDR_SHORT) ? (ADDRESS*) &mpib.macShortAddress : (ADDRESS*) &aExtendedAddress, 0, NULL, GET_MF(MF_BEACON_SECURITY));
// Superframe specification
superframeSpec = (mpib.macBeaconOrder << SS_BEACON_ORDER_IDX) |
(mpib.macSuperframeOrder << SS_SUPERFRAME_ORDER_IDX) |
(15 << SS_FINAL_CAP_SLOT_IDX) |
(mpib.macBattLifeExt ? SS_BATT_LIFE_EXT_BM : 0) |
(GET_MF(MF_PAN_COORDINATOR) ? SS_PAN_COORDINATOR_BM : 0) |
(mpib.macAssociationPermit ? SS_ASSOCIATION_PERMIT_BM : 0);
*((WORD*) pPayload) = superframeSpec;
pPayload += 2;
// GTS list (not implemented)
*(pPayload++) = 0x00;
// Pending address list
// Count the number of pending addresses to get the packet length
n = miqInfo.firstIndirectPacket;
pendShortAddrCount = 0;
pendExtAddrCount = 0;
while ((n != NO_PACKET) && ((pendShortAddrCount + pendExtAddrCount) < MAX_PENDING_LIST_SIZE)) {
pIndirectPacket = &pMtxPacketPool[n];
if (pIndirectPacket->timeToLive > 0) {
if (pIndirectPacket->isFirstPacket) {
if ((pIndirectPacket->pHeader[1] & DEST_ADDR_BM) == DEST_ADDR_EXT) {
pendExtAddrCount++;
} else {
pendShortAddrCount++;
}
}
}
n = pIndirectPacket->nextPacket;
}
// Pending address specification (indicates the number of short and extended addresses)
pendAddrSpec = pendShortAddrCount + (pendExtAddrCount << 4);
*(pPayload++) = pendAddrSpec;
// Address list
if (pendAddrSpec) {
// Short addresses
n = miqInfo.firstIndirectPacket;
do {
pIndirectPacket = &pMtxPacketPool[n];
if (pIndirectPacket->isFirstPacket && (pIndirectPacket->timeToLive > 0) && ((pIndirectPacket->pHeader[1] & DEST_ADDR_BM) == DEST_ADDR_SHORT)) {
// Copy the packet destination address
memcpy(pPayload, pIndirectPacket->pHeader + 5, 2);
pendShortAddrCount--;
pPayload += 2;
}
n = pIndirectPacket->nextPacket;
} while (pendShortAddrCount);
// Extended addresses
n = miqInfo.firstIndirectPacket;
do {
pIndirectPacket = &pMtxPacketPool[n];
if (pIndirectPacket->isFirstPacket && (pIndirectPacket->timeToLive > 0) && ((pIndirectPacket->pHeader[1] & DEST_ADDR_BM) == DEST_ADDR_EXT)) {
// Copy the packet destination address
memcpy(pPayload, pIndirectPacket->pHeader + 5, 8);
pendExtAddrCount--;
pPayload += 8;
}
n = pIndirectPacket->nextPacket;
} while (pendExtAddrCount);
}
// Beacon payload (safe access to mpib.pMacBeaconPayload)
DISABLE_GLOBAL_INT();
pMacBeaconPayload = mpib.pMacBeaconPayload;
ENABLE_GLOBAL_INT();
memcpy(pPayload, pMacBeaconPayload, mpib.macBeaconPayloadLength);
pPayload += mpib.macBeaconPayloadLength;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -