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

📄 zmac.c

📁 zigbee精简协议栈代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			else if ( TickGetDiff(TickGet(), macStartTick) >= MAC_ACK_WAIT_DURATION )
			{
				// Remove current frame and try again, if needed.
				MACFrameRemove(hFrame);

				if ( macFrameRetryCount == 0 )
				{
					ConsolePutString("MAC: MACIsAssociated(): No ACK.\r\n");
	               
					result = TRUE;
				}
				else
				{
					ConsolePutString("MAC: MACIsAssociated(): ACK Timeout, retrying...\r\n");
					smAssociation = SM_SEND_ASSOCIATE_REQ;
				}
			}

			break;


		case SM_WAIT_FOR_ASSOC_RESP:
			if( MACIsGetReady() )
			{
	            
				if (MACIsAssocResponse())
				{

	#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
					{
	                   
							//du 抛弃掉分配的short address
							MACGet();
							MACGet();

							macAssociationStatus = MACGet();

							if ( macAssociationStatus  != MAC_ASSOCIATE_SUCCESS )
							{
								ConsolePutString("MAC: MACIsAssociated(): Association attempt has failed.\r\n");
								result = TRUE;
							}

							else
							{

	                        

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

								macState.bits.bIsAssociated = TRUE;

								result = TRUE;

								PANDesc.CoordAddress.longAddr.v[0] = macCurrentFrame.src.longAddr.v[0];
								PANDesc.CoordAddress.longAddr.v[1] = macCurrentFrame.src.longAddr.v[1];
								PANDesc.CoordAddress.longAddr.v[2] = macCurrentFrame.src.longAddr.v[2];
								PANDesc.CoordAddress.longAddr.v[3] = macCurrentFrame.src.longAddr.v[3];
								PANDesc.CoordAddress.longAddr.v[4] = macCurrentFrame.src.longAddr.v[4];
								PANDesc.CoordAddress.longAddr.v[5] = macCurrentFrame.src.longAddr.v[5];
								PANDesc.CoordAddress.longAddr.v[6] = macCurrentFrame.src.longAddr.v[6];
								PANDesc.CoordAddress.longAddr.v[7] = macCurrentFrame.src.longAddr.v[7];

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

								MACUpdateAddressInfo();

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

			break;

		}
		return result;
	}

	/*********************************************************************
	 * 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.
	 ********************************************************************/
	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;
	}

	/*********************************************************************
	 * 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.
	 ********************************************************************/
	BOOL MACIsOrphanNotificationComplete(void)
	{
		BOOL result;

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

		switch(smAssociation)
		{
		case SM_SEND_ORPHAN_NOTICE:
			ConsolePutString("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();

							//du 忽略short address
							MACGet();
							MACGet();

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

							// Indicate that this process was successful.
	                       

							// 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 )
			{
				ConsolePutString("MAC: MACIsOrphanNotificationComplete(): ORPHAN Response timeout.\r\n");

				// For every timeout, also make sure that we retry predefined number
				// of times.
				if ( macFrameRetryCount == 0 )
				{
					ConsolePutString("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
				{
					ConsolePutString("MAC: MACIsOrphanNotificationComplete(): Trying ORPHAN scan again...\r\n");

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

		return result;
	}

/*********************************************************************
 * Function:        void MACAcceptCurrentPAN(void)
 *
 * PreCondition:    MACIsScanComplete() = TRUE and there is no
 *                  ERROR.
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Accepts last discovered coordinator as ours.
 *
 * Note:            Available to end device only.
 ********************************************************************/
void MACAcceptCurrentPAN(void)
{
    // Coordinator info will be same as what was received in beacon.
    if ( PANDesc.Flags.bits.CoordAddrMode == TRUE )
    {
        macCoordInfo.addrMode = MAC_DST_LONG_ADDR;
        macCoordInfo.longAddr.v[0] = PANDesc.CoordAddress.longAddr.v[0];
        macCoordInfo.longAddr.v[1] = PANDesc.CoordAddress.longAddr.v[1];
        macCoordInfo.longAddr.v[2] = PANDesc.CoordAddress.longAddr.v[2];
        macCoordInfo.longAddr.v[3] = PANDesc.CoordAddress.longAddr.v[3];
        macCoordInfo.longAddr.v[4] = PANDesc.CoordAddress.longAddr.v[4];
        macCoordInfo.longAddr.v[5] = PANDesc.CoordAddress.longAddr.v[5];
        macCoordInfo.longAddr.v[6] = PANDesc.CoordAddress.longAddr.v[6];
        macCoordInfo.longAddr.v[7] = PANDesc.CoordAddress.longAddr.v[7];
    }

    else
    {
        macCoordInfo.shortAddr = PANDesc.CoordAddress.shortAddr;
        macCoordInfo.addrMode = MAC_DST_SHORT_ADDR;
    }

    macCoordInfo.panID.Val = PANDesc.CoordPANId.Val;

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

    MACUpdateAddressInfo();

    
}

/*********************************************************************
 * Function:        void MACStartDisassociation(void)
 *
 * PreCondition:    MACInit(), MACEnable() are called
 *                  And MACIsPutReady() == TRUE
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Starts the disassociation process.
 *
 * Note:            Available to end devices only.
 ********************************************************************/
void MACStartDisassociation(void)
{
    macFrameRetryCount = MAC_MAX_FRAME_RETRIES;
    smAssociation = SM_SEND_DISASSOCIATE_REQ;
}

/*********************************************************************
 * Function:        BOOL MACIsDisassociationComplete(void)
 *
 * PreCondition:    MACStartDisassociation() is already called
 *
 * Input:           None
 *
 * Output:          TRUE, if disassociation is complete
 *                  FALSE, if otherwise
 *
 * Side Effects:    None
 *
 * Overview:        Performs disassociation state machine
 *
 * Note:            Available to end devices only.
 ********************************************************************/
BOOL MACIsDisassociationComplete(void)
{
    BOOL result;

    result = FALSE;
    switch(smAssociation)
    {
    case SM_SEND_DISASSOCIATE_REQ:
SM_SEND_DISASSOCIATE_REQ_LABEL:
        macFrameRetryCount--;

        // When disassociating, provide long address.
        macInfo.addrMode    = MAC_SRC_LONG_ADDR;

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



        // Load command specific data
        PHYBeginTxFIFOAccess();

        // Actual command code
        PHYPutTxData(MAC_CMD_DISASSOCIATE_NOTICE);

        // Leave reason
        PHYPutTxData(0x02);                         // Device wants to leave the PAN.

        // End of command specific data.
        PHYEndTxFIFOAccess();

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

        MACFlush();

        ConsolePutString("MAC: MACIsDisassociationComplete(): Sent Disassociation notice...\r\n");

        // Start the timeout tick.
        macStartTick = TickGet();
        smAssociation = SM_WAIT_FOR_ACK;
        break;

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

            ConsolePutString("MAC: MACIsDisassociationComplete(): ACK Received.\r\n");

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

            // Update the transceiver
            MACUpdateAddressInfo();

            // Function is done.
            result = TRUE;
        }

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

            // If retries are exhausted, set error code and finish.
            if ( macFrameRetryCount == 0 )
            {
                SetZError(ZCODE_NO_ACK);
                result = TRUE;
            }

            ConsolePutString("MAC: MACIsDisassociationComplete(): ACK timeout.\r\n");

⌨️ 快捷键说明

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