📄 mac.c
字号:
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
// Dirty trick: Create another task to tell us when the transmission task has completed
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
waiting = TRUE;
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, msupWaitTask, (WORD) &waiting);
while (waiting);
}
// Set beacon and superframe order
firstBeaconNow = !GET_MF(MF_TRANSMIT_BEACON);
mlmeSetRequest(MAC_BEACON_ORDER, &beaconOrder);
if (beaconOrder == 15) {
mpib.macSuperframeOrder = 15;
CLEAR_MF(MF_TRANSMIT_BEACON);
// 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 CC2420 PAN coordinator bit
mdmctrl0 = 0x0AE2;
// 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 |= 0x1000;
} 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)
DISABLE_GLOBAL_INT();
FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0);
ENABLE_GLOBAL_INT();
// 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, 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
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.
//-------------------------------------------------------------------------------------------------------
void mlmeSyncRequest(UINT8 logicalChannel, BOOL trackBeacon) {
UINT8 taskNumber;
WORD taskData;
// 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
taskData = (((WORD) logicalChannel) << 8) | ((BYTE) trackBeacon);
mschAddTask(taskNumber, MAC_TASK_PRI_HIGH, mbcnSyncToBeacons, taskData);
}
} // 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 or 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?
//-------------------------------------------------------------------------------------------------------
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
//-------------------------------------------------------------------------------------------------------
MAC_ENUM mlmeScanRequest(BYTE scanType, DWORD scanChannels, UINT8 scanDuration, MAC_SCAN_RESULT *pScanResult) {
UINT8 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; // TBD: Remove this variable
mscInfo.scanChannels = scanChannels;
mscInfo.scanDuration = scanDuration;
mscInfo.pScanResult = pScanResult;
// Clear the complete flag
mscInfo.scanStatus = MSC_STATUS_ACTIVE;
///sprintf(str, "\n%d\n", scanTaskNumber);///
///UART_StartTx(str);///
///WDTE = 0xAC; ///
// Create the task that will perform the actual scanning
mschAddTask(scanTaskNumber, MAC_TASK_PRI_LOW, mscScanProcedure, 0);
///mscScanProcedure(0);///
///ENABLE_GLOBAL_INT();
///ENABLE_T3_COMPA_INT();
///CLEAR_T3_COMPA_INT();
///halWait(12000);///
///sprintf(str, "\r\n%ld\r\n", mtimInfo.bosCounter);
///sprintf(str, "\r\n%ld\r\n", test);///
///sprintf(str, "\r\n%ld\r\n", array1[0]);///
///UART_StartTx(str);///
///WDTE = 0xAC; ///
///sprintf(str, "\r\n%d\r\n", COMA);///
///UART_StartTx(str);///
/*
sprintf(&str[0], "\r\n%d\r\n", array1[0]);///
sprintf(&str[4], "\r\n%d\r\n", array1[1]);///
sprintf(&str[8], "\r\n%d\r\n", array1[2]);///
sprintf(&str[12], "\r\n%d\r\n", array1[3]);///
sprintf(&str[16], "\r\n%d\r\n", array1[4]);///
sprintf(&str[20], "\r\n%d\r\n", array1[5]);///
UART_StartTx(str);///
*/
///UART_StartTx("\r\n123456789\r\n>");
// Wait for the scan to complete
while (mscInfo.scanStatus == MSC_STATUS_ACTIVE);
UART_StartTx("\r\nYEAH\r\n>");
// 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(QWORD orphanAddress, WORD shortAddress, BOOL associatedMember, BOOL ...)
//
// DESCRIPTION:
// Respond to an orphan notification by transmitting a coordinator realignment frame.
//
// PARAMETERS:
// QWORD 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
void mlmeOrphanResponse(QWORD orphanAddress, WORD shortAddress, BOOL associatedMember, BOOL securityEnable) {
MAC_TX_PACKET *pPacket;
UINT8 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
//-------------------------------------------------------------------------------------------------------
MAC_ENUM mlmeSetRequest(MAC_PIB_ATTR pibAttribute, void *pPibAttributeValue) {
BOOL isBeaconEnabledPan = (mpib.macBeaconOrder < 15);
WORD pibAttributeValue;
// Store the word, not always used but saves memory space
pibAttributeValue = *((WORD*) pPibAttributeValue);
switch (pibAttribute) {
#if MAC_OPT_TRANSMIT_POWER
case PHY_TRANSMIT_POWER:
ppib.phyTransmitPower = *((UINT8*)pPibAttributeValue);
break;
#endif
// Category 1 attributes (read-only)
case MAC_ACK_WAIT_DURATION:
if ((UINT8) pibAttributeValue == 54) break;
return INVALID_PARAMETER;
case MAC_BATT_LIFE_EXT_PERIODS:
if ((UINT8) pibAttributeValue == 6) break;
return INVALID_PARAMETER;
case MAC_GTS_PERMIT:
case MAC_PROMISCUOUS_MODE:
if ((BOOL) pibAttributeValue == FALSE) break;
return INVALID_PARAMETER;
// Category 2 attributes (direct write)
case MAC_ASSOCIATION_PERMIT:
mpib.macAssociationPermit = (BOOL) pibAttributeValue;
break;
case MAC_AUTO_REQUEST:
mpib.macAutoRequest = (BOOL) pibAttributeValue;
break;
case MAC_BEACON_PAYLOAD_LENGTH:
if (((UINT8) pibAttributeValue) > aMaxBeaconPayloadLength) {
return INVALID_PARAMETER;
} else {
mpib.macBeaconPayloadLength = (UINT8) pibAttributeValue;
}
break;
case MAC_BSN:
mpib.macBSN = (UINT8) pibAttributeValue;
break;
case MAC_DSN:
mpib.macDSN = (UINT8) pibAttributeValue;
break;
case MAC_MAX_CSMA_BACKOFFS:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -