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

📄 mac.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 4 页
字号:
    // 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 + -