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

📄 zdobject.c

📁 Zigbee2006入门(源代码+文档讲解+系统推荐)
💻 C
📖 第 1 页 / 共 5 页
字号:
  else
    HalLcdWriteString( "Timeout", HAL_LCD_LINE_2 );
#endif

}
#endif // REFLECTOR

#if defined ( REFLECTOR ) || defined ( ZDO_COORDINATOR )
/*********************************************************************
 * @fn          ZDO_CompareClusterLists
 *
 * @brief       Compare one list to another list
 *
 * @param       numList1 - number of items in list 1
 * @param       list1 - first list of cluster IDs
 * @param       numList2 - number of items in list 2
 * @param       list2 - second list of cluster IDs
 * @param       pMatches - buffer to put matches
 *
 * @return      number of matches
 */
static byte ZDO_CompareClusterLists( byte numList1, uint16 *list1,
                          byte numList2, uint16 *list2, uint16 *pMatches )
{
  byte x, y;
  uint16 z;
  byte numMatches = 0;

  // Check the first in against the seconds out
  for ( x = 0; x < numList1; x++ )
  {
    for ( y = 0; y < numList2; y++ )
    {
      z = list2[y];
      if ( list1[x] == z )
        pMatches[numMatches++] = z;
    }
  }

  return ( numMatches );
}
#endif // REFLECTOR || ZDO_COORDINATOR

#if defined ( REFLECTOR )
/*********************************************************************
 * @fn          ZDO_DoEndDeviceBind
 *
 * @brief       Process the End Device Bind Req from ZDApp
 *
 * @param  bindReq  - Bind Request Information
 * @param  SecurityUse - Security enable/disable
 *
 * @return      none
 */
void ZDO_DoEndDeviceBind( ZDEndDeviceBind_t *bindReq )
{
  uint8 numMatches;
  uint8 Status;
  BindingEntry_t *pBind;
  AddrMgrEntry_t addrEntry;
  zAddrType_t SrcAddr;

  SrcAddr.addrMode = Addr16Bit;
  SrcAddr.addr.shortAddr = bindReq->srcAddr;

  // Ask for IEEE address
  if ( (bindReq->srcAddr != ZDAppNwkAddr.addr.shortAddr) )
  {
    addrEntry.user = ADDRMGR_USER_BINDING;
    addrEntry.nwkAddr = bindReq->srcAddr;
    Status = AddrMgrEntryLookupNwk( &addrEntry );
    if ( Status == TRUE)
    {
      // Add a reference to entry
      AddrMgrEntryAddRef( &addrEntry );
    }
    else
    {
      // If we have the extended address
      if ( NLME_GetProtocolVersion() != ZB_PROT_V1_0 )
      {
        osal_cpyExtAddr( addrEntry.extAddr, bindReq->ieeeAddr );
      }

      // Not in address manager?
      AddrMgrEntryUpdate( &addrEntry );   // Add it
    }

    if ( AddrMgrExtAddrValid( addrEntry.extAddr ) == FALSE )
    {
      ZDP_IEEEAddrReq( bindReq->srcAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, false );
    }
  }

  if ( ZDO_EDBind )   // End Device Bind in progress
  {
    Status = ZDP_NO_MATCH;

    if ( bindReq->profileID == ZDO_EDBind->ProfileID )
    {
      // Check the first in against the seconds out
      numMatches = ZDO_CompareClusterLists(
                  ZDO_EDBind->numOutClusters, ZDO_EDBind->outClusters,
                  bindReq->numInClusters, bindReq->inClusters, ZDOBuildBuf );

      if ( numMatches )
      {
        // if existing bind exists, remove it
        pBind = bindFindExisting( &(ZDO_EDBind->SrcAddr), ZDO_EDBind->epIntf,
                      &SrcAddr, bindReq->endpoint );
        if ( pBind )
        {
          bindRemoveEntry( pBind );
          Status = ZDP_SUCCESS;
        }
        // else add new binding table entry
        else if ( bindAddEntry( &(ZDO_EDBind->SrcAddr), ZDO_EDBind->epIntf,
                      &SrcAddr, bindReq->endpoint, numMatches, ZDOBuildBuf ) )
          Status = ZDP_SUCCESS;
        else
          Status = ZDP_TABLE_FULL;
      }

      // Check the second in against the first out
      numMatches = ZDO_CompareClusterLists( bindReq->numOutClusters, bindReq->outClusters,
                      ZDO_EDBind->numInClusters, ZDO_EDBind->inClusters,
                      ZDOBuildBuf );

      if ( numMatches )
      {
        // if existing bind exists, remove it
        pBind = bindFindExisting( &SrcAddr, bindReq->endpoint, &(ZDO_EDBind->SrcAddr),
                      ZDO_EDBind->epIntf );
        if ( pBind )
        {
          bindRemoveEntry( pBind );
          Status = ZDP_SUCCESS;
        }
        // else add new binding table entry
        else if ( bindAddEntry( &SrcAddr, bindReq->endpoint, &(ZDO_EDBind->SrcAddr),
                      ZDO_EDBind->epIntf, numMatches, ZDOBuildBuf ) )
          Status = ZDP_SUCCESS;
        else
          Status = ZDP_TABLE_FULL;
      }
    }

    if ( Status == ZDP_SUCCESS )
    {
      // We've found a match, so we don't have to wait for the timeout
      APS_SetEndDeviceBindTimeout( 10, ZDO_EndDeviceTimeoutCB );  // psuedo stop end device timeout

        // Notify to save info into NV
      osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 );
    }

    ZDO_EDBind->status = Status;

    // Send the response message to the device sending this message
    ZDO_SendEDBindRsp( bindReq->TransSeq, &SrcAddr, Status, bindReq->SecurityUse );
  }
  else  // Start a new End Device Bind
  {
    // Copy the info
    ZDO_EDBind = osal_mem_alloc( sizeof( ZDO_EDBind_t ) );
    if ( ZDO_EDBind )
    {
      osal_memcpy( &(ZDO_EDBind->SrcAddr), &SrcAddr, sizeof( zAddrType_t ) );
      ZDO_EDBind->LocalCoordinator = bindReq->localCoordinator;
      ZDO_EDBind->epIntf = bindReq->endpoint;
      ZDO_EDBind->ProfileID = bindReq->profileID;
      ZDO_EDBind->SrcTransSeq = bindReq->TransSeq;

      ZDO_EDBind->numInClusters = bindReq->numInClusters;
      if ( bindReq->numInClusters )
      {
        ZDO_EDBind->inClusters = osal_mem_alloc( (short)(bindReq->numInClusters * sizeof(uint16)) );
        if ( ZDO_EDBind->inClusters )
        {
          osal_memcpy( ZDO_EDBind->inClusters, bindReq->inClusters, (bindReq->numInClusters * sizeof( uint16 )) );
        }
        else
        {
          // Force no clusters
          ZDO_EDBind->numInClusters = 0;
        }
      }
      else
        ZDO_EDBind->inClusters = NULL;

      ZDO_EDBind->numOutClusters = bindReq->numOutClusters;
      if ( bindReq->numOutClusters )
      {
        ZDO_EDBind->outClusters = osal_mem_alloc( (short)(bindReq->numOutClusters*sizeof(uint16)) );
        if ( ZDO_EDBind->outClusters )
        {
          osal_memcpy( ZDO_EDBind->outClusters, bindReq->outClusters, (bindReq->numOutClusters * sizeof( uint16 )) );
        }
        else
        {
          ZDO_EDBind->numOutClusters = 0;
        }
      }
      else
        ZDO_EDBind->outClusters = NULL;

      ZDO_EDBind->SecurityUse = bindReq->SecurityUse;
      ZDO_EDBind->status = ZDP_TIMEOUT;

      // Setup the timer
      APS_SetEndDeviceBindTimeout( AIB_MaxBindingTime, ZDO_EndDeviceTimeoutCB );
    }
  }
}
#endif // REFLECTOR

/*********************************************************************
 * Utility functions
 */

/*********************************************************************
 * @fn          ZDO_CreateAlignedUINT16List
 *
 * @brief       Creates a list of cluster IDs that is guaranteed to be aligned.
 *              according to the needs of the target. If thre device is running
 *              Protocol version 1.0 the incoming buffer will have only a single
 *              byte for the cluster ID.
 *
 *              Depends on the malloc taking care of alignment.
 *
 *              When cluster ID went to 16 bits alignment for cluster IDs became
 *              an issue.
 *
 * @param       num  - number of entries in list
 * @param       buf  - pointer to list
 *
 * @return      pointer to aligned list. Null if can't allocate memory.
 *              Caller's responsibility to free memory.
 */
static uint16 *ZDO_CreateAlignedUINT16List(uint8 num, uint8 *buf)
{
  uint16 *ptr;

  if ((ptr=osal_mem_alloc((short)(num*sizeof(uint16)))))  {
    uint8 i, ubyte, inc;

    inc = (ZB_PROT_V1_1 == NLME_GetProtocolVersion()) ? 2 : 1;

    for (i=0; i<num; ++i)  {
      // set upper byte to 0 if we're talking Version 1.0. otherwise
      // the buffer contains 16 bit cluster IDs.
      ubyte  = (2 == inc) ? buf[1] : 0;
      ptr[i] = BUILD_UINT16(buf[0], ubyte);
      buf    += inc;
    }
  }

  return ptr;
}

/*********************************************************************
 * @fn          ZDO_CompareByteLists
 *
 * @brief       Compares two lists for matches.
 *
 * @param       ACnt  - number of entries in list A
 * @param       AList  - List A
 * @param       BCnt  - number of entries in list B
 * @param       BList  - List B
 *
 * @return      true if a match is found
 */
byte ZDO_AnyClusterMatches( byte ACnt, uint16 *AList, byte BCnt, uint16 *BList )
{
  byte x, y;

  for ( x = 0; x < ACnt; x++ )
  {
    for ( y = 0; y < BCnt; y++ )
    {
      if ( AList[x] == BList[y] )
      {
        return true;
      }
    }
  }

  return false;
}

/*********************************************************************
 * Callback functions from ZDProfile
 */

/*********************************************************************
 * @fn          ZDO_ProcessNodeDescReq
 *
 * @brief       This function processes and responds to the
 *              Node_Desc_req message.
 *
 * @param       src  - Source address
 * @param       msg - NWKAddrOfInterest
 * @param       sty - Security enable/disable
 *
 * @return      none
 */
void ZDO_ProcessNodeDescReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
  uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
  NodeDescriptorFormat_t *desc = NULL;
  byte stat = ZDP_INVALID_REQTYPE;

  if ( aoi == ZDAppNwkAddr.addr.shortAddr )
  {
    desc = &ZDO_Config_Node_Descriptor;
  }
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
  else if ( CACHE_SERVER )
  {
    desc = (NodeDescriptorFormat_t *)ZDCacheGetDesc( aoi, eNodeDesc, &stat );
  }
#endif

  if ( desc != NULL )
  {
    ZDP_NodeDescMsg( seq, src, aoi, desc, sty );
  }
  else
  {
    ZDP_GenericRsp( seq, src, stat, aoi, Node_Desc_rsp, sty );
  }
}

/*********************************************************************
 * @fn          ZDO_ProcessPowerDescReq
 *
 * @brief       This function processes and responds to the
 *              Node_Power_req message.
 *
 * @param       src  - Source address
 * @param       msg - NWKAddrOfInterest
 * @param       sty - Security enable/disable
 *
 * @return      none
 */
void ZDO_ProcessPowerDescReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
  uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
  NodePowerDescriptorFormat_t *desc = NULL;
  byte stat = ZDP_INVALID_REQTYPE;

  if ( aoi == ZDAppNwkAddr.addr.shortAddr )
  {
    desc = &ZDO_Config_Power_Descriptor;
  }
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
  else if ( CACHE_SERVER )
  {
    desc = (NodePowerDescriptorFormat_t *)ZDCacheGetDesc(aoi,ePowerDesc,&stat);
  }
#endif

  if ( desc != NULL )
  {
    ZDP_PowerDescMsg( seq, src, aoi, desc, sty );
  }
  else
  {
    ZDP_GenericRsp( seq, src, stat, aoi, Power_Desc_rsp, sty );
  }
}

/*********************************************************************
 * @fn          ZDO_ProcessSimpleDescReq
 *
 * @brief       This function processes and responds to the
 *              Simple_Desc_req message.
 *
 * @param       src - Source address
 * @param       msg - message data
 * @param       sty - Security enable/disable
 *
 * @return      none
 */
void ZDO_ProcessSimpleDescReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
  SimpleDescriptionFormat_t *sDesc = NULL;
  uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
  byte endPoint = msg[2];
  byte free = false;
  byte stat = ZDP_SUCCESS;

  if ( (endPoint == ZDO_EP) || (endPoint > MAX_ENDPOINTS) )
  {
    stat = ZDP_INVALID_EP;
  }
  else if ( aoi == ZDAppNwkAddr.addr.shortAddr )
  {
    free = afFindSimpleDesc( &sDesc, endPoint );
    if ( sDesc == NULL )
    {
      stat = ZDP_NOT_ACTIVE;
    }
  }
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
  else if ( CACHE_SERVER )
  {
    stat = endPoint;
    sDesc = (SimpleDescriptionFormat_t *)ZDCacheGetDesc(aoi, eSimpDesc, &stat);
  }
#endif
  else
  {
#if defined ( RTR_NWK )
    stat = ZDP_DEVICE_NOT_FOUND;
#else
    stat = ZDP_INVALID_REQTYPE;
#endif
  }

  ZDP_SimpleDescMsg( seq, src, stat, sDesc, Simple_Desc_rsp, sty );

  if ( free )
  {
    osal_mem_free( sDesc );
  }
}

/*********************************************************************
 * @fn          ZDO_ProcessActiveEPReq
 *
 * @brief       This function processes and responds to the
 *              Active_EP_req message.
 *
 * @param       src  - Source address
 * @param       sty - Security enable/disable
 *
 * @return      none
 */
void ZDO_ProcessActiveEPReq( byte seq, zAddrType_t *src, byte *msg, byte sty )
{
  uint16 aoi = BUILD_UINT16( msg[0], msg[1] );
  byte cnt = CACHE_EP_MAX;
  byte stat = ZDP_SUCCESS;

  if ( aoi == ZDAppNwkAddr.addr.shortAddr )
  {
    cnt = afNumEndPoints() - 1;  // -1 for ZDO endpoint descriptor
    afEndPoints( (uint8 *)ZDOBuildBuf, true );
  }
#if defined( ZDO_CACHE ) && ( CACHE_DEV_MAX > 0 )
  else if ( CACHE_SERVER )
  {
    cnt = *((byte *)ZDCacheGetDesc(aoi, eActEPDesc, (uint8 *)ZDOBuildBuf));
    // If cnt = 0, err code in 1st byte of buf, otherwise EP list is in the buf.
    if ( cnt == 0 )

⌨️ 快捷键说明

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