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

📄 zmac_receive.c

📁 通过cc2420+pic实现无线通信
💻 C
📖 第 1 页 / 共 5 页
字号:
            DEBUG_OUT("MAC: MACIsAssociated(): Valid ACK received, waiting for response...\r\n");

            macStartTick = TickGet();

            smAssociation = SM_WAIT_FOR_ASSOC_RESP;
        }
        else if ( TickGetDiff(TickGet(), macStartTick) >= MAC_ACK_WAIT_DURATION )
        {
            // Remove current frame and try again, if needed.
            MACFrameRemove(hFrame);

            if ( macFrameRetryCount == 0 )
            {
                SetZError(ZCODE_NO_ACK);
                result = TRUE;
            }

            DEBUG_OUT("MAC: MACIsAssociated(): ACK Timeout.\r\n");
            smAssociation = SM_SEND_ASSOCIATE_REQ;
        }

        break;


    case SM_WAIT_FOR_ASSOC_RESP:
        if( MACIsGetReady() )
        {
            //length = MACGetHeader();
            // First of all make sure that the payload length with that
            // of execpted Association response frame.
            if ( macCurrentFrame.frameLength == 3 )
            {
                // A valid association response must have following frame control  LSB
                // xx10?011 = Frame Type = MAC Command
                //            Security Enabled = 1 or 0 to match with our compile-time option
                //            Frame Pending is '0' and ignored
                //            Ack Required is '1'.
                //            Intra PAN is don't care
                //            Reserved bit don't care
                // And both source and destination address must be 64-bit long
#if defined(MAC_USE_SECURITY)
                if ( (macCurrentFrame.frameCONLSB.Val & 0x2B == 0x2B) &&
                     (macCurrentFrame.frameCONMSB.Val & 0xCC == 0xCC) )
#else
                if ( ((BYTE)(macCurrentFrame.frameCONLSB.Val & 0x23) == (BYTE)0x23) &&
                     ((BYTE)(macCurrentFrame.frameCONMSB.Val & 0xCC) == (BYTE)0xCC) )
#endif
                {
                    // The command type must be MAC_CMD_ASSOCIATE_RPLY
                    if ( macCurrentFrame.cmd == MAC_CMD_ASSOCIATE_RPLY )
                    {
                        // If coordinator was able to associate with us, next two bytes will
                        // be the our new short address, or else it will be 0xffff.
                        // If it is 0xffff, associationStatus will tell us the reason.
                        macInfo.shortAddr.byte.LSB = MACGet();
                        macInfo.shortAddr.byte.MSB = MACGet();
                        macAssociationStatus = MACGet();

                        // Is association successful?
                        if ( macAssociationStatus  != MAC_ASSOCIATE_SUCCESS )
                        {
                            DEBUG_OUT("MAC: MACIsAssociated(): Association attempt has failed.\r\n");
                            result = TRUE;
                        }

                        else
                        {

                            // Once we receive this frame, coordinator expects an acknowledgement.
                            // MACInit() has already configured CC2420 to automatically acknolwedge all
                            // frames with AckReq bit set.

                            DEBUG_OUT("MAC: MACIsAssociated(): Association successful.\r\n");

                            macState.bits.bIsAssociated = TRUE;

                            result = TRUE;

                            MACSetPANIdLSB(macCoordInfo.panID.byte.LSB);
                            MACSetPANIdMSB(macCoordInfo.panID.byte.MSB);

                            MACUpdateAddressInfo();

                        }
                    }
                }
            }
            MACDiscardRx();
        }
        else if ( TickGetDiff(TickGet(), macStartTick) >= MAC_RESPONSE_WAIT_TIME )
        {
            if ( macFrameRetryCount == 0 )
            {
                DEBUG_OUT("MAC: MACIsAssociated(): No DATA REQ reply.\r\n");
                SetZError(ZCODE_NO_ACK);
                result = TRUE;
            }
            else
            {
                DEBUG_OUT("MAC: MACIsAssociated(): DATA REQ reply timeout, retrying...\r\n");
                smAssociation = SM_SEND_ASSOCIATE_REQ;
            }
        }

        break;

    }
    return result;
}
#endif


/*********************************************************************
 * Function:        static void MACSendAck(void)
 *
 * PreCondition:    A valid frame has just arrived.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends ACK frame in response to just received
 *                  frame.
 *
 * Note:            This is a private function
 ********************************************************************/
static void MACSendAck(void)
{
    //DEBUG_OUT("MAC: MACSendAck(): Sending ACK.\r\n");

#if defined(WIN32)
    MACPutHeader(NULL, MAC_FRAME_ACK);
    MACFlush();
#else

    // First, update the packet length.
    PHYBegin();

    PHYSendAck();

    // Terminate RAM access
    PHYEnd();
#endif
}


/*********************************************************************
 * Function:        HFRAME MACPoll(void)
 *
 * PreCondition:    MACIsPutReady() = TRUE
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends Data request frame as per 802.15.4 spec.
 *
 * Note:            Available to end device only
 ********************************************************************/
#if defined(I_AM_END_DEVICE)
HFRAME MACPoll(void)
{
    // Use long address only if short address is not yet assigned.
    if ( macInfo.shortAddr.byte.MSB == 0xff &&
         (macInfo.shortAddr.byte.LSB == 0xff ||
          macInfo.shortAddr.byte.LSB == 0xfe) )
        macInfo.addrMode = MAC_SRC_LONG_ADDR;
    else
        macInfo.addrMode = MAC_SRC_SHORT_ADDR;

    MACPutHeader(&macCoordInfo,            // Dest
                  MAC_FRAME_CMD |           // Frame Control LSB
                  MAC_SECURITY |
                  MAC_FRAME_PENDING_NO |
                  MAC_ACK_YES |
                  MAC_INTRA_PAN_NO);



    PHYBeginTxFIFOAccess();
    PHYPutTxData(MAC_CMD_DATA_REQ);
    PHYEndTxFIFOAccess();

    // Manually update packet length here instead of calling MACPut() and adding more code
    // and time.
    macPacketLen++;

    // For Poll request, we don't care to wait or confirm ack from remote node.
    // If it was received by remote node and there is some pending data for us
    // remote node will send it to us and that will serve as a confirmation
    // to our poll request.
    // By default, bToBeQueued was set by MACPutHeader because of MAC_ACK_YES flag.
    macCurrentFrame.Flags.bits.bToBeQueued = FALSE;

    macState.bits.bIsPollDone = FALSE;

    return MACFlush();

}
#endif




/*********************************************************************
 * Function:        BOOL MACProcessAssociation(void)
 *
 * PreCondition:    A valid frame is in RX buffer and
 *                  header is already fetched and processed.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Fetches rest of the frame and processes it if
 *                  is a valid association request frame.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
#if defined(I_AM_COORDINATOR)
BOOL MACProcessAssociation(void)
{
    BOOL lbResult;

    lbResult = FALSE;

    // There must be exactly two bytes of data in association request frame.
    if( macCurrentFrame.frameLength == 1 )
    {
        // Make sure that current frame is indeed association request.
        // LSB = Mask: 0b00100111 Value: 0b00100011,
        // MSB = Mask: 0b11001100 Value: 0b11001100
        if ( ((BYTE)(macCurrentFrame.frameCONLSB.Val & 0x27) == (BYTE)0x23) &&
             ((BYTE)(macCurrentFrame.frameCONMSB.Val & 0xCC) == (BYTE)0xCC) )
        {
            macCurrentFrame.capInfo.Val = MACGet();

            return TRUE;
        }
    }

    return FALSE;
}
#endif


/*********************************************************************
 * Function:        HFRAME MACSendAssociateResponse(
 *                              SHORT_ADDR *assocShortAddr,
 *                              MAC_ASSOCIATE_STATUS status)
 *
 * PreCondition:    assocShortAddr  - Short address to be sent
 *                                    as part of association response
 *                  status          - Association result code to be sent
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Creates and sends valid association response frame
 *                  as per IEEE spec.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
#if defined(I_AM_COORDINATOR)
HFRAME MACSendAssociateResponse(SHORT_ADDR *assocShortAddr,
                              MAC_ASSOCIATE_STATUS status)
{
    macInfo.addrMode = MAC_SRC_LONG_ADDR;

    // Use information from macCurrentFrame to build response frame.
    // If we arrive at this point, macCurrentFrame must be a valid
    // Associate Request and as a result, we will only change those fields
    // that needs to changed as part of response frame format.
    macCurrentFrame.src.addrMode = MAC_DST_LONG_ADDR;

    // Dest panID will be same as ours.
    macCurrentFrame.src.panID.Val = macInfo.panID.Val;

    MACPutHeader(&macCurrentFrame.src,         // Dest
                  MAC_FRAME_CMD |           // Frame Control LSB
                  MAC_SECURITY |
                  MAC_FRAME_PENDING_NO |
                  MAC_ACK_YES |
                  MAC_INTRA_PAN_NO);



    PHYBeginTxFIFOAccess();
    PHYPutTxData(MAC_CMD_ASSOCIATE_RPLY);
    PHYPutTxData(assocShortAddr->byte.LSB);
    PHYPutTxData(assocShortAddr->byte.MSB);
    PHYPutTxData((BYTE)status);
    PHYEndTxFIFOAccess();

    // Manually update packet length here instead of calling MACPut() and adding more code
    // and time.
    macPacketLen += 4;

    return MACFlush();

}
#endif



/*********************************************************************
 * Function:        HFRAME MACSendRealignment(
 *                          SHORT_ADDR *destShortAddr, BOOL bBroadcast)
 *
 * PreCondition:    MACIsPutReady() = TRUE
 *
 * Input:           destShortAddr - node to whom relignment frame to send
 *                  bBroadcast    - indicates if this is to be broadcast
 *
 * Output:          Handle to frame that was just transmitted.
 *                  Caller must use this handle to determine if this
 *                  frame was ack'ed by intended remote node.
 *
 * Side Effects:    None
 *
 * Overview:        Creates and sends valid relignment frame
 *                  as per IEEE spec.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
#if defined(I_AM_COORDINATOR)
HFRAME MACSendRealignment(SHORT_ADDR *destShortAddr, BOOL bBroadcast)
{
    BYTE frameFlags;

    macInfo.addrMode = MAC_SRC_LONG_ADDR;
    // Other information is already set.

    // If this is a unicast, we need to use LONG address.
    // Since we already have remote device's address information
    // in current frame, we will use current frame's source as
    // destination for this frame.
    if ( bBroadcast == FALSE )
    {
        macCurrentFrame.src.addrMode = MAC_DST_LONG_ADDR;

        // For unicast frame, request ack.
        frameFlags = MAC_FRAME_CMD |
                     MAC_SECURITY |
                     MAC_FRAME_PENDING_NO |
                     MAC_ACK_YES |
                     MAC_INTRA_PAN_NO;
    }

    else
    {
        macCurrentFrame.src.addrMode = MAC_DST_SHORT_ADDR;
        macCurrentFrame.src.shortAddr.Val = 0xffff;

        // For broadcast, do not request ack.
        frameFlags = MAC_FRAME_CMD |
                     MAC_SECURITY |
                     MAC_FRAME_PENDING_NO |
                     MAC_ACK_NO |
                     MAC_INTRA_PAN_NO;
    }

    // The destination PAN will be 0xFFFF
    macCurrentFrame.src.panID.Val = 0xffff;

    MACPutHeader(&macCurrentFrame.src, frameFlags);

    // Now load coord realignment specific payload.
    PHYBegin();
    PHYSelectTxFIFO();
    PHYPut(MAC_CMD_COORD_REALIGNMENT);

    // Current PAN ID.
    PHYPut(macInfo.panID.byte.LSB);
    PHYPut(macInfo.panID.byte.MSB);

    // Coordinator's short address
    PHYPut(macInfo.shortAddr.byte.LSB);
    PHYPut(macInfo.shortAddr.byte.MSB);

    // Logical channel
    PHYPut(macCurrentChannel);

    // If this is a unicast, supply dest short addr.
    if ( bBroadcast == FALSE )
    {
        PHYPut(destShortAddr->byte.LSB);
        PHYPut(destShortAddr->byte.MSB);
    }
    else
    {
        // For broadcast, this will be 0xffff.
        PHYPut(0xff);
        PHYPut(0xff);
    }

    PHYEnd();

    // Update MACPacketLen manually.
    macPacketLen += 8;

    return MACFlush();

}
#endif


/*********************************************************************
 * Function:        void MACStartOrphanNotification(void)
 *
 * PreCondition:    MACIsPutReady() = TRUE
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Prepares the state machine for orphan notification
 *
 * Note:            Available to end devices only.
 ********************************************************************/

⌨️ 快捷键说明

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