📄 mac_support.c
字号:
// ADDRESS *pSrcAddr
// Pointer to the source address (short or extended)
// WORD destPanId,
// Destination PAN identifier
// ADDRESS *pDestAddr,
// Pointer to the destination address (short or extended)
// BYTE txOptions
// (TX_OPT_SECURITY_ENABLE | TX_OPT_INDIRECT | TX_OPT_GTS | TX_OPT_ACK_REQ) or TX_OPT_NONE
//-------------------------------------------------------------------------------------------------------
ROOT __xdata_reentrant void msupPrepareHeader(MAC_TX_PACKET *pPacket, BYTE type, BYTE addrModes, WORD srcPanId,
ADDRESS *pSrcAddr, WORD destPanId, ADDRESS *pDestAddr, BYTE txOptions)
{
BYTE temp;
UINT8 length = 0;
// Packet type and options
pPacket->type = type;
pPacket->txOptions = txOptions;
// Frame control field
temp = (BYTE)(type & FRAME_TYPE_BM);
#if MAC_OPT_SECURITY
pPacket->securitySetup.micLength = 0;
if (txOptions & TX_OPT_SECURITY_ENABLE) {
temp |= SECURITY_ENABLED_BM;
// Set securitySuite or securityStatus (UNAVAILABLE_KEY)
msecFindTxSecurityMaterial(pPacket, TRUE, ((addrModes & DEST_ADDR_BM) >> 2), destPanId, pDestAddr);
} else {
pPacket->securitySuite = MAC_SECURITY_NONE;
}
#else
pPacket->securitySuite = MAC_SECURITY_NONE;
#endif
if (txOptions & TX_OPT_ACK_REQ) temp |= ACK_REQ_BM;
if (((addrModes & BOTH_ADDR_USED) == BOTH_ADDR_USED) && (srcPanId == destPanId)) temp |= INTRA_PAN_BM;
pPacket->pHeader[length++] = temp;
pPacket->pHeader[length++] = addrModes;
// Sequence number
if (type == FT_BEACON) {
pPacket->pHeader[length++] = mpib.macBSN++;
} else {
pPacket->pHeader[length++] = mpib.macDSN++;
}
// Destination PAN ID
if (addrModes & DEST_ADDR_BM) {
pPacket->pHeader[length++] = LOBYTE(destPanId);
pPacket->pHeader[length++] = HIBYTE(destPanId);
pPacket->toCoord = mpib.macPANId == destPanId;
} else {
pPacket->toCoord = FALSE;
}
// Destination address
if ((addrModes & DEST_ADDR_BM) == DEST_ADDR_SHORT) {
pPacket->pHeader[length++] = LOBYTE(pDestAddr->Short);
pPacket->pHeader[length++] = HIBYTE(pDestAddr->Short);
pPacket->toCoord &= (mpib.macCoordShortAddress == pDestAddr->Short);
} else if ((addrModes & DEST_ADDR_BM) == DEST_ADDR_EXT) {
memcpy(pPacket->pHeader + length, pDestAddr->pExtended, 8);
length += 8;
pPacket->toCoord &= msupCompareExtendedAddress((ADDRESS *) mpib.pMacCoordExtendedAddress, pDestAddr);
}
// Source PAN ID
if (!(temp & INTRA_PAN_BM) && (addrModes & SRC_ADDR_BM)) {
pPacket->pHeader[length++] = LOBYTE(srcPanId);
pPacket->pHeader[length++] = HIBYTE(srcPanId);
}
// Source address
if ((addrModes & SRC_ADDR_BM) == SRC_ADDR_SHORT) {
pPacket->pHeader[length++] = LOBYTE(pSrcAddr->Short);
pPacket->pHeader[length++] = HIBYTE(pSrcAddr->Short);
} else if ((addrModes & SRC_ADDR_BM) == SRC_ADDR_EXT) {
memcpy(pPacket->pHeader + length, pSrcAddr->pExtended, 8);
length += 8;
}
pPacket->headerLength = length;
#if MAC_OPT_SECURITY
// By default, set cleartextLenght to header length
// Include command frame identifier for MAC command frames
// Note: clearTextLength must be incremented for beacon frames
pPacket->securitySetup.clearTextLength = length + (type == FT_MAC_COMMAND);
// Decode security suite and find setup information
// Set clearTextLength to 0 for CBC-MAC
msecDecodeSecuritySuite(&pPacket->securitySetup, pPacket->securitySuite);
#endif
} // msupPrepareHeader
//-------------------------------------------------------------------------------------------------------
// UINT8 msupCalcPacketDuration(UINT8 length, BOOL ackRequest)
//
// DESCRIPTION:
// Calculates the number of backoff slots required to transmit a packet, including (turnaround time,
// acknowledgment and) inter-frame spacing.
//
// PARAMETERS:
// UINT8 length
// The packet length in bytes (PHY frame length field)
// BOOL ackRequest
// Acknowledged packet?
//
// RETURN VALUE:
// UINT8
// The number of backoff slots required to transmit the packet
//-------------------------------------------------------------------------------------------------------
ROOT UINT8 msupCalcPacketDuration(UINT8 length, BOOL ackRequest) {
UINT8 totalByteCount, lastBosByteCount;
// Calculate the number of bytes in the whole packet (not including the preamble, but including
// SFD, length-byte and PSDU)
totalByteCount = (BYTE)(1 + 1 + length);
// Acknowledgment request
if (ackRequest) {
// The number of bytes in the last backoff slot
lastBosByteCount = (BYTE)(totalByteCount % (aUnitBackoffPeriod / 2));
// Round up the total count to N * (aUnitBackoffPeriod / 2), and add an extra slot if there isn't enough turnaround time before the ack (12-32 symbols)
if (lastBosByteCount)
totalByteCount = (BYTE)(totalByteCount + (aUnitBackoffPeriod / 2) - lastBosByteCount);
// Add the bytes in the acknowledgment frame
totalByteCount += (aUnitBackoffPeriod / 2) + (1 + 1 + 5);
}
// Add interframe spacing
if (length > aMaxSIFSFrameSize) {
totalByteCount += (aMinLIFSPeriod / 2);
} else {
totalByteCount += (aMinSIFSPeriod / 2);
}
// Round up
return ((BYTE) (((totalByteCount + ((aUnitBackoffPeriod / 2) - 1))) / (aUnitBackoffPeriod / 2)));
} // msupCalcPacketDuration
/*******************************************************************************************************
*******************************************************************************************************
************************** CC2430 RAM/FIFO ACCESS **************************
*******************************************************************************************************
*******************************************************************************************************/
ROOT void msupWriteExtendedAddress(BYTE *pExtendedAddress) {
IEEE_ADDR0 = pExtendedAddress[0];
IEEE_ADDR1 = pExtendedAddress[1];
IEEE_ADDR2 = pExtendedAddress[2];
IEEE_ADDR3 = pExtendedAddress[3];
IEEE_ADDR4 = pExtendedAddress[4];
IEEE_ADDR5 = pExtendedAddress[5];
IEEE_ADDR6 = pExtendedAddress[6];
IEEE_ADDR7 = pExtendedAddress[7];
}
/*******************************************************************************************************
*******************************************************************************************************
************************** SIMPLE CALCULATIONS **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// UINT32 msupCalcCapDuration(void)
//
// DESCRIPTION:
// Calculates the number off backoff slots in the superframe, minus the CFP. Does not subtract the
// beacon transmission time.
//
// RETURN VALUE:
// UINT32
// See above
//-------------------------------------------------------------------------------------------------------
ROOT UINT32 msupCalcCapDuration(void) {
return ((UINT32) (aBaseSlotDuration / aUnitBackoffPeriod) * (UINT32) (mbcnInfo.lastSfSpec.finalCap + (UINT32) 1)) << (UINT32) mpib.macSuperframeOrder;
} // msupCalcCapDuration
//-------------------------------------------------------------------------------------------------------
// UINT32 msupCalcSuperframeDuration(void)
//
// DESCRIPTION:
// Calculates the number off backoff slots in the superframe. Does not subtract the beacon
// transmission time.
//
// RETURN VALUE:
// UINT32
// See above
//-------------------------------------------------------------------------------------------------------
ROOT UINT32 msupCalcSuperframeDuration(void) {
return ((UINT32) (aBaseSlotDuration / aUnitBackoffPeriod) * (UINT32) 16) << (UINT32) mpib.macSuperframeOrder;
} // msupCalcCapDuration
//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
ROOT UINT32 msupGetBosCounter(void) {
EUINT32 value;
value.pB[0] = T2OF0;
value.pB[1] = T2OF1;
value.pB[2] = T2OF2;
value.pB[3] = 0;
return value.dw;
}
//-------------------------------------------------------------------------------------------------------
// UINT32 msupCalcBeaconInterval(void)
//
// DESCRIPTION:
// Calculates the number off backoff slots in the beacon interval.
//
// RETURN VALUE:
// UINT32
// See above
//-------------------------------------------------------------------------------------------------------
ROOT UINT32 msupCalcBeaconInterval(void) {
return (UINT32) (aBaseSuperframeDuration / aUnitBackoffPeriod) << (UINT32) mpib.macBeaconOrder;
} // msupCalcBeaconInterval
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM msupTransmitPanConflict(BYTE coordAddrMode, WORD coordPANId, ADDRESS *pCoordAddress, BOOL ...)
//
// DESCRIPTION:
// Transmits a PAN ID conflict notification message.
//
// ARGUMENTS:
// BYTE coordAddrMode
// The address mode used by the coordinator
// WORD coordPANId
// The PAN ID used by the coordinator
// ADDRESS *pCoordAddress
// A pointer to the coordinator address (taken from the MAC PIB, short or extended)
// BOOL securityEnable
// TBD...
//
// RETURN VALUE:
// MAC_ENUM
// SUCCESS No error (the transmission was initiated)
// RESOURCE_SHORTAGE TX packet or task not available
// UNAVAILABLE_KEY No key
// FAILED_SECURITY_CHECK Failed security check
//-------------------------------------------------------------------------------------------------------
MAC_ENUM msupTransmitPanConflict(BYTE coordAddrMode, WORD coordPANId, ADDRESS *pCoordAddress, BOOL securityEnable) {
MAC_TX_PACKET *pPacket;
UINT8 taskNumber;
BYTE txOptions = 0;
UINT8 temp;
BYTE *pPayload;
// Try to reserve a packet
pPacket = mtxpReservePacket();
if (!pPacket) return RESOURCE_SHORTAGE;
// Try to reserve a transmission task
taskNumber = mschReserveTask();
if (taskNumber == NO_TASK) {
mtxpReleasePacket(pPacket);
return RESOURCE_SHORTAGE;
}
#if MAC_OPT_SECURITY
if (securityEnable) {
txOptions |= TX_OPT_SECURITY_ENABLE;
}
#endif
// TX mode
pPacket->txMode = MTX_MODE_USE_CSMACA_BM;
pPacket->retriesLeft = aMaxFrameRetries;
// Generate the packet header (and find security material, if enabled)
if (mpib.macShortAddress >= 0xFFFE) {
msupPrepareHeader(pPacket, FT_MAC_COMMAND, (coordAddrMode << 2) | SRC_ADDR_EXT, mpib.macPANId, (ADDRESS*) &aExtendedAddress, coordPANId, pCoordAddress, txOptions);
} else {
msupPrepareHeader(pPacket, FT_MAC_COMMAND, (coordAddrMode << 2) | SRC_ADDR_SHORT, mpib.macPANId, (ADDRESS*) &mpib.macShortAddress, coordPANId, pCoordAddress, txOptions);
}
// Store the command type
pPacket->commandType = CMD_PAN_ID_CONFLICT_NOTIFICATION;
// Command frame identifier
pPayload = pPacket->pPayload;
*(pPayload++) = CMD_PAN_ID_CONFLICT_NOTIFICATION;
#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
if (pPacket->securitySuite >= 8) {
mtxpReleasePacket(pPacket);
mschReleaseTask(taskNumber);
return pPacket->securitySuite;
}
// Increment payload pointer when counters inserted
pPayload += temp;
// Include command payload length and optional MIC (integrity code) length
temp += CMD_DATA_REQUEST_PAYLOAD_LENGTH + pPacket->securitySetup.micLength;
#else
// No security material included, set MAC payload length
temp = CMD_PAN_ID_CONFLICT_NOTIFICATION_PAYLOAD_LENGTH;
#endif
// Set the packet length
pPacket->length = pPacket->headerLength + temp + MAC_FCS_LENGTH;
// No further packet payload
// Calculate the packet duration (including FCS)
pPacket->duration = msupCalcPacketDuration(pPacket->length, pPacket->txOptions);
// Initiate the transmission
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
return SUCCESS;
} // msupTransmitPanConflict
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -