📄 mac_indirect_queue.c
字号:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY *
* *** + + *** Indirect Packet Queue + Related *
* *** +++ *** *
* *** *** *
* ************ *
* ********** *
* *
*******************************************************************************************************
* CONFIDENTIAL *
* The use of this file is restricted by the signed MAC software license agreement. *
* *
* Copyright Chipcon AS, 2005 *
*******************************************************************************************************
* This module contains functions related to the indirect packet queue (on coordinators), including *
* queue management, transmission initiation, expiration, and other functions. *
*******************************************************************************************************/
#include <mac_headers.h>
#if MAC_OPT_FFD
//-------------------------------------------------------------------------------------------------------
// Variables related to the indirect packet queue
__no_init MAC_INDIRECT_QUEUE_INFO miqInfo @ "PM0_XDATA";
//-------------------------------------------------------------------------------------------------------
/*******************************************************************************************************
*******************************************************************************************************
************************** QUEUE MANAGEMENT **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void miqInit(void)
//
// DESCRIPTION:
// Initializes the indirect packet queue
//-------------------------------------------------------------------------------------------------------
ROOT void miqInit(void) {
miqInfo.firstIndirectPacket = NO_PACKET;
miqInfo.lastIndirectPacket = NO_PACKET;
miqInfo.requestedCounter = 0;
} // miqInit
//-------------------------------------------------------------------------------------------------------
// void miqAddIndirectPacket(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task adds a packet to the indirect queue.
//
// TASK DATA:
// A pointer to the MAC_TX_PACKET to be added
//-------------------------------------------------------------------------------------------------------
void miqAddIndirectPacket(MAC_TASK_INFO *pTask) NEAR {
MAC_TX_PACKET *pPacket = (MAC_TX_PACKET *) pTask->taskData;
MAC_TX_PACKET *pIndirectPacket;
UINT8 temp;
BYTE destAddrMode;
ADDRESS *pDestAddr;
switch (pTask->state) {
case MIQ_STATE_FIND_FIRST_PACKET_FROM_NODE:
// Start by determining whether or not this is the first indirect packet to this node.
pPacket->isFirstPacket = TRUE;
destAddrMode = (BYTE)(pPacket->pHeader[1] & DEST_ADDR_BM);
pDestAddr = (ADDRESS*) (pPacket->pHeader + 5);
// Go through the whole packet queue, and clear the isFirstPacket flag if a match is found
temp = miqInfo.firstIndirectPacket;
while (temp != NO_PACKET) {
pIndirectPacket = &pMtxPacketPool[temp];
if (destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM)) {
if (destAddrMode == DEST_ADDR_SHORT) {
if (pDestAddr->Short == *((WORD *) (pIndirectPacket->pHeader + 5))) {
pPacket->isFirstPacket = FALSE;
break;
}
} else {
if (msupCompareExtendedAddress((ADDRESS *) pDestAddr, (ADDRESS *) (pIndirectPacket->pHeader + 5))) {
pPacket->isFirstPacket = FALSE;
break;
}
}
}
temp = pIndirectPacket->nextPacket;
}
pTask->state = MIQ_STATE_INSERT_INTO_QUEUE;
break;
case MIQ_STATE_INSERT_INTO_QUEUE:
// Find the index of the new packet
temp = pPacket->poolIndex;
// Add the packet to the queue
if (miqInfo.lastIndirectPacket != NO_PACKET)
pMtxPacketPool[miqInfo.lastIndirectPacket].nextPacket = temp;
pPacket->prevPacket = miqInfo.lastIndirectPacket;
pPacket->nextPacket = NO_PACKET;
pPacket->timeToLive = mpib.macTransactionPersistenceTime;
pPacket->purgeRequest = FALSE;
pPacket->requested = FALSE;
pPacket->transmissionStarted = FALSE;
// Update the global indexes
miqInfo.lastIndirectPacket = temp;
if (miqInfo.firstIndirectPacket == NO_PACKET) miqInfo.firstIndirectPacket = temp;
// Remove the task
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
break;
}
} // miqAddIndirectPacket
//-------------------------------------------------------------------------------------------------------
// void miqRemoveIndirectPacket(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task removes a packet from the indirect queue. Note that the "requested flag" must have been
// cleared before this task is created. To make sure that the packet is not requested again before
// this task completes, the timeToLive counter should be set to < 1.
//
// TASK DATA:
// A pointer to the MAC_TX_PACKET to be removed.
//-------------------------------------------------------------------------------------------------------
void miqRemoveIndirectPacket(MAC_TASK_INFO *pTask) NEAR {
MAC_TX_PACKET *pPacket = (MAC_TX_PACKET *) pTask->taskData;
MAC_TX_PACKET *pIndirectPacket;
BYTE temp;
BYTE destAddrMode;
ADDRESS *pDestAddr;
switch (pTask->state) {
case MIQ_STATE_REMOVE_PACKET:
// Update the link on the previous packet
if (pPacket->prevPacket != NO_PACKET) {
pMtxPacketPool[pPacket->prevPacket].nextPacket = pPacket->nextPacket;
}
// Update the link on the next packet
if (pPacket->nextPacket != NO_PACKET) {
pMtxPacketPool[pPacket->nextPacket].prevPacket = pPacket->prevPacket;
}
// Update the "head" and "tail" indexes of the queue
temp = pPacket->poolIndex;
if (temp == miqInfo.firstIndirectPacket) miqInfo.firstIndirectPacket = pPacket->nextPacket;
if (temp == miqInfo.lastIndirectPacket) miqInfo.lastIndirectPacket = pPacket->prevPacket;
pTask->state = MIQ_STATE_MOVE_FIRST_PACKET_FLAG;
break;
case MIQ_STATE_MOVE_FIRST_PACKET_FLAG:
// If set here, then move the isFirstPacket flag to the next packet with same destination in the queue
if (pPacket->isFirstPacket) {
pPacket->isFirstPacket = FALSE;
temp = pPacket->nextPacket;
destAddrMode = (BYTE)(pPacket->pHeader[1] & DEST_ADDR_BM);
pDestAddr = (ADDRESS *) (pPacket->pHeader + 5);
// For each packet in the queue ...
while (temp != NO_PACKET) {
pIndirectPacket = &pMtxPacketPool[temp];
if (destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM)) {
if (destAddrMode == DEST_ADDR_SHORT) {
if (pDestAddr->Short == *((WORD *) (pIndirectPacket->pHeader + 5))) {
pIndirectPacket->isFirstPacket = TRUE;
break;
}
} else {
if (msupCompareExtendedAddress((ADDRESS *) pDestAddr, (ADDRESS *) (pIndirectPacket->pHeader + 5))) {
pIndirectPacket->isFirstPacket = TRUE;
break;
}
}
}
temp = pIndirectPacket->nextPacket;
}
}
// Clean up
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
mtxpReleasePacket(pPacket);
break;
}
} // miqRemoveIndirectPacket
//-------------------------------------------------------------------------------------------------------
// BOOL miqFindIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr)
//
// DESCRIPTION:
// Searches through the indirect packet queue for a match on the given address.
//
// ARGUMENTS:
// ADDRESS *pDestAddr
// A pointer to the address to search for
// BOOL isExtAddr
// TRUE if pDestAddr points to an extended address
//
// RETURN VALUE:
// MAC_TX_PACKET
// A packet was found a packet pointer is returned, if no packet is found NULL is returned
//-------------------------------------------------------------------------------------------------------
ROOT MAC_TX_PACKET *miqFindIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr) {
UINT8 temp;
BYTE destAddrMode = isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT;
MAC_TX_PACKET *pIndirectPacket;
// For each packet in the queue ...
temp = miqInfo.firstIndirectPacket;
while (temp != NO_PACKET) {
pIndirectPacket = &pMtxPacketPool[temp];
// ... return the packet index if there's a match on the address mode ...
if ((destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM)) && (pIndirectPacket->transmissionStarted != TRUE)) {
// ... and the address itself
if (destAddrMode == DEST_ADDR_SHORT) {
if (pDestAddr->Short == *((WORD *) (pIndirectPacket->pHeader + 5))) {
return pIndirectPacket;
}
} else {
if (msupCompareExtendedAddress((ADDRESS *) pDestAddr, (ADDRESS *) (pIndirectPacket->pHeader + 5))) {
return pIndirectPacket;
}
}
}
// Move to the next packet in the queue
temp = pIndirectPacket->nextPacket;
}
// Could not find any match
return NULL;
} // miqFindIndirectPacket
//-------------------------------------------------------------------------------------------------------
// BOOL miqFindAndRequestIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr)
//
// DESCRIPTION:
// Searches through the indirect packet queue for a match on the given address. If successful, the
// found packet will be requested, and transmitted ASAP.
//
// ARGUMENTS:
// ADDRESS *pDestAddr
// A pointer to the address to search for
// BOOL isExtAddr
// TRUE if pDestAddr points to an extended address
//
// RETURN VALUE:
// BOOL
// A packet was found and flagged for transmission
//-------------------------------------------------------------------------------------------------------
ROOT BOOL miqFindAndRequestIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr) {
UINT8 temp;
BYTE destAddrMode;
MAC_TX_PACKET *pIndirectPacket;
destAddrMode = (BYTE)(isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT);
// For each packet in the queue ...
temp = miqInfo.firstIndirectPacket;
while (temp != NO_PACKET) {
pIndirectPacket = &pMtxPacketPool[temp];
// ... return the packet index if there's a match on the address mode ...
if (destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM))
{
// ... and the address itself
if (destAddrMode == DEST_ADDR_SHORT) {
if (pDestAddr->Short == *((WORD *) &pIndirectPacket->pHeader[5])) {
miqSetRequested(pIndirectPacket, TRUE);
return TRUE;
}
} else {
if (msupCompareExtendedAddress(pDestAddr, (ADDRESS *) (pIndirectPacket->pHeader + 5))) {
miqSetRequested(pIndirectPacket, TRUE);
return TRUE;
}
}
}
// Move to the next packet in the queue
temp = pIndirectPacket->nextPacket;
}
// Could not find any match (should reply to the data request with a zero-length data packet)
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -