?? mac_indirect_polling.c
字號:
/*******************************************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY *
* *** + + *** Indirect Packet Polling + 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 indirect packet polling, including packet formatting and *
* timeouts. *
*******************************************************************************************************/
#include <mac_headers.h>
/*******************************************************************************************************
*******************************************************************************************************
************************** COMMON POLLING FUNCTIONS **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void mipTransmitAutoDataRequest(void)
//
// DESCRIPTION:
// Tranmits an automatic data request when the address of the device has appeared in the beacon
// pending list, and mpib.macAutoRequest has been set (the default value is TRUE). This kind of
// data request does not make any callbacks to the higher layer (mlmePollConfirm).
//-------------------------------------------------------------------------------------------------------
ROOT void mipTransmitAutoDataRequest(void) {
MAC_ENUM result;
BOOL securityEnable = FALSE; // TBD...
// Switch to automatic polling mode
if (!macSetState(MAC_STATE_TX_AUTO_DATA_REQUEST)) return;
// Try to transmit the data request
if (mpib.macCoordShortAddress < 0xFFFE) {
result = mipTransmitDataRequest(AM_SHORT_16, mpib.macPANId, (ADDRESS *) &mpib.macCoordShortAddress, securityEnable);
} else {
result = mipTransmitDataRequest(AM_EXTENDED_64, mpib.macPANId, (ADDRESS *) mpib.pMacCoordExtendedAddress, securityEnable);
}
// Clean up if it failed
if (result != SUCCESS) macSetState(MAC_STATE_DEFAULT);
} // mipTransmitAutoDataRequest
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM mipTransmitDataRequest(BYTE coordAddrMode, WORD coordPANId, ADDRESS *pCoordAddress, BOOL ...)
//
// DESCRIPTION:
// Transmits a data request packet.
//
// ARGUMENTS:
// BYTE coordAddrMode
// The address mode used by the coordinator
// WORD coordPANId
// The PAN ID used by the coordinator
// ADDRESS *pCoordAddress
// A pointer to the coordinator address (taken from the MAC PIB, short or extended)
// BOOL securityEnable
// TBD...
//
// RETURN VALUE:
// MAC_ENUM
// SUCCESS No error (the transmission was initiated)
// RESOURCE_SHORTAGE TX packet or task not available
// UNAVAILABLE_KEY No key
// FAILED_SECURITY_CHECK Failed security check
//-------------------------------------------------------------------------------------------------------
ROOT MAC_ENUM mipTransmitDataRequest(BYTE coordAddrMode, WORD coordPANId, ADDRESS *pCoordAddress, BOOL securityEnable) {
MAC_TX_PACKET *pPacket;
UINT8 taskNumber;
BYTE txOptions;
UINT8 temp;
BYTE *pPayload;
// Try to reserve a packet
pPacket = mtxpReservePacket();
if (!pPacket) return RESOURCE_SHORTAGE;
// Try to reserve a transmission task
taskNumber = mschReserveTask();
if (taskNumber == NO_TASK) {
mtxpReleasePacket(pPacket);
return RESOURCE_SHORTAGE;
}
// Set TX options
txOptions = TX_OPT_ACK_REQ;
#if MAC_OPT_SECURITY
if (securityEnable) {
txOptions |= TX_OPT_SECURITY_ENABLE;
}
#endif
// TX mode
pPacket->txMode = MTX_MODE_USE_CSMACA_BM;
pPacket->retriesLeft = aMaxFrameRetries;
// Generate the packet header (and find security material, if enabled)
if (mpib.macShortAddress >= 0xFFFE) {
msupPrepareHeader(pPacket, FT_MAC_COMMAND, (coordAddrMode << 2) | SRC_ADDR_EXT, mpib.macPANId, (ADDRESS *) &aExtendedAddress, coordPANId, pCoordAddress, (BYTE)txOptions);
} else {
msupPrepareHeader(pPacket, FT_MAC_COMMAND, (coordAddrMode << 2) | SRC_ADDR_SHORT, mpib.macPANId, (ADDRESS *) &mpib.macShortAddress, coordPANId, pCoordAddress, txOptions);
}
// Store the command type
pPacket->commandType = CMD_DATA_REQUEST;
// Command frame identifier
pPayload = pPacket->pPayload;
*(pPayload++) = CMD_DATA_REQUEST;
#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);
mschReleaseTask(taskNumber);
return pPacket->securitySuite;
}
// Increment payload pointer when counters inserted
pPayload += temp;
// Include command payload length and optional MIC (integrity code) length
temp += CMD_DATA_REQUEST_PAYLOAD_LENGTH + pPacket->securitySetup.micLength;
#else
// No security material included, set MAC payload length
temp = CMD_DATA_REQUEST_PAYLOAD_LENGTH;
#endif
// Set the packet length
pPacket->length = pPacket->headerLength + temp + MAC_FCS_LENGTH;
// No further packet payload
// Calculate the packet duration (including ack. and FCS)
pPacket->duration = msupCalcPacketDuration(pPacket->length, pPacket->txOptions & TX_OPT_ACK_REQ);
// Initiate the transmission
mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);
return SUCCESS;
} // mipTransmitDataRequest
/*******************************************************************************************************
*******************************************************************************************************
************************** DATA REQUEST TIMEOUT **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// void mipDataRequestTimeoutTask(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task is run when no valid response has been received after a data request. The task makes
// the callback to the higher layer.
//
// TASK DATA:
// 0
//-------------------------------------------------------------------------------------------------------
void mipDataRequestTimeoutTask(MAC_TASK_INFO *pTask) NEAR {
MAC_STATE_TYPE oldState;
// The data request has failed, so stop listening
mrxDecrOnCounter();
oldState = macInfo.state;
macSetState(MAC_STATE_DEFAULT);
// Remove the task
mschRemoveTask(pTask->priority, 0);
// Notify the higher layer...
switch (oldState) {
case MAC_STATE_MANUAL_DATA_REQUEST_SENT: mlmePollConfirm(NO_DATA); break;
case MAC_STATE_ASSOC_DATA_REQUEST_SENT: mlmeAssociateConfirm(0xFFFF, NO_DATA); break;
default: break;
}
} // mipDataRequestTimeoutTask
//-------------------------------------------------------------------------------------------------------
// void mipDataRequestTimeout(void)
//
// DESCRIPTION:
// This timeout will occur when no response has been received after a data request.
//-------------------------------------------------------------------------------------------------------
void mipDataRequestTimeout(void) NEAR {
if (!mschAddTask(mschReserveTask(), MAC_TASK_PRI_HIGH, mipDataRequestTimeoutTask, 0)) {
mtimSetCallback(mipDataRequestTimeout, 10);
}
} // mipDataRequestTimeout
//-------------------------------------------------------------------------------------------------------
// MAC_STATE_TYPE mipCancelDataRequestTimeout(void)
//
// DESCRIPTION:
// Cancels the data request timeout. This function should be used when a valid or invalid "indirect
// packet" has been received. The MAC state is set back to the default state.
//
// RETURN VALUE:
// MAC_STATE_TYPE
// The MAC state before resetting it to MAC_STATE_DEFAULT
//-------------------------------------------------------------------------------------------------------
MAC_STATE_TYPE mipCancelDataRequestTimeout(void) NEAR {
MAC_STATE_TYPE macState = MAC_STATE_DEFAULT;
if (mtimCancelCallback(mipDataRequestTimeout)) {
mrxDecrOnCounter();
DISABLE_GLOBAL_INT();
macState = macInfo.state;
macSetState(MAC_STATE_DEFAULT);
ENABLE_GLOBAL_INT();
}
return macState;
} // mipCancelDataRequestTimeout
/*******************************************************************************************************
*******************************************************************************************************
************************** ASSOCIATION RESPONSE POLLING **************************
*******************************************************************************************************
*******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
// MAC_ENUM mipTransmitAssocDataRequest(void)
//
// DESCRIPTION:
// Tranmits an the data request packet that follows a successful association request packet. This
// packet is transmitted when the data is indicated in the beacon pending list, or the response
// time has passed.
//
// RETURN VALUE:
// BOOL
// The association request was transmitted
//-------------------------------------------------------------------------------------------------------
ROOT MAC_ENUM mipTransmitAssocDataRequest(void) {
BOOL securityEnable;
#if MAC_OPT_SECURITY
securityEnable = GET_MF(MF_SECURE_ASSOC);
#else
securityEnable = FALSE;
#endif
// Set automatic polling mode
if (!macSetState(MAC_STATE_TX_ASSOC_DATA_REQUEST)) return SUCCESS;
// Transmit the data request
if (mpib.macCoordShortAddress < 0xFFFE) {
return mipTransmitDataRequest(AM_SHORT_16, mpib.macPANId, (ADDRESS *) &mpib.macCoordShortAddress, securityEnable);
} else {
return mipTransmitDataRequest(AM_EXTENDED_64, mpib.macPANId, (ADDRESS *) mpib.pMacCoordExtendedAddress, securityEnable);
}
} // mipTransmitAssocDataRequest
//-------------------------------------------------------------------------------------------------------
// void mipPollAssociateResponseTask(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task makes sure that a data request is transmitted in the association procedure. If the
// transmission couldn't be initiated, this task will be rescheduled.
//
// TASK DATA:
// 0
//-------------------------------------------------------------------------------------------------------
void mipPollAssociateResponseTask(MAC_TASK_INFO *pTask) NEAR {
// We should not wait for the association response to be indicated in the beacon pending list, because there's no
// guarantee that it will ever appear there (the coordinator could for instance be out of resources when the
// association request is received)! If the association response is not polled, the MAC state machine (macInfo.state)
// will lock up (and probably the higher layer too).
if (macInfo.state == MAC_STATE_ASSOC_REQUEST_SENT) {
if (mipTransmitAssocDataRequest() == RESOURCE_SHORTAGE) {
// Reschedule this task if there was a lack of resources (TX packet or task)
mschRescheduleTask(pTask, 0);
return;
}
}
// Done! Remove this task
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
} // mipPollAssociateResponse
//-------------------------------------------------------------------------------------------------------
// void mipPollAssociateResponse(void)
//
// DESCRIPTION:
// This timeout function creates the task responsible for polling the association response.
//-------------------------------------------------------------------------------------------------------
void mipPollAssociateResponse(void) NEAR {
if (!mschAddTask(mschReserveTask(), MAC_TASK_PRI_LOW, mipPollAssociateResponseTask, 0)) {
mtimSetCallback(mipPollAssociateResponse, MIP_RETRY_ASSOCIATION_RESPONSE_POLLING_TIMEOUT);
}
} // mipPollAssociateResponse
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -