📄 mac.c
字号:
// Increment payload pointer when counters inserted
pPayload += temp;
// Include command payload length and optional MIC (integrity code) length
temp += CMD_ASSOCIATION_REQUEST_PAYLOAD_LENGTH + pPacket->securitySetup.micLength;
#else
// No security material included, set MAC payload length
temp = CMD_ASSOCIATION_REQUEST_PAYLOAD_LENGTH;
#endif
// Set the packet length (two bytes of payload)
pPacket->length = (BYTE)(pPacket->headerLength + temp + MAC_FCS_LENGTH);
// Generate the payload
*(pPayload++) = capabilityInformation;
// Calculate the packet duration
pPacket->duration = msupCalcPacketDuration(pPacket->length, TRUE);
// Reserve the transmission task
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
// Initiate the transmission
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
} // mlmeAssociateRequest
//-------------------------------------------------------------------------------------------------------
// void mlmeAssociateResponse(ADDRESS *pDeviceAddress, WORD assocShortAddress, MAC_ENUM status, ...
//
// DESCRIPTION:
// Used by a ccordinator to respond to an association indication. The response is placed in the
// indirect transmission queue.
// Generates a mlmeCommStatusIndication callback upon completion
//
// PARAMETERS:
// ADDRESS *pDeviceAddress
// Pointer to the extended address of the associated device
// WORD assocShortAddress
// The assigned short address
// MAC_ENUM status
// The association status
// BOOL securityEnable
// Security is enabled?
//-------------------------------------------------------------------------------------------------------
#if MAC_OPT_FFD
ROOT void mlmeAssociateResponse(ADDRESS *pDeviceAddress, WORD assocShortAddress, MAC_ENUM status,
BOOL securityEnable) {
MAC_TX_PACKET *pPacket;
BYTE txOptions;
UINT8 temp;
BYTE *pPayload;
MAC_ENUM commStatusError;
BYTE taskNumber;
securityEnable = FALSE;
if (securityEnable == TRUE)
securityEnable = FALSE;
// Reserve an indirect packet to use with the TX engine
pPacket = mtxpReservePacket();
if (!pPacket) {
commStatusError = TRANSACTION_OVERFLOW;
mlmeCommStatusIndication(mpib.macPANId, AM_EXTENDED_64, (ADDRESS *) &aExtendedAddress,
AM_EXTENDED_64, pDeviceAddress, commStatusError);
return;
}
// TX mode
pPacket->txMode = MTX_MODE_USE_CSMACA_BM;
pPacket->retriesLeft = aMaxFrameRetries;
// Set TX options
txOptions = TX_OPT_ACK_REQ | TX_OPT_INDIRECT;
#if MAC_OPT_SECURITY
if (securityEnable) txOptions |= TX_OPT_SECURITY_ENABLE;
#endif
// Generate the packet header
msupPrepareHeader(pPacket, FT_MAC_COMMAND, DEST_ADDR_EXT | SRC_ADDR_EXT, mpib.macPANId,
(ADDRESS *) &aExtendedAddress, mpib.macPANId, pDeviceAddress, txOptions);
// Store the command type
pPacket->commandType = CMD_ASSOCIATION_RESPONSE;
// Command frame identifier
pPayload = pPacket->pPayload;
*(pPayload++) = CMD_ASSOCIATION_RESPONSE;
#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) {
commStatusError = pPacket->securitySuite;
mtxpReleasePacket(pPacket);
mlmeCommStatusIndication(mpib.macPANId, AM_EXTENDED_64, (ADDRESS *) &aExtendedAddress,
AM_EXTENDED_64, pDeviceAddress, commStatusError);
return;
}
// Increment payload pointer when counters inserted
pPayload += temp;
// Include command payload length and optional MIC (integrity code) length
temp += CMD_ASSOCIATION_RESPONSE_PAYLOAD_LENGTH + pPacket->securitySetup.micLength;
#else
// No security material included, set MAC payload length
temp = CMD_ASSOCIATION_RESPONSE_PAYLOAD_LENGTH;
#endif
// Set the packet length (four bytes of payload)
pPacket->length = pPacket->headerLength + temp + MAC_FCS_LENGTH;
// Generate the payload
*(pPayload++) = (BYTE) assocShortAddress;
*(pPayload++) = (BYTE) ((assocShortAddress & 0xFF00) >> 8);
*(pPayload++) = (BYTE) status;
// Calculate the packet duration
pPacket->duration = msupCalcPacketDuration(pPacket->length, TRUE);
// Initiate the transmission
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
mschAddTask(taskNumber, MAC_TASK_PRI_MEDIUM, miqAddIndirectPacket, (WORD) pPacket);
} // mlmeAssociateResponse
#endif // MAC_OPT_FFD
//-------------------------------------------------------------------------------------------------------
// void mlmeDisassociateRequest(ADDRESS *pDeviceAddress, BYTE disassociateReason, BOOL securityEnable)
//
// DESCRIPTION:
// Used by an associated device to notify the coordinator of its intent to leave the PAN or
// used by the coordinator to instruct an associated device to leave the PAN. pDeviceAddress is a
// pointer to the extended address of the device to which to send the disassociation notification
// command.
//
// PARAMETERS:
// ADDRESS *pDeviceAddress
// For coordinators: A pointer to the extended address of the device to disassociate
// For devices: A pointer to the extended address of coordinator
// BYTE disassociateReason
// The disassociate reason (COORD_WISHES_DEVICE_TO_LEAVE | DEVICE_WISHES_TO_LEAVE)
// BOOL securityEnable
// Security is enabled?
//-------------------------------------------------------------------------------------------------------
ROOT void mlmeDisassociateRequest(ADDRESS *pDeviceAddress, BYTE disassociateReason, BOOL securityEnable) {
MAC_TX_PACKET *pPacket;
BYTE txOptions;
UINT8 temp;
BYTE *pPayload;
BYTE taskNumber;
// Set TX options
txOptions = TX_OPT_ACK_REQ;
#if MAC_OPT_SECURITY
if (securityEnable) {
txOptions |= TX_OPT_SECURITY_ENABLE;
}
#else
// Only added to avoid compiler warnings
if (securityEnable == TRUE)
temp = securityEnable;
#endif
// Device -> Coordinator: Use direct transmission
if (msupCompareExtendedAddress((ADDRESS *) mpib.pMacCoordExtendedAddress, pDeviceAddress)) {
// Reserve the packet to be used
do {
pPacket = mtxpReservePacket();
} while (pPacket == NULL);
} else {
#if MAC_OPT_FFD
// Coordinator -> Device: Use indirect transmission
if (GET_MF(MF_COORDINATOR)) {
// Start by trying to reserve a TX packet
pPacket = mtxpReservePacket();
if (!pPacket) {
mlmeDisassociateConfirm(TRANSACTION_OVERFLOW);
return;
}
// Set the indirect transmission flag
txOptions |= TX_OPT_INDIRECT;
// Device -> Device: Error
} else {
mlmeDisassociateConfirm(INVALID_PARAMETER);
return;
}
#else // RFD
mlmeDisassociateConfirm(INVALID_PARAMETER);
return;
#endif
}
// Set transmission mode
pPacket->txMode = MTX_MODE_USE_CSMACA_BM;
pPacket->retriesLeft = aMaxFrameRetries;
// Generate the packet header
msupPrepareHeader(pPacket, FT_MAC_COMMAND, (DEST_ADDR_EXT | SRC_ADDR_EXT),
mpib.macPANId, (ADDRESS *) &aExtendedAddress, mpib.macPANId,
(ADDRESS *) pDeviceAddress, txOptions);
// Store the command type
pPacket->commandType = CMD_DISASSOCIATION_NOTIFICATION;
// Command frame identifier
pPayload = pPacket->pPayload;
*(pPayload++) = CMD_DISASSOCIATION_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);
mlmeDisassociateConfirm(pPacket->securitySuite);
return;
}
// Increment payload pointer when counters inserted
pPayload += temp;
// Include command payload length and optional MIC (integrity code) length
temp += CMD_DISASSOCIATION_NOTIFICATION_PAYLOAD_LENGTH + pPacket->securitySetup.micLength;
#else
// No security material included, set MAC payload length
temp = CMD_DISASSOCIATION_NOTIFICATION_PAYLOAD_LENGTH;
#endif
// Set the packet length (two bytes of payload)
pPacket->length = pPacket->headerLength + temp + MAC_FCS_LENGTH;
// Generate the payload
*(pPayload++) = (BYTE) disassociateReason;
// Calculate the packet duration
pPacket->duration = msupCalcPacketDuration(pPacket->length, TRUE);
// Initiate the transmission
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
#if MAC_OPT_FFD
if (txOptions & TX_OPT_INDIRECT) {
mschAddTask(taskNumber, MAC_TASK_PRI_MEDIUM, miqAddIndirectPacket, (WORD) pPacket);
} else {
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
}
#else
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
#endif // MAC_OPT_FFD
} // mlmeDisassociateRequest
//-------------------------------------------------------------------------------------------------------
// void mlmeRxEnableRequest(BOOL deferPermit, UINT32 rxOnTime, UINT32 rxOnDuration)
//
// DESCRIPTION:
// Enable the receiver for after a given timeout (in symbols), and turn it off after the given
// duration (also in symbols). An rxOnDuration = 0 will immediately shut down the receiver.
// Note: Do NOT use on beacon networks, set RX_ON_WHEN_IDLE to TRUE in stead
//
// PARAMETERS:
// BOOL deferPermit
// Reception can be deferred until the next superframe
// UINT32 rxOnTime
// The number of symbols to elapse before the receiver should be turned on
// UINT32 rxOnDuration
// The number of symbols to listen before turning the receiver off
//-------------------------------------------------------------------------------------------------------
ROOT void mlmeRxEnableRequest(BOOL deferPermit, UINT32 rxOnTime, UINT32 rxOnDuration) {
BYTE taskNumber;
// Store the time values for use by the task
mrxInfo.rxEnableOnDuration = (rxOnDuration + (aUnitBackoffPeriod - 1)) / aUnitBackoffPeriod;
do {
taskNumber = mschReserveTask();
} while (taskNumber == NO_TASK);
while (!mschAddTask(taskNumber, MAC_TASK_PRI_MEDIUM, mrxRxEnableRequestTask, NULL));
} // mlmeRxEnableRequest
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM mcpsPurgeRequest(BYTE msduHandle)
//
// DESCRIPTION:
// Purge data frames from the indirect data transmission queue
//
// PARAMETERS:
// BYTE msduHandle
// The packet handle (from mcpsDataRequest(...))
//
// RETURN VALUE:
// MAC_ENUM
// SUCCESS: OK
// INVALID_HANDLE: The packet could not be found (already transmitted?)
//-------------------------------------------------------------------------------------------------------
#if MAC_OPT_FFD
ROOT MAC_ENUM mcpsPurgeRequest(BYTE msduHandle) {
UINT8 packetIndex;
MAC_TX_PACKET *pIndirectPacket;
// For each packet in the queue ...
restart:
packetIndex = miqInfo.firstIndirectPacket;
while (packetIndex != NO_PACKET) {
pIndirectPacket = &pMtxPacketPool[packetIndex];
// If there's a match on the MSDU handle
if ((pIndirectPacket->msduHandle == msduHandle) && (pIndirectPacket->type == FT_DATA)) {
// Just wait if the packet has been requested (we shouldn't interfere with the transmission)
if (pIndirectPacket->requested) {
goto restart;
} else {
pIndirectPacket->purgeRequest = TRUE;
pIndirectPacket->timeToLive = MIQ_PACKET_PURGED;
mschAddTask(mschReserveTask(), MAC_TASK_PRI_MEDIUM, miqExpireIndirectPacketsTask, (WORD) pIndirectPacket);
return SUCCESS;
}
}
// Move to the next packet in the queue
packetIndex = pIndirectPacket->nextPacket;
}
return INVALID_HANDLE;
} // mcpsPurgeRequest
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -