📄 zaps.c
字号:
if (is_route_discovered(pMessageInfo->destAddress.shortAddr))
{
ConsolePutString("route discover finished\n");
route = lookup_route(pMessageInfo->destAddress.shortAddr.Val );
}
else
{
ConsolePutString("route discover failed\n");
return TRANS_ID_INVALID;
}
}
macDestInfo.addrMode = MAC_DST_SHORT_ADDR;
macDestInfo.panID = macInfo.panID;
macDestInfo.shortAddr.Val = route->next_ip;
//du 当前版本不支持应用间接发送
if ( !pMessageInfo->flags.bits.bModeIsDirect )
{
return TRANS_ID_INVALID;
}
apsFlags = APS_FRAME_DATA | APS_DELIVERY_DIRECT;
apsCurrentFrame.destEP = pMessageInfo->destEP;
//du 当前版本不支持应用层应答
if (pMessageInfo->flags.bits.bAckRequested)
{
return TRANS_ID_INVALID;
}
APSPutHeader( &macDestInfo, apsFlags , pMessageInfo->destAddress.shortAddr);
if (pMessageInfo->transactionID == TRANS_ID_INVALID)
{
apsTransId++;
if ( apsTransId == TRANS_ID_INVALID )
apsTransId++;
APSPut(apsTransId);
}
else
{
APSPut( pMessageInfo->transactionID );
}
if (pMessageInfo->frameType == KVP_FRAME)
{
APSPut((BYTE)((BYTE)pMessageInfo->command | (BYTE)pMessageInfo->dataType));
APSPut(pMessageInfo->attribID.byte.LSB);
APSPut(pMessageInfo->attribID.byte.MSB);
}
else if (pMessageInfo->frameType == MSG_FRAME)
{
APSPut(pMessageInfo->dataLength);
}
APSPutArray( pMessageInfo->dataPointer, pMessageInfo->dataLength );
APSSend();
//du 是否应答
while (1){
APSTask();
if(APSIsConfirmed())
{
APSRemoveFrame();
ConsolePutString("send successfully\n");
return apsTransId;
}
else if( APSIsTimedOut()){
APSRemoveFrame();
//du 发送的数据包没有应答则产生路由错误
gen_rerr(route->next_ip);
ConsolePutString("send failed\n");
return TRANS_ID_INVALID;
}
}
}
/*********************************************************************
* Function: static void APSPutHeader(NODE_INFO *dest,
* BYTE frameCON)
*
*
* PreCondition: APSIsPutReady() = TRUE
*
* Input: dest - destination node address info
* frameCON - APS frame control info
*
* Output: None
*
* Side Effects: None
*
* Overview: Construct new APS frame header and load it in
* RF TX buffer.
*
* Note: None
********************************************************************/
static void APSPutHeader(NODE_INFO *dest, BYTE frameCON, SHORT_ADDR dest_nwk_addr)
{
BYTE deliveryMode;
// Load NWK header.
NWKPutHeader(dest,
NWK_FRAME_DATA |
NWK_PROT_VER,
0x00,
dest_nwk_addr);
#ifdef ROUTE_MONITOR
struct Route_Table_Entry *route = lookup_route(dest_nwk_addr.Val);
APSPut(1);
APSPut(macInfo.shortAddr.byte.LSB);
#endif
// And frame control byte.
APSPut(frameCON);
// If this is a command frame, then the APS header contains no
// more information, and we are done.
if ( (frameCON & APS_FRAME_TYPE_MASK) == APS_FRAME_COMMAND )
return;
// Extract current delivery mode.
deliveryMode = frameCON & APS_DELIVERY_MODE_MASK;
#ifdef I_AM_COORDINATOR
// Packets from the coordinator always have the destination EP.
APSPut(apsCurrentFrame.destEP);
#else
// If we're an end device, only direct and broadcast frames will have
// a destination EP.
if ( deliveryMode == APS_DELIVERY_DIRECT ||
deliveryMode == APS_DELIVERY_BROADCAST )
{
APSPut(apsCurrentFrame.destEP);
}
#endif
// Put the cluster ID.
APSPut(apsCurrentFrame.clusterID);
// Put the profile ID.
APSPut(apsCurrentFrame.profileID.byte.LSB);
APSPut(apsCurrentFrame.profileID.byte.MSB);
// Put the source EP only if it is present. It will be present UNLESS the
// delivery mode is indirect and the destination address is present.
if (!((deliveryMode == APS_DELIVERY_INDIRECT) &&
(((APS_FRAME_CON*)&frameCON)->bits.indirectAddressMode == APS_DESTINATION_EP_PRESENT )))
{
APSPut(apsCurrentFrame.srcEP);
}
}
/*********************************************************************
* Function: static BOOL SetEPDataReady(BYTE ep)
*
*
* PreCondition: None
*
* Input: ep - Endpoint that is to be matched.
*
* Output: TRUE if given EP found and there is no overflow
* FALSE otherwise
*
* Side Effects: None
*
* Overview: This function looks up the list of opened
* end points and tries to find the indicated endpoint.
* If it finds it, it sets the bIsDataReady flag.
* If the broadcast endpoint is passed in, all open
* endpoints except the ZDO endpoint are set to ready.
* If at least one endpoint could accept the data
* without overflow, TRUE is returned.
*
* Note: None
********************************************************************/
static BOOL SetEPDataReady( BYTE ep )
{
BYTE i;
BOOL status = FALSE;
//NODE_SIMPLE_DESCRIPTOR simpleDescriptor;
for (i=0; i<NUM_DEFINED_ENDPOINTS; i++ )
{
if (epList[i].flags.bits.bIsInUse)
{
//ProfileGetSimpleDesc( &simpleDescriptor, i );
//if ((simpleDescriptor.Endpoint == ep) ||
//((ep == BROADCAST_EP) && (simpleDescriptor.Endpoint != 0)))
//不支持应用层广播
if (i == ep)
{
if ( epList[i].flags.bits.bIsDataReady == 1 )
{
ConsolePutString("APS: An EP has overflowed.\r\n");
epList[i].flags.bits.bIsOverflow = 1;
}
else
{
epList[i].flags.bits.bIsDataReady = 1;
status = TRUE;
}
}
}
}
return status;
}
/*********************************************************************
* Function: static BOOL APSGetHeader(void)
*
*
* PreCondition: NWKGetHeader() is already
* called.
*
* Input: None
*
* Output: TRUE RX buffer contains valid APS frame.
* FALSE, otherwise
*
* Side Effects: None
*
* Overview: Fetch rx buffer bytes and check to see if
* it is a valid APS frame header.
*
* Note: None
********************************************************************/
static BOOL APSGetHeader(void)
{
// At this point, there must be some data paylond in the frame.
if ( APSGetDataLen() < 1 )
return FALSE;
// Fetch frame control
apsCurrentFrame.frameCON.Val = APSGet();
// Extract and remember delivery mode.
apsCurrentFrame.deliveryMode = apsCurrentFrame.frameCON.Val & APS_DELIVERY_MODE_MASK;
// Make sure that deliveryMode is not using reserved mode.
if (apsCurrentFrame.deliveryMode == APS_DELIVERY_RESERVED)
return FALSE;
// Destination EP will be present UNLESS the delivery mode is indirect and the source
// address is present.
if (!((apsCurrentFrame.deliveryMode == APS_DELIVERY_INDIRECT) &&
(apsCurrentFrame.frameCON.bits.indirectAddressMode == APS_SOURCE_EP_PRESENT )))
{
apsCurrentFrame.destEP = APSGet();
}
// Data and APS acknowledge frames will contain the cluster ID.
if ( ((apsCurrentFrame.frameCON.Val & APS_FRAME_TYPE_MASK) == APS_FRAME_DATA ) ||
((apsCurrentFrame.frameCON.Val & APS_FRAME_TYPE_MASK) == APS_FRAME_ACKNOWLEDGE ) )
{
apsCurrentFrame.clusterID = APSGet();
}
// Profile ID is now always sent.
apsCurrentFrame.profileID.byte.LSB = APSGet();
apsCurrentFrame.profileID.byte.MSB = APSGet();
// Get source endpoint byte, if present. If will be present UNLESS the
// delivery mode is indirect and the destination endpoint is present.
if (!((apsCurrentFrame.deliveryMode == APS_DELIVERY_INDIRECT) &&
(apsCurrentFrame.frameCON.bits.indirectAddressMode == APS_DESTINATION_EP_PRESENT )))
{
apsCurrentFrame.srcEP = APSGet();
}
// Remember that we have already processed this frame.
apsCurrentFrame.Flags.bits.bIsInProcess = TRUE;
apsCurrentFrame.payload = NWKPayload;
return TRUE;
}
/*********************************************************************
* Function: void APSDiscard(void)
*
* PreCondition: APSSetEP() is called with valid EP handle.
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Clears internal flag indicating that this EP
* is done processing the current frame. If all
* endpoints are done with the current frame, the
* frame is released.
*
* Note: None
********************************************************************/
void APSDiscardRx( void )
{
EP *epPtr;
BYTE i;
pCurrentEP->flags.bits.bIsDataReady = FALSE;
NWKPayload = apsCurrentFrame.payload;
NWKPayloadLength = NWKPayloadLengthSave;
// See if all of the endpoints are done with the frame. If any
// endpoint still needs this packet, return.
epPtr = (EP*)&epList[0];
for ( i =0; i < NUM_DEFINED_ENDPOINTS; i++, epPtr++)
{
if (epPtr->flags.bits.bIsDataReady)
{
return;
}
}
// All of the endpoints are done with the frame, so release it.
NWKDiscardRx();
apsCurrentFrame.Flags.bits.bIsInProcess = FALSE;
ConsolePutString("discard\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -