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

📄 zmac.c

📁 zigbee精简协议栈代码
💻 C
📖 第 1 页 / 共 5 页
字号:

                    //Notify the application of a timeout condition.
					//ConsolePutString("time out and remove\n");
					//du 直接从DSN中移除   
					//MACFrameRemove(i);
				
                    #if 0
                    if(pMACFrameStatus->retryCount == 0)
                    {
                        //DumpMacFrameStatusQ();
                        //MACRemoveFrame(i);
                    }
                    #endif
                }
            }
        }
    }
}

/*********************************************************************
 * Function:        BOOL MACTask(void)
 *
 * PreCondition:    MACInit() is called
 *
 * Input:           None
 *
 * Output:          TRUE        - If Processing is complete
 *                  FALSE       - If further processing is required
 *
 * Side Effects:    None
 *
 * Overview:        If previous frame is processed, it checks
 *                  for new RX frame.
 *                  Fetches the header and determiens if it is valid
 *                  Automatically sends ACK if remote node has
 *                  requested it.
 *                  Also performs some other automatic processing
 *                  based on the frame type.
 *                  If there is no frame in buffer, it goes through
 *                  DSN queue and calculates timeout for unack'ed
 *                  TX frames.
 *
 * Note:            This function must be called as many times as
 *                  possible to keep handling MAC frames.
 ********************************************************************/
BOOL MACTask(void)
{	
	 MACUpdateTimeoutFlags();

    // If there was an overflow, handle it.
    // Since this is a half-duplex and the way CC2420 indicates RX FIFO OVERFLOW,
    // check for overflow condition only when RF is not actively transmitting a packet.
    if ( macState.bits.bIsTxBusy == FALSE )
    {
        if ( PHYProcessRxOverflow() )
        {
            ConsolePutString("MAC: A receive overflow was detected and removed.\r\n");
        }
    }

    //du 当过去的数据被处理完成后,才接受新的数据
	if ( MACIsGetReady() ){
		
		ConsolePutString("mac not handled\n");
		return TRUE;
	}
        

    
    if ( !PHYIsGetReady() )
    {
		
        return TRUE;
    }

    if ( !MACGetHeader() )
    {
        ConsolePutString("mac header wrong\n");
		return TRUE;
    }

    ConsolePutString("mac receive right frame\n");
    macCurrentFrame.Flags.bits.bIsGetReady = TRUE;
	
    // Send ack back if requested.
    if ( macCurrentFrame.frameCONLSB.bits.AckRequest )
    {
        if((MACIsCommand()) && (MACIsDataReq()))
        {
           MACSendAck(ACK_DATA_PENDING);
           MACSendAck(ACK_NO_DATA);
        }
        else
        {
            MACSendAck(ACK_NO_DATA);
        }
    }

    if (MACIsAck())
    {
        UpdateQueue(macCurrentFrame.macDSN);   
        MACDiscardRx();
    }
    else if (MACIsCommand())
    {
        if (MACIsBeaconRequest())
        {
            if (macState.bits.bIsAssociated)
            { 
                MACSendBeacon();
            }
			MACDiscardRx();			
        }

        // New associations are allowed only if it is permitted by application.
        else if (MACIsAssocRequest())
        {            
            if ( !MACProcessAssociation() )
            {
                MACDiscardRx();
				
			}
			else {
				MACDiscardRx();
				//du macInfo.shortAddr接收被忽略
				MACSendAssociateResponse(&macInfo.shortAddr, MAC_ASSOCIATE_SUCCESS);
			}         
        }
		        // Orphan can be rejoined only after we have established new network.
        else if ( MACIsOrphanNotice() )
        {
            if ( macState.bits.bIsAssociated )
            {
                if ( !MACProcessOrphanNotice() )
                    MACDiscardRx();
				else {
					MACDiscardRx();
					//du macInfo.shortAddr接收被忽略
					MACSendRealignment(&macInfo.shortAddr, FALSE);
				}
					
            }
            else
                MACDiscardRx();
        }

      
        else if ( MACIsDisassocNotice() )
        {
#ifdef I_AM_COORDINATOR
            if ( !MACProcessDisassociation() )
                MACDiscardRx();
			else {
				 MACDiscardRx();
			}
#endif 
#ifdef I_AM_END_DEVICE
			            //The coordinator or router I am associated to has asked
            //me to leave.
            //MLME-DISASSOCIATION.indication
            macState.bits.bIsAssociated = FALSE;

            // Forget PAN ID.
            MACSetPANIdLSB(0xff);
            MACSetPANIdMSB(0xff);

            // Update the transceiver
            MACUpdateAddressInfo();
			MACDiscardRx();
#endif

        }

    }


    return TRUE;
}

/*********************************************************************
 * Function:        static BOOL MACGetHeader(void)
 *
 * PreCondition:    _MACIsGetReady() == TRUE
 *
 * Input:           None
 *
 * Output:          TRUE        - if current frame has valid header
 *                  FALSE       - if current frame does not have
 *                                valid header
 *
 * Side Effects:    None
 *
 * Overview:        Fetches rx frame one byte at a time and validates
 *                  as per 802.15.4 spec.
 *
 * Note:            This is private function, called MAC module only.
 ********************************************************************/
static BOOL MACGetHeader(void)
{
    BYTE_VAL temp;
    BYTE frameType;
    BYTE_VAL length;

    PHYBegin();

    // Start reading RX FIFO.
    PHYSelectRxFIFO();

    // First byte is length
    length.Val = PHYGet();

    // Make sure that this is a valid length
    if ( length.Val == 0 || length.bits.b7 == 1 )
    {
        goto DiscardAndReturn;
    }

    // Save received packet length minus 2 bytes of CRC/(RSSI + CORRELATION for CC2420)
    macCurrentFrame.frameLength = length.Val - 2;

    // Get frame control field - LSB.
    temp.Val = PHYGet();
    // One less byte from packet count.
    macCurrentFrame.frameLength--;

    // save frame LSB
    macCurrentFrame.frameCONLSB.Val = temp.Val;

    // Extract and save frame type
    macCurrentFrame.type = temp.Val & 0x07;

    // Reject "Reserved" frame type.
    frameType = macCurrentFrame.type;
    if ( frameType > 0x03 )
    {
        goto DiscardAndReturn;
    }

    // Other bits will be processed later...

    // Now get MSB
    temp.Val = PHYGet();
    // One less byte from packet count.
    macCurrentFrame.frameLength--;

    // Save MSB
    macCurrentFrame.frameCONMSB.Val = temp.Val;

    // Save frame MSB.
    macCurrentFrame.dst.addrMode = temp.Val & 0x0c;
    macCurrentFrame.src.addrMode = temp.Val & 0xc0;

    // Get Sequence number
    macCurrentFrame.macDSN = PHYGet();

    macCurrentFrame.frameLength--;

    // Mode value of non-zero means that destination PAN identifier is present.
    if ( macCurrentFrame.dst.addrMode == MAC_DST_ADDR_RESERVED )
    {
        goto DiscardAndReturn;
    }

    // If the destination addressing mode field is non-zero, there is a dst PAN ID.
    if ( macCurrentFrame.dst.addrMode )
    {
        macCurrentFrame.dst.panID.byte.LSB = PHYGet();
        macCurrentFrame.dst.panID.byte.MSB = PHYGet();

        macCurrentFrame.frameLength -= 2;
    }

    // Fetch destination address according to its type
    if ( macCurrentFrame.dst.addrMode == MAC_DST_SHORT_ADDR )
    {
        macCurrentFrame.dst.shortAddr.byte.LSB = PHYGet();
        macCurrentFrame.dst.shortAddr.byte.MSB = PHYGet();

        macCurrentFrame.frameLength -= 2;
    }
    else if ( macCurrentFrame.dst.addrMode == MAC_DST_LONG_ADDR )
    {
        macCurrentFrame.dst.longAddr.v[0] = PHYGet();
        macCurrentFrame.dst.longAddr.v[1] = PHYGet();
        macCurrentFrame.dst.longAddr.v[2] = PHYGet();
        macCurrentFrame.dst.longAddr.v[3] = PHYGet();
        macCurrentFrame.dst.longAddr.v[4] = PHYGet();
        macCurrentFrame.dst.longAddr.v[5] = PHYGet();
        macCurrentFrame.dst.longAddr.v[6] = PHYGet();
        macCurrentFrame.dst.longAddr.v[7] = PHYGet();

        macCurrentFrame.frameLength -= 8;
    }

    // Mode value of non-zero means that source PAN identifier is present.
    if ( macCurrentFrame.src.addrMode == MAC_SRC_ADDR_RESERVED )
        goto DiscardAndReturn;

    // If the source addressing mode field is non-zero and the IntraPAN flag is clear,
    // the IEEE spec says there will be a src PAN ID.
    if ( macCurrentFrame.src.addrMode &&
         macCurrentFrame.frameCONLSB.bits.IntraPAN == 0 )
    {
        macCurrentFrame.src.panID.byte.LSB = PHYGet();
        macCurrentFrame.src.panID.byte.MSB = PHYGet();

        macCurrentFrame.frameLength -= 2;
    }


    // Fetch source address according to its type
    if ( macCurrentFrame.src.addrMode == MAC_SRC_SHORT_ADDR )
    {
        macCurrentFrame.src.shortAddr.byte.LSB = PHYGet();
        macCurrentFrame.src.shortAddr.byte.MSB = PHYGet();

        macCurrentFrame.frameLength -= 2;
    }
    else if ( macCurrentFrame.src.addrMode == MAC_SRC_LONG_ADDR )
    {
        macCurrentFrame.src.longAddr.v[0] = PHYGet();
        macCurrentFrame.src.longAddr.v[1] = PHYGet();
        macCurrentFrame.src.longAddr.v[2] = PHYGet();
        macCurrentFrame.src.longAddr.v[3] = PHYGet();
        macCurrentFrame.src.longAddr.v[4] = PHYGet();
        macCurrentFrame.src.longAddr.v[5] = PHYGet();
        macCurrentFrame.src.longAddr.v[6] = PHYGet();
        macCurrentFrame.src.longAddr.v[7] = PHYGet();

        macCurrentFrame.frameLength -= 8;
    }

    // If this is a command frame, extract and save command id.
    if ( macCurrentFrame.type == MAC_FRAME_CMD )
    {
        macCurrentFrame.frameLength--;
        macCurrentFrame.cmd = PHYGet();
    }
#if defined(I_AM_END_DEVICE)
    else if ( macCurrentFrame.type == MAC_FRAME_DATA )
        macState.bits.bIsPollDone = TRUE;
#endif

    PHYEnd();

    return TRUE;


DiscardAndReturn:
    PHYEnd();

    PHYBegin();
    PHYFlushRx();
    PHYEnd();
    return FALSE;
}

#if defined(I_AM_END_DEVICE)
	/*********************************************************************
	 * Function:        void MACStartAssociation(void)
	 *
	 * PreCondition:    MACAcceptCurrentPAN() is already called.
	 *                  A network scan was performed and appropriate
	 *                  coordinator was selected.
	 *
	 * Input:           None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:        Prepares MAC state machine to begin association
	 *                  sequence.
	 *
	 * Note:            This is available for end device only.
	 ********************************************************************/
	void MACStartAssociation(void)
	{
		// Forget about previous association.
		macState.bits.bIsAssociated = FALSE;

		macFrameRetryCount = MAC_MAX_FRAME_RETRIES;

		// Reset the state machine.
		smAssociation = SM_SEND_ASSOCIATE_REQ;

	}

	/*********************************************************************
	 * Function:        BOOL MACIsAssociationComplete(void)
	 *
	 * PreCondition:    MACStartAssociation() is called.
	 *
	 * Input:           None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:        performs association sequence as per 802.15.4
	 *                  spec.
	 *
	 * Note:            This is available for end device only.
	 ********************************************************************/
	BOOL MACIsAssociationComplete(void)
	{
		BOOL result = FALSE;
		MAC_ASSOCIATE_STATUS    macAssociationStatus;

	   
		switch(smAssociation)
		{
		case SM_SEND_ASSOCIATE_REQ:
			macFrameRetryCount--;

			// When associating, provide long address and no pan id.
			macInfo.addrMode    = MAC_SRC_LONG_ADDR;
			macInfo.panID.Val   = 0xffff;
			//du macCoordInfo 不一定是真正的Coord
			MACPutHeader(&macCoordInfo,            
						MAC_FRAME_CMD |           
						MAC_SECURITY |
						MAC_FRAME_PENDING_NO |
						MAC_ACK_YES|
						MAC_INTRA_PAN_NO);



			PHYBeginTxFIFOAccess();
			PHYPutTxData(MAC_CMD_ASSOCIATE_REQ);
			PHYPutTxData(0x00);	//MAC_CAP_INFO,接收忽略
			PHYEndTxFIFOAccess();

	        
			macPacketLen += 2;

			hFrame = MACFlush();

			ConsolePutString("MAC: MACSendAssociateRequest(): Sent association request...\r\n");
			
			macStartTick = TickGet();
			smAssociation = SM_WAIT_FOR_ACK;

			break;
			

		case SM_WAIT_FOR_ACK:
			if ( MACFrameIsAcked(hFrame) )
			{
				MACFrameRemove(hFrame);

				ConsolePutString("MAC: MACIsAssociated(): Valid ACK received, asking for response...\r\n");
				smAssociation = SM_WAIT_FOR_ASSOC_RESP;

			}

⌨️ 快捷键说明

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