⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_indirect_polling.c

📁 zigbee location examples
💻 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -