📄 mac.c
字号:
} while (taskNumber == NO_TASK);
waiting = TRUE;
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, msupWaitTask, (WORD) &waiting);
while (waiting);
}
// Set beacon and superframe order
firstBeaconNow = (BOOL)!GET_MF(MF_TRANSMIT_BEACON);
mlmeSetRequest(MAC_BEACON_ORDER, &beaconOrder);
if (beaconOrder == 15) {
mpib.macSuperframeOrder = 15;
CLEAR_MF(MF_TRANSMIT_BEACON);
firstBeaconNow = FALSE;
// Release task number and TX packet, if reserved
if (mbcnInfo.txTaskNumber != NO_TASK) {
mschReleaseTask(mbcnInfo.txTaskNumber);
mbcnInfo.txTaskNumber = NO_TASK;
}
if (mbcnInfo.pTxPacket != NULL) {
mtxpReleasePacket(mbcnInfo.pTxPacket);
mbcnInfo.pTxPacket = NULL;
}
} else {
mpib.macSuperframeOrder = superframeOrder;
}
// Prepare to modify the CC2430 PAN coordinator bit
mdmctrl0 = MDMCTRL0_NO_PAN_COORDINATOR;
// PAN coordinator?
if (panCoordinator) {
// Set the PAN ID
mlmeSetRequest(MAC_PAN_ID, &panId);
// Change the RF channel
msupSetChannel(logicalChannel, TRUE);
// Set PAN coordinator flags
SET_MF(MF_PAN_COORDINATOR);
mdmctrl0 |= PAN_COORDINATOR_BM;
} else {
// Just clear the flag
CLEAR_MF(MF_PAN_COORDINATOR);
}
// Set the coordinator flag (used in addition to the PAN coordinator flag)
SET_MF(MF_COORDINATOR);
// Set the MDMCTRL0.PAN_COORDINATOR bit (affects address regocnition)
WRITE_RFR16(MDMCTRL0, mdmctrl0);
// Other parameters
if (securityEnable) {
SET_MF(MF_BEACON_SECURITY);
} else {
CLEAR_MF(MF_BEACON_SECURITY);
}
// Set battery life extension
mlmeSetRequest(MAC_BATT_LIFE_EXT, &batteryLifeExtension);
// Beacon now?
if (beaconOrder == 15) {
mtimCancelCallback(mbcnExpirePacketsNonBeacon);
mtimSetCallback(mbcnExpirePacketsNonBeacon, (UINT32)(aBaseSuperframeDuration / aUnitBackoffPeriod));
} else if (firstBeaconNow) {
SET_MF(MF_TRANSMIT_BEACON);
// Reserve a task number and a TX packet
if (mbcnInfo.txTaskNumber == NO_TASK) mbcnInfo.txTaskNumber = mschReserveTask();
if (mbcnInfo.pTxPacket == NULL) mbcnInfo.pTxPacket = mtxpReservePacket();
// Start transmitting periodical beacons
T2_SET_OVERFLOW_COUNTER(msupCalcBeaconInterval() - MBCN_TX_STARTUP_OVERHEAD - MBCN_INITIAL_STARTUP_OVERHEAD);
mbcnTxPeriodicalBeacon ();
}
return SUCCESS;
}
} // mlmeStartRequest
#endif //MAC_OPT_FFD
//-------------------------------------------------------------------------------------------------------
// void mlmeSyncRequest(UINT8 logicalChannel, BOOL trackBeacon)
//
// DESCRIPTION:
// Switch to the selected channel, locate a single beacon, and start or stop tracking beacons
// (optional).
//
// PARAMETERS:
// UINT8 logicalChannel
// The channel to switch to.
// BOOL trackBeacon
// Track beacons if >0.
//-------------------------------------------------------------------------------------------------------
ROOT void mlmeSyncRequest(UINT8 logicalChannel, BOOL trackBeacon) {
BYTE taskNumber;
// Reserve a task if we are using beacon network.
if (mpib.macBeaconOrder != 15) {
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
// Create the task that will start the synchronization process
mschAddTask(taskNumber, MAC_TASK_PRI_HIGH, mbcnSyncToBeacons, (((WORD) logicalChannel) << 8) | ((BYTE) trackBeacon));
}
} // mlmeSyncRequest
//-------------------------------------------------------------------------------------------------------
// void mlmePollRequest(BYTE coordAddrMode, WORD coordPANId, ADDRESS *pCoordAddress, BOOL ...)
//
// DESCRIPTION:
// Poll indirect data from the coordinator
//
// PARAMETERS:
// BYTE coordAddrMode
// The coordinator address mode (AM_SHORT_16 | AM_EXTENDED_64)
// WORD coordPANId
// The PAN identifier of the coordinator
// ADDRESS *pCoordAddress
// A pointer to the coordinator address (short or extended)
// BOOL securityEnable
// Enable security for data-request command frame?
//-------------------------------------------------------------------------------------------------------
ROOT void mlmePollRequest(BYTE coordAddrMode, WORD coordPANId, ADDRESS *pCoordAddress, BOOL securityEnable) {
MAC_ENUM result;
// Force switch to manual polling mode
while (!macSetState(MAC_STATE_TX_MANUAL_DATA_REQUEST));
// Transmit the data request
do {
result = mipTransmitDataRequest(coordAddrMode, coordPANId, pCoordAddress, securityEnable);
} while (result == RESOURCE_SHORTAGE);
// Clean up if it failed
if (result != SUCCESS) macSetState(MAC_STATE_DEFAULT);
} // mlmePollRequest
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM mlmeScanRequest(BYTE scanType, DWORD scanChannels, UINT8 scanDuration)
//
// DESCRIPTION:
// Scan through the selected channels (energy, active, passive and orphan scanning supported).
// Important:
// - The maximum number of results returned for active and passive scans is
// defined by the MAC_OPT_MAX_PAN_DESCRIPTORS (>= 1) mac option
// - This function will not exit before the scan is completed.
//
// PARAMETERS:
// BYTE scanType
// ENERGY_SCAN, ACTIVE_SCAN, PASSIVE_SCAN or ORPHAN_SCAN
// DWORD scanChannels
// The channel index mask (0x07FFF800 are the legal values for 2.4 GHz channels)
// UINT8 scanDuration
// The scan duration defines the time spent scanning each channel, defined as:
// (aBaseSuperframeDuration * (2 ^^ scanDuration + 1)) symbol periods
// = (60 * 16 * (2^^scanDuration+1)) symbol periods
// E.g., scanning all 16 channels with Scanduration 5 takes 8.11 seconds
// MAC_SCAN_RESULT *pScanResult
// The pointer to the MAC_SCAN_RESULT struct (defined by the higher layer) where
// the MAC sublayer shall store the scan result.
//
// RETURN VALUE:
// MAC_ENUM
// INVALID_PARAMETER, SUCCESS or NO_BEACON
//-------------------------------------------------------------------------------------------------------
ROOT MAC_ENUM mlmeScanRequest(BYTE scanType,
DWORD scanChannels,
UINT8 scanDuration,
MAC_SCAN_RESULT *pScanResult)
{
BYTE scanTaskNumber;
// Set the scan type
pScanResult->scanType = scanType;
// Invalid parameters?
if ((scanType & 0xFC) || ((scanType != ORPHAN_SCAN) && (scanDuration > 14))) {
return INVALID_PARAMETER;
}
// Reserve the scanning task
do {
scanTaskNumber = mschReserveTask();
} while (scanTaskNumber == NO_TASK);
// Copy the scan parameters
mscInfo.scanType = scanType;
mscInfo.scanChannels = scanChannels;
mscInfo.scanDuration = scanDuration;
mscInfo.pScanResult = pScanResult;
// Clear the complete flag
mscInfo.scanStatus = MSC_STATUS_ACTIVE;
// Create the task that will perform the actual scanning
mschAddTask(scanTaskNumber, MAC_TASK_PRI_LOW, mscScanProcedure, NULL);
// Wait for the scan to complete
while (mscInfo.scanStatus == MSC_STATUS_ACTIVE);
// Return the result
if ((mscInfo.pScanResult->resultListSize != 0) || (scanType == ENERGY_SCAN) || ((scanType == ORPHAN_SCAN) && (mscInfo.scanStatus == MSC_STATUS_ORPHAN_REALIGNED))) {
return SUCCESS;
} else {
return NO_BEACON;
}
} // mlmeScanRequest
//-------------------------------------------------------------------------------------------------------
// void mlmeOrphanResponse(ADDRESS orphanAddress, WORD shortAddress, BOOL associatedMember, BOOL ...)
//
// DESCRIPTION:
// Respond to an orphan notification by transmitting a coordinator realignment frame.
//
// PARAMETERS:
// ADDRESS orphanAddress
// Extended address of the orphaned device
// WORD shortAddress
// The short address of the coordinator
// BOOL associatedMember
// This node is associated on this PAN
// Note: mlmeOrphanResponse is ignored if set to FALSE
// BOOL securityEnable
// Security is enabled for the coordinator realignment command frame?
//-------------------------------------------------------------------------------------------------------
#if MAC_OPT_FFD
ROOT void mlmeOrphanResponse(ADDRESS orphanAddress, WORD shortAddress, BOOL associatedMember, BOOL securityEnable) {
MAC_TX_PACKET *pPacket;
BYTE taskNumber;
// Ignore this response if the associatedMember field is FALSE
if (associatedMember) {
// Reserve a packet to use with the TX engine
do {
pPacket = mtxpReservePacket();
} while (!pPacket);
// Prepare the packet data
mbcnPrepareCoordinatorRealignment(pPacket, &orphanAddress, shortAddress, securityEnable, mpib.macPANId, ppib.phyCurrentChannel);
// Initiate the transmission
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
}
} // mlmeOrphanResponse
#endif // MAC_OPT_FFD
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM mlmeSetRequest(MAC_PIB_ATTR pibAttribute, void *pPibAttributeValue)
//
// DESCRIPTION:
// Set MAC PIB attribute.
//
// PARAMETERS:
// MAC_PIB_ATTR pibAttribute
// The attribute to be changed
// void *pPibAttributeValue
// A pointer to the PIB attribute. Note that this data is _copied_ into the PIB.
//
// RETURN VALUE:
// MAC_ENUM
// INVALID_PARAMETER, SUCCESS or UNSUPPORTED_ATTRIBUTE
//-------------------------------------------------------------------------------------------------------
ROOT MAC_ENUM mlmeSetRequest(MAC_PIB_ATTR pibAttribute, void *pPibAttributeValue) {
BOOL isBeaconEnabledPan;
// Store attribute as WORD
WORD pibAttributeValueW;
pibAttributeValueW = *((WORD *) pPibAttributeValue);
isBeaconEnabledPan = mpib.macBeaconOrder < 15;
switch (pibAttribute) {
case PHY_TRANSMIT_POWER:
ppib.phyTransmitPower = (UINT8)pibAttributeValueW;
break;
// Category 1 attributes (read-only)
case MAC_ACK_WAIT_DURATION:
if ((UINT8)pibAttributeValueW == 54) break;
return INVALID_PARAMETER;
case MAC_BATT_LIFE_EXT_PERIODS:
if ((UINT8)pibAttributeValueW == 6) break;
return INVALID_PARAMETER;
case MAC_GTS_PERMIT:
case MAC_PROMISCUOUS_MODE:
if ((BOOL)pibAttributeValueW == FALSE) break;
return INVALID_PARAMETER;
// Category 2 attributes (direct write)
case MAC_ASSOCIATION_PERMIT:
mpib.macAssociationPermit = (BOOL)pibAttributeValueW;
break;
case MAC_AUTO_REQUEST:
mpib.macAutoRequest = (BOOL)pibAttributeValueW;
break;
case MAC_BEACON_PAYLOAD_LENGTH:
if ((UINT8)pibAttributeValueW > aMaxBeaconPayloadLength) {
return INVALID_PARAMETER;
} else {
mpib.macBeaconPayloadLength = (UINT8)pibAttributeValueW;
}
break;
case MAC_BSN:
mpib.macBSN = (UINT8)pibAttributeValueW;
break;
case MAC_DSN:
mpib.macDSN = (UINT8)pibAttributeValueW;
break;
case MAC_MAX_CSMA_BACKOFFS:
if ((UINT8)pibAttributeValueW > 5) {
return INVALID_PARAMETER;
} else {
mpib.macMaxCsmaBackoffs = (UINT8)pibAttributeValueW;
}
break;
case MAC_MIN_BE:
if ((UINT8)pibAttributeValueW > 3) {
return INVALID_PARAMETER;
} else {
mpib.macMinBE = (UINT8)pibAttributeValueW;
}
break;
case MAC_ASSOCIATED_PAN_CORDINATOR:
mpib.macAssociatedPanCordinator = (BOOL)pibAttributeValueW;
break;
// Category 3 attributes (disable interrupts)
case MAC_BEACON_PAYLOAD:
DISABLE_GLOBAL_INT();
mpib.pMacBeaconPayload = (BYTE *) pPibAttributeValue;
ENABLE_GLOBAL_INT();
break;
case MAC_BEACON_TX_TIME:
DISABLE_GLOBAL_INT();
memcpy(&mpib.macBeaconTxTime, (BYTE *) pPibAttributeValue, sizeof(mpib.macBeaconTxTime));
ENABLE_GLOBAL_INT();
break;
case MAC_COORD_EXTENDED_ADDRESS:
DISABLE_GLOBAL_INT();
memcpy(&mpib.pMacCoordExtendedAddress, (BYTE *) pPibAttributeValue, sizeof(mpib.pMacCoordExtendedAddress));
ENABLE_GLOBAL_INT();
break;
case MAC_COORD_SHORT_ADDRESS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -