📄 zmac.c
字号:
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 + -