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

📄 zmac_receive.c

📁 通过cc2420+pic实现无线通信
💻 C
📖 第 1 页 / 共 5 页
字号:
#if defined(I_AM_END_DEVICE)
void MACStartOrphanNotification(void)
{
    // Once we start the orphan process, we assume that we are no
    // longer associated with network - we are trying to find our
    // previous network.
    macState.bits.bIsAssociated = FALSE;

    // This is how many times we should retry before giving out.
    macFrameRetryCount = MAC_MAX_FRAME_RETRIES;

    // Start with sending the notice.
    smAssociation = SM_SEND_ORPHAN_NOTICE;
}
#endif


/*********************************************************************
 * Function:        BOOL MACIsOrphanNotificationComplete(void)
 *
 * PreCondition:    MACStartOrphanNotification() is called.
 *
 * Input:           None
 *
 * Output:          TRUE if orphan notification process is complete
 *                  FALSE otherwise.
 *
 * Side Effects:    None
 *
 * Overview:        Performs orphan notification steps as per
 *                  IEEE spec.
 *
 * Note:            Available to end devices only.
 ********************************************************************/
#if defined(I_AM_END_DEVICE)
BOOL MACIsOrphanNotificationComplete(void)
{
    BOOL result;

    // Begin with not ready return value.
    result = FALSE;

    switch(smAssociation)
    {
    case SM_SEND_ORPHAN_NOTICE:
        DEBUG_OUT("MAC: MACIsOrphanNotificationComplete(): Sending an orphan request...\r\n");

        // This is a retry
        macFrameRetryCount--;

        // macInfo is our address - source address in this case.
        // As per spec, source address would be 64-bit address.
        macInfo.addrMode = MAC_SRC_LONG_ADDR;
        // And no PAN id.
        macInfo.panID.Val = 0xffff;

        // Destination will use not yet known short address with no PAN id.
        macCoordInfo.addrMode = MAC_DST_SHORT_ADDR;
        macCoordInfo.shortAddr.Val = 0xffff;
        macCoordInfo.panID.Val = 0xffff;

        // Prepare the header.
        MACPutHeader(&macCoordInfo,
                     MAC_FRAME_CMD |
                     MAC_SECURITY |
                     MAC_FRAME_PENDING_NO |
                     MAC_ACK_NO |
                     MAC_INTRA_PAN_NO);

        // Copy orphan norification specific bytes in payload area.
        PHYBeginTxFIFOAccess();
        PHYPut(MAC_CMD_ORPHAN_NOTICE);
        PHYEndTxFIFOAccess();

        // Update transmit frame length to account for one byte
        // that we added manually.
        macPacketLen++;

        // Mark this frame as ready to be transmitted.
        MACFlush();

        // Remember when we sent the frame.
        macStartTick = TickGet();

        // We will now wait for ACK from coordinator.
        smAssociation = SM_WAIT_FOR_COORD_ALIGNMENT;
        break;

    case SM_WAIT_FOR_COORD_ALIGNMENT:
        // See if we received any thing...
        if( MACIsGetReady() )
        {
            // The coordinator alignment frame has 7 data bytes in addition to command identifier.
            if ( macCurrentFrame.frameLength == 7 )
            {
                // Make sure that this is a coordinator realignment frame
                if ( MACIsCommand() )
                {
                    // Is this coordinator reliang command?
                    // Coordinator will respond with coordinator realignment frame
                    // to our orphan notice command.
                    if ( MACIsCoordRealign() )
                    {
                        // Now make sure that the frame header is correct according to realignment frame.
                        // TBD

                        // If we receive realignment frame, it means that we are in fact
                        // orphan to this coordinator. In that case, this response will
                        // contain our previously assigned short address.
                        // Fetch PAN id.
                        macInfo.panID.byte.LSB = MACGet();
                        macInfo.panID.byte.MSB = MACGet();

                        // Coordinator's PAN address is same as what is given to us
                        macCoordInfo.panID.Val = macInfo.panID.Val;


                        // Fetch coordinator short address.
                        macCoordInfo.shortAddr.byte.LSB = MACGet();
                        macCoordInfo.shortAddr.byte.MSB = MACGet();

                        // Remember the channel.
                        macCurrentChannel = MACGet();

                        // Now get our own short address.
                        macInfo.shortAddr.byte.LSB = MACGet();
                        macInfo.shortAddr.byte.MSB = MACGet();

                        // Now that we have our PAN id, update transciever buffer.
                        MACUpdateAddressInfo();

                        // Indicate that this process was successful.
                        SetZError(ZCODE_NO_ERROR);

                        // Remember that we are now associated.
                        macState.bits.bIsAssociated = TRUE;

                        // Return value.
                        result = TRUE;
                    }
                }
            }

            // Discard now processed frame.
            MACDiscardRx();

        }

        // Keep track of timeout so that we do not wait forever for the response.
        else if ( TickGetDiff(TickGet(), macStartTick) >= MAC_RESPONSE_WAIT_TIME )
        {
            DEBUG_OUT("MAC: MACIsOrphanNotificationComplete(): ORPHAN Response timeout.\r\n");

            // For every timeout, also make sure that we retry predefined number
            // of times.
            if ( macFrameRetryCount == 0 )
            {
                DEBUG_OUT("MAC: MACIsOrphanNotificationComplete(): ORPHAN Response retry timeout.\r\n");

                // We exhausted retry count, set an error - NO_ACK
                SetZError(ZCODE_NO_ACK);

                // Done.
                result = TRUE;
            }
            else
            {
                DEBUG_OUT("MAC: MACIsOrphanNotificationComplete(): Trying ORPHAN scan again...\r\n");

                // We still have not exhausted retry count, try again...
                smAssociation = SM_SEND_ORPHAN_NOTICE;
            }
        }
    }

    return result;
}
#endif



/*********************************************************************
 * Function:        BOOL MACProcessDisassociation(void)
 *
 * PreCondition:    MACGetHeader() is already called and this frame
 *                  is identified as Disassociate command frame.
 *
 * Input:           None
 *
 * Output:          TRUE if found valid association frame.
 *                  FALSE othersie
 *
 * Side Effects:    None
 *
 * Overview:        Fetches rest of disassociation frame and validates
 *                  as per IEEE spec.
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
#if defined(I_AM_COORDINATOR)
BOOL MACProcessDisassociation(void)
{
    // There must be exactly two bytes of data in association request frame.
    if( macCurrentFrame.frameLength == 1 )
    {
        // A disassociation request must have
        // 1. Both source and destination addressing mode = 64-bit addresses.
        // 2. Frame pending field set to 0.
        // 3. Acknowledge field set to 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) )
        {
            // Fetch and discard disassociation reason.
            MACGet();

            return TRUE;
        }
    }

    return FALSE;
}
#endif


/*********************************************************************
 * Function:        void MACSendPANIDConflict(NODE_INFO *dest)
 *
 * PreCondition:    TBD
 *
 * Input:           TBD
 *
 * Output:          TBD
 *
 * Side Effects:    None
 *
 * Overview:        TBD
 *
 * Note:            Available to coordinator only.
 ********************************************************************/
#if 0
#if defined(I_AM_COORDINATOR)
void MACSendPANIDConflict(NODE_INFO *dest)
{
    MACPutHeader(MAC_FRAME_CMD |
                 MAC_SECURITY |
                 MAC_FRAME_PENDING_NO |
                 MAC_ACK_YES |
                 MAC_INTRA_PAN_YES,
                 MAC_SRC_LONG_ADDR |
                 MAC_DST_LONG_ADDR);

    PHYBegin();
    PHYPut(MAC_CMD_PAN_ID_CONFLICT);
    PHYEnd();

    MACFlush();
}
#endif
#endif




#define SUPERFRAME_SPEC_LSB         (0x00)
#define SUPERFRAME_SPEC_MSB         (0xC0)
#define GTS_FIELD_VAL               (0x00)


/*********************************************************************
 * Function:        static void MACSendBeaconReq(void)
 *
 * PreCondition:    MACIsPutready() = TRUE
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends out beacon request
 *
 * Note:            None
 ********************************************************************/
static void MACSendBeaconReq(void)
{
    // Now that we are trying to associate, forget previous PAN ID
    macInfo.addrMode    = MAC_SRC_NO_ADDR;

    // Coordinator info will be same as what was received in beacon.
    // But for time being use hardcoded value to test out...
    macCoordInfo.addrMode       = MAC_DST_SHORT_ADDR;
    macCoordInfo.shortAddr.Val  = 0xffff;
    macCoordInfo.panID.Val      = 0xffff;

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


    // Load beacon req specific bytes in payload area.
    PHYBeginTxFIFOAccess();
    PHYPutTxData(MAC_CMD_BEACON_REQ);
    PHYEndTxFIFOAccess();

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

    // Mark it as ready to transmit
    MACFlush();

}


/*********************************************************************
 * Function:        static void MACSendBeacon(void)
 *
 * PreCondition:    MACIsPutready() = TRUE
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Sends out beacon
 *
 * Note:            Available to coordinator only
 ********************************************************************/
#if defined(I_AM_COORDINATOR)
static void MACSendBeacon(void)
{
    // Coordinator uses extended address.
    macInfo.addrMode = MAC_SRC_LONG_ADDR;

    // In beacon, there is no destination address.
    macCoordInfo.addrMode = MAC_DST_NO_ADDR;

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


    // Load beacon specific bytes into payload area.
    PHYBeginTxFIFOAccess();
    PHYPutTxData(SUPERFRAME_SPEC_LSB);
    PHYPutTxData(SUPERFRAME_SPEC_MSB);
    PHYPutTxData(GTS_FIELD_VAL);

    // Pending address field - TBD
    PHYPutTxData(0x00);

    PHYEndTxFIFOAccess();

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

    MACFlush();

}
#endif



/*********************************************************************
 * Function:        void MACStartScan(BOOL bActiveScan)
 *
 * PreCondition:    MACInit(), MACEnable() are called
 *                  And MACIsPutReady() == TRUE
 *
 * Input:           bActiveScan - flag to perform active/passive scan
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        If this is active scan, sends out beacon request
 *
 * Note:            None
 ********************************************************************/
void MACStartScan(BOOL bActiveScan)
{
    // Send beacon if this is active scan
    if ( bActiveScan )
    {
        // First send out a beacon
        MACSendBeaconReq();
    }

    // Earlier version of CC2420 (see zMAC.h for more info) has this
    // bug where it would not receive beacon frame without disabling
    // filter.
#if defined(CC2420_BUG1_WORKAROUND)
    PHYEnableRxFilter(FALSE);
#endif

    // Remember time so that we can know when to abort.
    macStartTick = TickGet();

    // Zero out number of discovered coordinators
    PANDescCount = 0;

}


/*********************************************************************
 * Function:        BOOL MACIsScanComplete(void)
 *
 * PreCondition:    MACStartScan() is called.
 *
 * Input:           None
 *
 * Output:          TRUE if scan is complete
 *                  FALSE otherwise.
 *
 * Side Effects:    None
 *
 * Overview:        Checks to see a beacon was r

⌨️ 快捷键说明

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