📄 zmac.c
字号:
// Try again.
smAssociation = SM_SEND_DISASSOCIATE_REQ;
}
}
return result;
}
#endif
/*********************************************************************
* Function: static void MACSendAck(ACK_TYPE typeOfAck)
*
* PreCondition: A valid frame has just arrived.
*
* Input: typeOfAck - either ACK_NO_DATA or ACK_NO_DATA_PENDING
*
* Output: None
*
* Side Effects: None
*
* Overview: Sends ACK frame in response to just received
* frame.
*
* Note: This is a private function
********************************************************************/
static void MACSendAck(ACK_TYPE ack)
{
// First, update the packet length.
PHYBegin();
PHYSendAck(ack);
// Terminate RAM access
PHYEnd();
//TODO(DF16) - Investigate error. Without the following delay the
//FCS value of the ACK packet gets corrupted/ miscalculated.
{BYTE i = 0x40; while(++i){nop();}}
}
/*********************************************************************
* 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.
********************************************************************/
BOOL MACProcessAssociation(void)
{
BOOL 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,
if ( ((BYTE)(macCurrentFrame.frameCONLSB.Val & 0x27) == (BYTE)0x23))
{
macCurrentFrame.capInfo.Val = MACGet();
return TRUE;
}
}
return FALSE;
}
/*********************************************************************
* 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.
********************************************************************/
HFRAME MACSendAssociateResponse(SHORT_ADDR *assocShortAddr,
MAC_ASSOCIATE_STATUS status)
{
ConsolePutString("send response\n");
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();
}
/*********************************************************************
* 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.
********************************************************************/
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);
//du 不一定是真正的coord
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 )
{
//du 收到后被忽略
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();
}
/*********************************************************************
* 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: 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
********************************************************************/
static void MACSendBeacon(void)
{
macInfo.addrMode = MAC_SRC_SHORT_ADDR;
//du beacon frame没有目的地址
macDestInfo.addrMode = MAC_DST_NO_ADDR;
MACPutHeader(&macDestInfo, // 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);
//Protocol ID
//0x00 as specified in table 45 NWK spec
PHYPutTxData(0x00);
//Stack profile (8-11) and nwkcProtocolVersion (12-15)
//nwkcProtocolVersion = 0x01 because ZigBee v1.0
PHYPutTxData(0x10);
//nwkSecurityLevel (16-18)
//0x00 - no security
//Device router capacity (19)
//FALSE because we only do star networks right now (no routers)
//Device depth (20-22)
//0x00 because we are coordinator
//device capacity (23)
//TRUE - we have room
PHYPutTxData(0x80);
//TxOffset
//only included in multihop beaconing networks
//PHYPutTxData(TxOffset);
PHYEndTxFIFOAccess();
// Manually update packet length here instead of calling MACPut() and adding more code
// and time.
//macPacketLen += 4;
macPacketLen += 7;
MACFlush();
ConsolePutString("send beacon successfully\n");
//while(1){wdt_reset();}
}
/*********************************************************************
* 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();
}
// 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -