/*********************************************************************
* @fn afBuildMSGIncoming
*
* @brief Build the message for the app
*
* @param
*
* @return pointer to next in data buffer
*/
static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp )
{
afIncomingMSGPacket_t *MSGpkt;
const uint8 len = sizeof( afIncomingMSGPacket_t ) + aff->asduLength;
uint8 *asdu = aff->asdu;
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_allocate( len );
if ( MSGpkt == NULL )
{
return;
}
MSGpkt->hdr.event = AF_INCOMING_MSG_CMD;
MSGpkt->groupId = aff->GroupID;
MSGpkt->clusterId = aff->ClusterID;
afCopyAddress( &MSGpkt->srcAddr, SrcAddress );
MSGpkt->srcAddr.endPoint = aff->SrcEndPoint;
MSGpkt->endPoint = epDesc->endPoint;
MSGpkt->wasBroadcast = aff->wasBroadcast;
MSGpkt->LinkQuality = sig->LinkQuality;
MSGpkt->correlation = sig->correlation;
MSGpkt->rssi = sig->rssi;
MSGpkt->SecurityUse = SecurityUse;
MSGpkt->timestamp = timestamp;
MSGpkt->nwkSeqNum = nwkSeqNum;
MSGpkt->macDestAddr = aff->macDestAddr;
MSGpkt->srcAddr.panId = SrcPanId;
MSGpkt->cmd.TransSeqNumber = 0;
MSGpkt->cmd.DataLength = aff->asduLength;
if ( MSGpkt->cmd.DataLength )
{
MSGpkt->cmd.Data = (uint8 *)(MSGpkt + 1);
osal_memcpy( MSGpkt->cmd.Data, asdu, MSGpkt->cmd.DataLength );
}
else
{
MSGpkt->cmd.Data = NULL;
}
#if defined ( MT_AF_CB_FUNC )
// If ZDO or SAPI have registered for this endpoint, dont intercept it here
if (AFCB_CHECK(CB_ID_AF_DATA_IND, *(epDesc->task_id)))
{
MT_AfIncomingMsg( (void *)MSGpkt );
// Release the memory.
osal_msg_deallocate( (void *)MSGpkt );
}
else
#endif
{
// Send message through task message.
osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
}
}
/*********************************************************************
* @fn afIncomingData
*
* @brief Transfer a data PDU (ASDU) from the APS sub-layer to the AF.
*
* @param aff - pointer to APS frame format
* @param SrcAddress - Source address
* @param SrcPanId - Source PAN ID
* @param sig - incoming message's link quality
* @param nwkSeqNum - incoming network sequence number (from nwk header frame)
* @param SecurityUse - Security enable/disable
* @param timestamp - the MAC Timer2 timestamp at Rx.
*
* @return none
*/
void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
NLDE_Signal_t *sig, uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp )
{
endPointDesc_t *epDesc = NULL;
epList_t *pList = epList;
#if !defined ( APS_NO_GROUPS )
uint8 grpEp = APS_GROUPS_EP_NOT_FOUND;
#endif
if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
{
#if !defined ( APS_NO_GROUPS )
// Find the first endpoint for this group
grpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );
if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
return; // No endpoint found
epDesc = afFindEndPointDesc( grpEp );
if ( epDesc == NULL )
return; // Endpoint descriptor not found
pList = afFindEndPointDescList( epDesc->endPoint );
#else
return; // Not supported
#endif
}
else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
{//广播就拿到第一个节点
// Set the list
if ( pList != NULL )
{//从第一个开始,第0个是端点0么,记得好像不是,广播会播给端点0么
//理解错了,这个端点描述符仅仅是他的一个域,所以还是第0个开始
epDesc = pList->epDesc;
}
}
else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) )
{//点播,在AF注册过的端点对应的端点描述符,pList指向我们目标端点的端点描述符
pList = afFindEndPointDescList( epDesc->endPoint );
}
while ( epDesc )
{//如果有目标端点描述符
uint16 epProfileID = 0xFFFF; // Invalid Profile ID
if ( pList->pfnDescCB )
{
uint16 *pID = (uint16 *)(pList->pfnDescCB(
AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));
if ( pID )
{
epProfileID = *pID;
osal_mem_free( pID );
}
}
else if ( epDesc->simpleDesc )
{
epProfileID = epDesc->simpleDesc->AppProfId;
}
if ( (aff->ProfileID == epProfileID) ||
((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) )
{//可见端点0还是会经来
{
// Save original endpoint
uint8 endpoint = aff->DstEndPoint;
// overwrite with descriptor's endpoint
aff->DstEndPoint = epDesc->endPoint;
afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig,
nwkSeqNum, SecurityUse, timestamp );
// Restore with original endpoint
aff->DstEndPoint = endpoint;
}
}
if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
{//组播处理
#if !defined ( APS_NO_GROUPS )
// Find the next endpoint for this group
grpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );
if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
return; // No endpoint found
epDesc = afFindEndPointDesc( grpEp );
if ( epDesc == NULL )
return; // Endpoint descriptor not found
pList = afFindEndPointDescList( epDesc->endPoint );
#else
return;
#endif
}
else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
{//广播处理
pList = pList->nextDesc;
if ( pList )
epDesc = pList->epDesc;
else
epDesc = NULL;
}
else//点播处理
epDesc = NULL;
}
}
AF.h (c:\texas instruments\...\af):375
* afIncomingData - APS will call this function when an incoming
* message is received.
*/
extern void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
NLDE_Signal_t *sig, uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp );
epList_t *epList;在AF.c文件中
typedef struct _epList_t {
struct _epList_t *nextDesc;
endPointDesc_t *epDesc;
pDescCB pfnDescCB; // Don't use if this function pointer is NULL.
afAPSF_Config_t apsfCfg;
eEP_Flags flags;
} epList_t;在AF.h文件中
//可以理解成把端点描述符合指针串起来一个链表,epList是这个链表中节点指针,指向表头
// Register the endpoint description with the AF
afRegister( &SampleApp_epDesc );
/*********************************************************************
* @fn afRegister
*
* @brief Register an Application's EndPoint description.
*
* @param epDesc - pointer to the Application's endpoint descriptor.
*
* NOTE: The memory that epDesc is pointing to must exist after this call.
*
* @return afStatus_SUCCESS - Registered
* afStatus_MEM_FAIL - not enough memory to add descriptor
* afStatus_INVALID_PARAMETER - duplicate endpoint
*/
afStatus_t afRegister( endPointDesc_t *epDesc )
{
if (afFindEndPointDescList(epDesc->endPoint)) // Look for duplicate endpoint.
{//如果注册了,那么就不能注册,没有就注册,侧面证明了,每个端点只能被一个任务注册
return afStatus_INVALID_PARAMETER;
}
return ((NULL == afRegisterExtended(epDesc, NULL)) ? afStatus_MEM_FAIL : afStatus_SUCCESS);
}
/*********************************************************************
* @fn afFindEndPointDescList
*
* @brief Find the endpoint description entry from the endpoint
* number.
*
* @param EndPoint - Application Endpoint to look for
*
* @return the address to the endpoint/interface description entry
*/
static epList_t *afFindEndPointDescList( uint8 EndPoint )
{//从链表中通过端点,来在端点描述符列表中搜索,有没有这个端点对应的端点描述符被注册,有就返回,没有返回NULL
epList_t *epSearch;
for (epSearch = epList; epSearch != NULL; epSearch = epSearch->nextDesc)
{
if (epSearch->epDesc->endPoint == EndPoint)
{
break;
}
}
return epSearch;
}
/*********************************************************************
* @fn afRegisterExtended
*
* @brief Register an Application's EndPoint description.
*
* @param epDesc - pointer to the Application's endpoint descriptor.
* @param descFn - pointer to descriptor callback function
*
* NOTE: The memory that epDesc is pointing to must exist after this call.
*
* @return Pointer to epList_t on success, NULL otherwise.
*/
epList_t *afRegisterExtended( endPointDesc_t *epDesc, pDescCB descFn )
{//从这里看建立是从右边到左边,epList头不断向新的头滑动
epList_t *ep = osal_mem_alloc(sizeof(epList_t));
if (ep != NULL)
{
ep->nextDesc = epList;
epList = ep;
ep->epDesc = epDesc;
ep->pfnDescCB = descFn;
ep->apsfCfg.frameDelay = APSF_DEFAULT_INTERFRAME_DELAY;
ep->apsfCfg.windowSize = APSF_DEFAULT_WINDOW_SIZE;
ep->flags = eEP_AllowMatch; // Default to allow Match Descriptor.
}
return ep;
}