⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zdprofile.c

📁 Zigbee2007.rar
💻 C
📖 第 1 页 / 共 5 页
字号:
{
  uint8 *buf;
  uint8 *pBuf;
  // Status + RoutingTableEntries + StartIndex + RoutingListCount.
  byte len = 1 + 1 + 1 + 1;
  byte x;

  // Add an array for Routing List data
  len += (RoutingListCount * ZDP_ROUTINGENTRY_SIZE);

  buf = osal_mem_alloc( (short)(len+1) );
  if ( buf == NULL )
  {
    return afStatus_MEM_FAIL;
  }

  pBuf = buf+1;

  *pBuf++ = Status;
  *pBuf++ = RoutingTableEntries;
  *pBuf++ = StartIndex;
  *pBuf++ = RoutingListCount;

  for ( x = 0; x < RoutingListCount; x++ )
  {
    *pBuf++ = LO_UINT16( RoutingTableList->dstAddress );  // Destination Address
    *pBuf++ = HI_UINT16( RoutingTableList->dstAddress );
    *pBuf++ = RoutingTableList->status;
    *pBuf++ = LO_UINT16( RoutingTableList->nextHopAddress );  // Next hop
    *pBuf++ = HI_UINT16( RoutingTableList->nextHopAddress );
    RoutingTableList++;    // Move to next list entry
  }

  FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Rtg_rsp, len, buf );
}

/*********************************************************************
 * @fn          ZDP_MgmtBindRsp
 *
 * @brief       This builds and send a Mgmt_Bind_rsp message. This
 *              function sends a unicast message.
 *
 * @param       dstAddr - destination address of the message
 * @param       Status - message status (ZDP_SUCCESS or other)
 * @param       BindingTableEntries - Total number of entries
 * @param       StartIndex - Starting index within the reporting list
 * @param       BindingTableListCount - number of entries included
 *                                 in this message
 * @param       BindingTableList - List of Binding Table entries
 * @param       SecurityEnable - Security Options
 *
 * @return      ZStatus_t
 */
ZStatus_t ZDP_MgmtBindRsp( byte TransSeq, zAddrType_t *dstAddr,
                            byte Status,
                            byte BindingTableEntries,
                            byte StartIndex,
                            byte BindingTableListCount,
                            apsBindingItem_t *BindingTableList,
                            byte SecurityEnable )
{
  uint8 *buf;
  uint8 *pBuf;
  uint8 maxLen; // maxLen is the maximum packet length to allocate enough memory space
  uint8 len;    // Actual length varies due to different addrMode
  uint8 x;
  byte extZdpBindEntrySize = ZDP_BINDINGENTRY_SIZE + 1 + 1; // One more byte for cluserID and DstAddrMode
  byte shortZdpBindEntrySize = ZDP_BINDINGENTRY_SIZE + 1 + 1 + 2 - 8 - 1; // clusterID + DstAddrMode + shortAddr - ExtAddr - DstEndpoint

  // Status + BindingTableEntries + StartIndex + BindingTableListCount.
  maxLen = 1 + 1 + 1 + 1;
  maxLen += (BindingTableListCount * extZdpBindEntrySize );  //max length
  buf = osal_mem_alloc( maxLen + 1 );  // +1 for transaction ID

  if ( buf == NULL )
  {
    return afStatus_MEM_FAIL;
  }

  pBuf = buf+1;

  *pBuf++ = Status;
  *pBuf++ = BindingTableEntries;
  *pBuf++ = StartIndex;
  *pBuf++ = BindingTableListCount;

  // Initial length = Status + BindingTableEntries + StartIndex + BindingTableListCount.
  // length += ZDP_BINDINGENTRY_SIZE   -- Version 1.0
  //           extZdpBindEntrySize     -- Version 1.1 extended address mode
  //           shortZdpBindEntrySize   -- Version 1.1 group address mode

  len = 1 + 1 + 1 + 1;
  for ( x = 0; x < BindingTableListCount; x++ )
  {
    pBuf = osal_cpyExtAddr( pBuf, BindingTableList->srcAddr );
    *pBuf++ = BindingTableList->srcEP;

    // Cluster ID
    *pBuf++ = LO_UINT16( BindingTableList->clusterID );
    *pBuf++ = HI_UINT16( BindingTableList->clusterID );

    *pBuf++ = BindingTableList->dstAddr.addrMode;
    if ( BindingTableList->dstAddr.addrMode == Addr64Bit )
    {
      len += extZdpBindEntrySize;
      pBuf = osal_cpyExtAddr( pBuf, BindingTableList->dstAddr.addr.extAddr );
      *pBuf++ = BindingTableList->dstEP;
    }
    else
    {
      len += shortZdpBindEntrySize;
      *pBuf++ = LO_UINT16( BindingTableList->dstAddr.addr.shortAddr );
      *pBuf++ = HI_UINT16( BindingTableList->dstAddr.addr.shortAddr );
    }
    BindingTableList++;    // Move to next list entry
  }

  FillAndSendBuffer( &TransSeq, dstAddr, Mgmt_Bind_rsp, len, buf );
}

/*********************************************************************
 * @fn          ZDP_MgmtNwkUpdateNotify
 *
 * @brief       This builds and send a Mgmt_NWK_Update_notify message. This
 *              function sends a unicast message.
 *
 * @param       dstAddr - destination address of the message
 * @param       status - message status (ZDP_SUCCESS or other)
 * @param       scannedChannels - List of channels scanned by the request
 * @param       totalTransmissions - Total transmissions
 * @param       transmissionFailures - Sum of transmission failures
 * @param       listCount - Number of records contained in the energyValues list
 * @param       energyValues - List of descriptors, one for each of ListCount,
 *                             of the enegry detect descriptors
 * @param       txOptions - Transmit options
 * @param       securityEnable - Security options
 *
 * @return      afStatus_t
 */
afStatus_t ZDP_MgmtNwkUpdateNotify( uint8 TransSeq, zAddrType_t *dstAddr,
                                    uint8 status, uint32 scannedChannels,
                                    uint16 totalTransmissions, uint16 transmissionFailures,
                                    uint8 listCount, uint8 *energyValues, uint8 txOptions,
                                    uint8 securityEnable )
{
  uint8 *buf;
  uint8 *pBuf;
  uint8 len;

  // Status + ScannedChannels + totalTransmissions + transmissionFailures + ListCount + energyValues
  len = 1 + 4 + 2 + 2 + 1 + listCount;

  buf = osal_mem_alloc( len+1 ); // +1 for transaction ID
  if ( buf == NULL )
  {
    return afStatus_MEM_FAIL;
  }

  pBuf = buf+1;

  *pBuf++ = status;

  pBuf = osal_buffer_uint32( pBuf, scannedChannels );

  *pBuf++ = LO_UINT16( totalTransmissions );
  *pBuf++ = HI_UINT16( totalTransmissions );

  *pBuf++ = LO_UINT16( transmissionFailures );
  *pBuf++ = HI_UINT16( transmissionFailures );

  *pBuf++ = listCount;

  if ( listCount > 0 )
    osal_memcpy( pBuf, energyValues, listCount );

  FillAndSendBufferTxOptions( &TransSeq, dstAddr, Mgmt_NWK_Update_notify, len, buf, txOptions );
}

/*********************************************************************
 * Functions to register for ZDO Over-the-air messages
 */

/*********************************************************************
 * @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 = 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 );
}

/*********************************************************************
 * @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 )
{
  ZDO_MsgCB_t *pList;
  ZDO_MsgCB_t *pLast = NULL;

  pList = zdoMsgCBs;
  while ( pList )
  {
    if ( pList->taskID == taskID && pList->clusterID == clusterID )
    {
      if ( pLast )
      {
        // remove this one from the linked list
        pLast->next = pList->next;
      }
      else if ( pList->next )
      {
        // remove the first one from the linked list
        zdoMsgCBs = pList->next;
      }
      else
      {
        // remove the only item from the list
        zdoMsgCBs = (ZDO_MsgCB_t *)NULL;
      }
      osal_mem_free( pList );
      return ( ZSuccess );
    }
    pLast = pList;
    pList = pList->next;
  }

  return ( ZFailure );
}

/*********************************************************************
 * @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 );
}

/*********************************************************************
 * Incoming message processor
 */

/*********************************************************************
 * @fn          ZDP_IncomingData
 *
 * @brief       This function indicates the transfer of a data PDU (ASDU)
 *              from the APS sub-layer to the ZDO.
 *
 * @param       pData - Incoming Message
 *
 * @return      none
 */
void ZDP_IncomingData( afIncomingMSGPacket_t *pData )
{
  uint8 x = 0;
  uint8 handled;
  zdoIncomingMsg_t inMsg;

  inMsg.srcAddr.addrMode = Addr16Bit;
  inMsg.srcAddr.addr.shortAddr = pData->srcAddr.addr.shortAddr;
  inMsg.wasBroadcast = pData->wasBroadcast;
  inMsg.clusterID = pData->clusterId;
  inMsg.SecurityUse = pData->SecurityUse;

  inMsg.asduLen = pData->cmd.DataLength-1;
  inMsg.asdu = pData->cmd.Data+1;
  inMsg.TransSeq = pData->cmd.Data[0];
  inMsg.macDestAddr = pData->macDestAddr;

  handled = ZDO_SendMsgCBs( &inMsg );

#if defined( MT_ZDO_CB_FUNC )
  MT_ZdoDirectCB( pData, &inMsg );
#endif

  while ( zdpMsgProcs[x].clusterID != 0xFFFF )
  {
    if ( zdpMsgProcs[x].clusterID == inMsg.clusterID )
    {
      zdpMsgProcs[x].pFn( &inMsg );
      return;
    }
    x++;
  }

  // Handle unhandled messages
  if ( !handled )
    ZDApp_InMsgCB( &inMsg );
}

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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -