Zstack杂乱笔记2

来源:互联网 发布:node schedule 文档 编辑:程序博客网 时间:2024/05/16 12:02

Zstack的SerialApp 例子中,是怎么接受空气中的信息以及是怎样对信息进行处理的?接收了信息最终要用下面这个函数来处理,但是在哪使taskArrs[]中相对应的元素置为非零呢?也就是在哪产生了SYS_EVENT_MSG事件,并且附带消息为ZDO_CB_MSG。

/********************************************************************* * @fn      SerialApp_ProcessEvent * * @brief   Generic Application Task event processor. * * @param   task_id  - The OSAL assigned task ID. * @param   events   - Bit map of events to process. * * @return  Event flags of all unprocessed events. */UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events ){  (void)task_id;  // Intentionally unreferenced parameter#if defined ( AUTO_BIND )  zAddrType_t txAddr;  #endif    if ( events & SYS_EVENT_MSG )  {    afIncomingMSGPacket_t *MSGpkt;    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SerialApp_TaskID )) )    {      switch ( MSGpkt->hdr.event )      {      case ZDO_CB_MSG:        SerialApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );        break;                case KEY_CHANGE:        SerialApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );        break;      case AF_INCOMING_MSG_CMD:        SerialApp_ProcessMSGCmd( MSGpkt );        break;#if defined ( AUTO_BIND )      case ZDO_STATE_CHANGE:     SerialApp_NwkState = (devStates_t)(MSGpkt->hdr.status);        if ( (SerialApp_NwkState == DEV_ZB_COORD)      || (SerialApp_NwkState == DEV_ROUTER)      || (SerialApp_NwkState == DEV_END_DEVICE) )    {             HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );                        // Initiate an End Device Bind Request for the mandatory endpoint            txAddr.addrMode = Addr16Bit;            txAddr.addr.shortAddr = 0x0000; // Coordinator            ZDP_EndDeviceBindReq( &txAddr, NLME_GetShortAddr(),                                   SerialApp_epDesc.endPoint,                                  SERIALAPP_PROFID,                                  SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,                                  SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,                                  FALSE );            }        break;#endif      default:        break;      }      osal_msg_deallocate( (uint8 *)MSGpkt );    }    return ( events ^ SYS_EVENT_MSG );  }  if ( events & SERIALAPP_SEND_EVT )  {    SerialApp_Send();    return ( events ^ SERIALAPP_SEND_EVT );  }  if ( events & SERIALAPP_RESP_EVT )  {    SerialApp_Resp();    return ( events ^ SERIALAPP_RESP_EVT );  }  return ( 0 );  // Discard unknown events.}

/********************************************************************* * @fn      SerialApp_ProcessZDOMsgs() * * @brief   Process response messages * * @param   none * * @return  none */static void SerialApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg ){  switch ( inMsg->clusterID )  {    case End_Device_Bind_rsp:      if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )      {        // Light LED        HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );      }#if defined(BLINK_LEDS)      else      {        // Flash LED to show failure        HalLedSet ( HAL_LED_4, HAL_LED_MODE_FLASH );      }#endif      break;          case Match_Desc_rsp:      {        ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );        if ( pRsp )        {          if ( pRsp->status == ZSuccess && pRsp->cnt )          {            SerialApp_TxAddr.addrMode = (afAddrMode_t)Addr16Bit;            SerialApp_TxAddr.addr.shortAddr = pRsp->nwkAddr;            // Take the first endpoint, Can be changed to search through endpoints            SerialApp_TxAddr.endPoint = pRsp->epList[0];                        // Light LED            HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );          }          osal_mem_free( pRsp );        }      }      break;  }}

在哪里注册了函数要用SerialApp_ProcessEvent来处理空气中发来的消息???发出了SYS_EVENT_MSG事件,消息为ZDO_CB_MSG,在哪注册了???
在void SerialApp_Init( uint8 task_id )中明明写着,

ZDO_RegisterForZDOMsg( SerialApp_TaskID, End_Device_Bind_rsp );//

 ZDO_RegisterForZDOMsg( SerialApp_TaskID, Match_Desc_rsp );

#define End_Device_Bind_rsp     (End_Device_Bind_req | ZDO_RESPONSE_BIT)

#define End_Device_Bind_req     ((uint16)0x0020)

#define ZDO_RESPONSE_BIT        ((uint16)0x8000)

#define Match_Desc_rsp          (Match_Desc_req | ZDO_RESPONSE_BIT)

#define Match_Desc_req          ((uint16)0x0006)

#define ZDO_CB_MSG                0xD3    // ZDO incoming message callback

/********************************************************************* * @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;  while ( pList )  {    if ( pList->taskID == taskID && pList->clusterID == clusterID )      return ( ZSuccess );    pLast = pList;    pList = (ZDO_MsgCB_t *)pList->next;  }  // Add to the list  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 );}

typedef struct
{
  void *next;
  uint8 taskID;
  uint16 clusterID;
} ZDO_MsgCB_t;

ZDO_MsgCB_t *zdoMsgCBs = (ZDO_MsgCB_t *)NULL;


uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr )该函数应该被调用后,然后才能执行UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events ),我是这样认为的!

貌似要有突破!!

void ZDApp_Init( uint8 task_id ){  // Save the task ID  ZDAppTaskID = task_id;  // Initialize the ZDO global device short address storage  ZDAppNwkAddr.addrMode = Addr16Bit;  ZDAppNwkAddr.addr.shortAddr = INVALID_NODE_ADDR;  (void)NLME_GetExtAddr();  // Load the saveExtAddr pointer.  // Check for manual "Hold Auto Start"  ZDAppCheckForHoldKey();  // Initialize ZDO items and setup the device - type of device to create.  ZDO_Init();  // Register the endpoint description with the AF  // This task doesn't have a Simple description, but we still need  // to register the endpoint.  afRegister( (endPointDesc_t *)&ZDApp_epDesc );#if defined( ZDO_USERDESC_RESPONSE )  ZDApp_InitUserDesc();#endif // ZDO_USERDESC_RESPONSE  // Start the device?  if ( devState != DEV_HOLD )  {    ZDOInitDevice( 0 );  }  else  {    ZDOInitDevice( ZDO_INIT_HOLD_NWK_START );    // Blink LED to indicate HOLD_START    HalLedBlink ( HAL_LED_4, 0, 50, 500 );  }    // Initialize the ZDO callback function pointers zdoCBFunc[]  ZDApp_InitZdoCBFunc();    ZDApp_RegisterCBs();} /* ZDApp_Init() */



。。。。好吧暂时没搞出来!

这个函数包括了对不同IDcluster的处理,以及回应。

void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt ){  uint8 stat;  uint8 seqnb;  uint8 delay;  switch ( pkt->clusterId )  {  // A message with a serial data block to be transmitted on the serial port.  case SERIALAPP_CLUSTERID1:    // Store the address for sending and retrying.    osal_memcpy(&SerialApp_RxAddr, &(pkt->srcAddr), sizeof( afAddrType_t ));    seqnb = pkt->cmd.Data[0];    // Keep message if not a repeat packet    if ( (seqnb > SerialApp_RxSeq) ||                    // Normal        ((seqnb < 0x80 ) && ( SerialApp_RxSeq > 0x80)) ) // Wrap-around    {      // Transmit the data on the serial port.      if ( HalUARTWrite( SERIAL_APP_PORT, pkt->cmd.Data+1, (pkt->cmd.DataLength-1) ) )      {        // Save for next incoming message        SerialApp_RxSeq = seqnb;        stat = OTA_SUCCESS;      }      else      {        stat = OTA_SER_BUSY;      }    }    else    {      stat = OTA_DUP_MSG;    }    // Select approproiate OTA flow-control delay.    delay = (stat == OTA_SER_BUSY) ? SERIALAPP_NAK_DELAY : SERIALAPP_ACK_DELAY;    // Build & send OTA response message.    SerialApp_RspBuf[0] = stat;    SerialApp_RspBuf[1] = seqnb;    SerialApp_RspBuf[2] = LO_UINT16( delay );    SerialApp_RspBuf[3] = HI_UINT16( delay );    osal_set_event( SerialApp_TaskID, SERIALAPP_RESP_EVT );    osal_stop_timerEx(SerialApp_TaskID, SERIALAPP_RESP_EVT);    break;  // A response to a received serial data block.  case SERIALAPP_CLUSTERID2:    if ((pkt->cmd.Data[1] == SerialApp_TxSeq) &&       ((pkt->cmd.Data[0] == OTA_SUCCESS) || (pkt->cmd.Data[0] == OTA_DUP_MSG)))    {      SerialApp_TxLen = 0;// 准备下一次发送      osal_stop_timerEx(SerialApp_TaskID, SERIALAPP_SEND_EVT);    }    else    {      // Re-start timeout according to delay sent from other device.      delay = BUILD_UINT16( pkt->cmd.Data[2], pkt->cmd.Data[3] );      osal_start_timerEx( SerialApp_TaskID, SERIALAPP_SEND_EVT, delay );    }    break;    default:      break;  }}

参考:http://blog.163.com/a_hui8/blog/static/205830307201282085853248/

序列号问题:

第一种情况:

 // Keep message if not a repeat packet
    if ( (seqnb > SerialApp_RxSeq) ||                    // Normal正常,是否是最新的数据
        ((seqnb < 0x80 ) && ( SerialApp_RxSeq > 0x80)) ) // Wrap-around不过还是不太懂??

第二种情况:

// A response to a received serial data block.

 if ((pkt->cmd.Data[1] == SerialApp_TxSeq) &&//正常
       ((pkt->cmd.Data[0] == OTA_SUCCESS) || (pkt->cmd.Data[0] == OTA_DUP_MSG))) //成功或过期


static uint8 SerialApp_RxSeq;

 SerialApp_RxSeq = 0xC3;








原创粉丝点击