📄 mac_indirect_queue.c
字号:
} // miqFindAndRequestIndirectPacket
/*******************************************************************************************************
*******************************************************************************************************
************************** INDIRECT PACKET TRANSMISSION **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void miqSetRequested(MAC_TX_PACKET *pPacket, BOOL requested)
//
// DESCRIPTION:
// Requests or unrequests indirect packets. This function is responsible for creating the task that
// initiates the indirect packet transmission.
//
// ARGUMENTS:
// MAC_TX_PACKET *pPacket
// A pointer to the packet to be requested or unrequested
// BOOL requested
// TRUE if the packet should be flagged for transmission, FALSE if the flag is to be cleared
// (note that this .
//
// RETURN VALUE:
// BOOL
// A packet was found and flagged for transmission
//-------------------------------------------------------------------------------------------------------
ROOT void miqSetRequested(MAC_TX_PACKET *pPacket, BOOL requested) {
// Unrequested -> requested
if (requested && !pPacket->requested) {
if (pPacket->timeToLive > 0) {
// Create the transmission whn the first packet is requested
if (miqInfo.requestedCounter == 0) {
if (mschAddTask(mschReserveTask(), MAC_TASK_PRI_LOW, miqTransmitRequestedPackets, NULL)) {
pPacket->requested = TRUE;
miqInfo.requestedCounter++;
}
} else {
pPacket->requested = TRUE;
miqInfo.requestedCounter++;
}
}
// Requested -> unrequested
} else {
DISABLE_GLOBAL_INT();
if (!requested && pPacket->requested) {
miqInfo.requestedCounter--;
pPacket->requested = FALSE;
}
ENABLE_GLOBAL_INT();
}
} // miqSetRequested
//-------------------------------------------------------------------------------------------------------
// void miqUnrequestAll(void)
//
// DESCRIPTION:
// Unrequests all indirect packets
//-------------------------------------------------------------------------------------------------------
ROOT void miqUnrequestAll(void) {
UINT8 n;
for (n = 0; n < MAC_OPT_TX_POOL_SIZE; n++) {
miqSetRequested(&pMtxPacketPool[n], FALSE);
}
} // miqUnrequestAll
//-------------------------- -----------------------------------------------------------------------------
// void miqTransmitRequestedPackets(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task runs in a loop (reschedules itself), and creates the mtxScheduleTransmission tasks for
// requested indirect packets. The task dies when there are no more requested packets.
//
// TASK DAYA:
// 0
//-------------------------------------------------------------------------------------------------------
void miqTransmitRequestedPackets(MAC_TASK_INFO *pTask) NEAR {
UINT8 index;
MAC_TX_PACKET *pIndirectPacket;
if (miqInfo.requestedCounter) {
// Search for requested packets
index = miqInfo.firstIndirectPacket;
while (index != NO_PACKET) {
// Activate the current packet if it has been requested
pIndirectPacket = &pMtxPacketPool[index];
DISABLE_GLOBAL_INT();
if (pIndirectPacket->requested) {
pIndirectPacket->transmissionStarted = TRUE;
ENABLE_GLOBAL_INT();
// The requested bit should still be set, because it will be checked before the packet is transmitted
if (!mschAddTask(mschReserveTask(), MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pIndirectPacket)) {
pIndirectPacket->transmissionStarted = FALSE;
}
break;
}
ENABLE_GLOBAL_INT();
// Move on to the next packet
index = pIndirectPacket->nextPacket;
}
// Re-schedule this task, so that it runs in a loop while there are packets to be transmitted
mschRescheduleTask(pTask, 0);
} else {
ENABLE_GLOBAL_INT();
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
}
} // miqTransmitRequestedPackets
//-------------------------------------------------------------------------------------------------------
// void miqTransmitRequestedPackets(ADDRESS *pDestAddr, BOOL isExtAddr)
//
// DESCRIPTION:
// Transmits a packet with no payload as a response to a data request when there are no pending
// packets in the queue.
//
// ARGUMENTS:
// ADDRESS *pDestAddr
// The destination address of the packet
// BOOL isExtAddr
// TRUE if pDestAddr points to an extended address
//
// RETURN VALUE:
// BOOL
// The packet transmission has been initiated
//-------------------------------------------------------------------------------------------------------
ROOT BOOL miqTransmitNoDataPacket(ADDRESS *pDestAddr, BOOL isExtAddr) {
MAC_TX_PACKET *pPacket;
UINT8 taskNumber;
BYTE txOptions;
// Try to reserve a packet
pPacket = mtxpReservePacket();
if (!pPacket) return FALSE;
// Try to reserve a transmission task
taskNumber = mschReserveTask();
if (taskNumber == NO_TASK) {
mtxpReleasePacket(pPacket);
return FALSE;
}
// Set TX options
txOptions = TX_OPT_ACK_REQ;
#if MAC_OPT_SECURITY
//TBD: Include security here?
// if (securityEnable) {
// txOptions |= TX_OPT_SECURITY_ENABLE;
// }
#endif
// TX mode
pPacket->txMode = MTX_MODE_USE_CSMACA_BM | MTX_MODE_MAC_INTERNAL_BM;
pPacket->retriesLeft = 1;
// Generate the packet header (and find security material, if enabled)
if (mpib.macShortAddress >= 0xFFFE) {
msupPrepareHeader(pPacket, FT_DATA, (isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT) | SRC_ADDR_EXT, mpib.macPANId, (ADDRESS *) &aExtendedAddress, mpib.macPANId, pDestAddr, txOptions);
} else {
msupPrepareHeader(pPacket, FT_DATA, (isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT) | SRC_ADDR_SHORT, mpib.macPANId, (ADDRESS *) &mpib.macShortAddress, mpib.macPANId, pDestAddr, txOptions);
}
// Calculate and set the total packet length (TBD: will security ever be used / is it allowed by the spec?)
#if MAC_OPT_SECURITY
pPacket->length = pPacket->headerLength + pPacket->securitySetup.micLength + MAC_FCS_LENGTH;
#else
pPacket->length = pPacket->headerLength + MAC_FCS_LENGTH;
#endif
// Calculate the packet duration (including ack. and IFS)
pPacket->duration = msupCalcPacketDuration(pPacket->length, pPacket->txOptions & TX_OPT_ACK_REQ);
// Initiate the transmission
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
return TRUE;
} // miqTransmitNoDataPacket
/*******************************************************************************************************
*******************************************************************************************************
************************** INDIRECT PACKET EXPIRATION **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void miqDecrTimeToLive(void)
//
// DESCRIPTION:
// Decrements the "time to live" variable for all indirect packets, until it reaches zero
//-------------------------------------------------------------------------------------------------------
ROOT void miqDecrTimeToLive(void) {
UINT8 n;
for (n = 0; n < MAC_OPT_TX_POOL_SIZE; n++) {
DISABLE_GLOBAL_INT();
if (pMtxPacketPool[n].timeToLive > 0) pMtxPacketPool[n].timeToLive--;
ENABLE_GLOBAL_INT();
}
} // miqDecrTimeToLive
//-------------------------------------------------------------------------------------------------------
// void miqExpireIndirectPacketsTask(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// Expires indirect packets that have not been requested or taken into the TX engine. Only one
// packet will be expired for each round.
//
// TASK DATA:
// 0 (modified by the task)
//-------------------------------------------------------------------------------------------------------
void miqExpireIndirectPacketsTask(MAC_TASK_INFO *pTask) NEAR {
UINT8 index;
BOOL wasPurged;
UINT8 msduHandle;
MAC_TX_PACKET *pIndirectPacket;
// Skip the search state if we already have a pointer to a specific packet
if (pTask->taskData != NULL) pTask->state = MIQ_STATE_REMOVE_EXPIRED_PACKET;
switch (pTask->state) {
case MIQ_STATE_FIND_EXPIRED_PACKET:
index = miqInfo.firstIndirectPacket;
while (index != NO_PACKET) {
pIndirectPacket = &pMtxPacketPool[index];
// Purge packets with time no more time to live (unless they have been requested
DISABLE_GLOBAL_INT();
if (!pIndirectPacket->requested && (pIndirectPacket->timeToLive < 1)) {
pTask->taskData = (WORD) pIndirectPacket;
// pTask->state = MIQ_STATE_REMOVE_EXPIRED_PACKET is not required here (duplicate operation, see above)
ENABLE_GLOBAL_INT();
return;
}
ENABLE_GLOBAL_INT();
index = pIndirectPacket->nextPacket;
}
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
break;
case MIQ_STATE_REMOVE_EXPIRED_PACKET:
// The task data contains a pointer to the packet to be removed
pIndirectPacket = (MAC_TX_PACKET *) pTask->taskData;
// Only if the packet has not been requested, and is not already been taken into the TX engine...
if (!pIndirectPacket->requested && !pIndirectPacket->transmissionStarted) {
// Save the reason for the packet to be removed
wasPurged = pIndirectPacket->purgeRequest;
msduHandle = pIndirectPacket->msduHandle;
// Make the call to the higher layer
if (!wasPurged) {
if (pIndirectPacket->type == FT_DATA) {
mcpsDataConfirm(TRANSACTION_EXPIRED, msduHandle);
} else {
switch (pIndirectPacket->commandType) {
case CMD_ASSOCIATION_RESPONSE:
mtxCommStatusIndication(pIndirectPacket, TRANSACTION_EXPIRED);
break;
case CMD_DISASSOCIATION_NOTIFICATION:
mlmeDisassociateConfirm(TRANSACTION_EXPIRED);
break;
}
}
}
// Transform this task into a removal task
pTask->pTaskFunc = miqRemoveIndirectPacket;
pTask->state = 0;
} else {
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
}
break;
}
} // miqExpireIndirectPacketsTask
#endif // MAC_OPT_FFD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -