zigbee消息的处理流程

1)  消息的注册

首先我们需要申请注册,协议栈将我们的申请备案保存,然后当有消息事件时,会通知申请过的任务ID。

在函数void ZDApp_RegisterCBs( void )【ZDApp.c】中进行注册,由函数ZDO_RegisterForZDOMsg()【ZDProfile.c】将cluster ID(即OTA接收到的消息,如NWK_addr_rsp)和任务ID进行注册,当有响应消息时会触发ZDO_CB_MSG事件通知应用层。

/*********************************************************************

 * @fn          ZDO_RegisterForZDOMsg

 *

 * @brief       Call this function to register of an incoming over the air ZDO message - probably a response message but requests can also be received. Messages are delivered to the task with ZDO_CB_MSG as the message ID.

* @param       taskID - Where you would like the message delivered

 * @param       clusterID - What message?

 *

 * @return      ZSuccess - successful, ZMemError if not

 */

ZStatus_t ZDO_RegisterForZDOMsg( uint8 taskID, uint16 clusterID )

{

  ZDO_MsgCB_t *pList;

  ZDO_MsgCB_t *pLast;

  ZDO_MsgCB_t *pNew;

 

  // Look for duplicate

  pList = pLast = zdoMsgCBs;  //指针指向ZDO消息列表

  while ( pList ) //先查找,如果有注册则返回成功

  {

    if ( pList->taskID == taskID && pList->clusterID == clusterID )

      return ( ZSuccess );

    pLast = pList;

    pList = (ZDO_MsgCB_t *)pList->next;  //指向下一个链表节点

  }

 

  // Add to the list  如果原ZDO消息列表中无注册,添加一个新的注册记录

  pNew = (ZDO_MsgCB_t *)osal_mem_alloc( sizeof ( ZDO_MsgCB_t ) );

  if ( pNew ) //若分配空间成功

  {

    pNew->taskID = taskID;

    pNew->clusterID = clusterID;

    pNew->next = NULL;

    if ( zdoMsgCBs ) //若原来的链表非空,在链表后面添加

    {

      pLast->next = pNew;

    }

    else //若原来的链表为空,作为链表的第一项

      zdoMsgCBs = pNew;

    return ( ZSuccess );

  }

  else

    return ( ZMemError );

}

该函数在中ZDApp_RegisterCBs调用:

/*********************************************************************

 * @fn      ZDApp_RegisterCBs()

* @brief   Process response messages

* @param   none

 * @return  none

 */

void ZDApp_RegisterCBs( void )

{

#if defined ( ZDO_IEEEADDR_REQUEST ) || defined ( REFLECTOR )

  ZDO_RegisterForZDOMsg( ZDAppTaskID, IEEE_addr_rsp );

#endif

#if defined ( ZDO_NWKADDR_REQUEST ) || defined ( REFLECTOR )

  ZDO_RegisterForZDOMsg( ZDAppTaskID, NWK_addr_rsp );

#endif  

#if ZG_BUILD_COORDINATOR_TYPE

  ZDO_RegisterForZDOMsg( ZDAppTaskID, Bind_rsp );

  ZDO_RegisterForZDOMsg( ZDAppTaskID, Unbind_rsp );

  ZDO_RegisterForZDOMsg( ZDAppTaskID, End_Device_Bind_req );

#endif

#if defined ( REFLECTOR )

  ZDO_RegisterForZDOMsg( ZDAppTaskID, Bind_req );

  ZDO_RegisterForZDOMsg( ZDAppTaskID, Unbind_req );

#endif  

}

 

ZDO_RegisterForZDOMsg()
Call this function to request an over-the-air message. A copy of the message will be sent to a task in an OSALmessage. The task receiving the message can either parse the message themselves or call a ZDO Parser function toparse the message. Only response messages have a ZDO Parser function.After registering for a message, and the message is received (OTA), the message is sent to the application/task as aZDO_CB_MSG (OSAL Msg). The body of the message (zdoIncomingMsg_t – defined in ZDProfile.h) contains the
OTA message.

程序原型(prototype)

ZStatus_t ZDO_RegisterForZDOMsg( uint8 taskID, uint16 clusterID );
参数详解(Parameter Details)
taskID – the application’s task ID. This will be used to send the OSAL message.
clusterID – the over the air message’s clusterID that you would like to receive (example: NWK_addr_rsp).
These are defined in ZDProfile.h.
Return
ZStatus_t –status values defined in ZStatus_t in ZComDef.h,

2)  去掉ZDO消息的注册

/*********************************************************************

 * @fn          ZDO_RemoveRegisteredCB

 * @brief       Call this function if you don't want to receive the incoming message.

 * @param       taskID - Where the messages are being delivered.

 * @param       clusterID - What message?

 * @return      ZSuccess - successful, ZFailure if not found

 */

ZStatus_t ZDO_RemoveRegisteredCB( uint8 taskID, uint16 clusterID )

{

3)  向注册的taskID发送消息ZDO_CB_MSG

/*********************************************************************

 * @fn          ZDO_SendMsgCBs

 *

 * @brief       This function sends messages to registered tasks.

 *              Local to ZDO and shouldn't be called outside of ZDO.

 *

 * @param       inMsg - incoming message

 *

 * @return      TRUE if sent to at least 1 task, FALSE if not

 */

uint8 ZDO_SendMsgCBs( zdoIncomingMsg_t *inMsg )

{

  uint8 ret = FALSE;

  ZDO_MsgCB_t *pList = zdoMsgCBs;

  while ( pList )

  {

    if ( pList->clusterID == inMsg->clusterID )

    {

      zdoIncomingMsg_t *msgPtr;

 

      // Send the address to the task

      msgPtr = (zdoIncomingMsg_t *)osal_msg_allocate( sizeof( zdoIncomingMsg_t ) + inMsg->asduLen );

      if ( msgPtr )

      {

        // copy struct

        osal_memcpy( msgPtr, inMsg, sizeof( zdoIncomingMsg_t ));

 

        if ( inMsg->asduLen )

        {

          msgPtr->asdu = (byte*)(((byte*)msgPtr) + sizeof( zdoIncomingMsg_t ));

          osal_memcpy( msgPtr->asdu, inMsg->asdu, inMsg->asduLen );

        }

 

        msgPtr->hdr.event = ZDO_CB_MSG;

        osal_msg_send( pList->taskID, (uint8 *)msgPtr );

        ret = TRUE;

      }

    }

    pList = (ZDO_MsgCB_t *)pList->next;

  }

  return ( ret );

}

4)  消息处理GenericApp_ProcessZDOMsgs()【在应用层源文件中】

      switch ( MSGpkt->hdr.event )

      {

        case ZDO_CB_MSG:

          GenericApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );

          break;

注意SampleApp_MessageMSGCB()【SampleApp.c应用对应的源文件】函数一般是对应消息AF_INCOMING_MSG_CMD的处理函数

         switch ( MSGpkt->hdr.event )

      {

             case AF_INCOMING_MSG_CMD:

          GenericApp_MessageMSGCB( MSGpkt );

          break;

你可能感兴趣的:(function,prototype,cmd,application,byte,任务)