zdobject.c

来自「一些基于IRA环境开发的zigbee实例程序」· C语言 代码 · 共 2,264 行 · 第 1/5 页

C
2,264
字号
 *
 * @return      none
 */
void ZDO_ProcessMgmtRtgReq( zdoIncomingMsg_t *inMsg )
{
  byte x;
  byte maxNumItems;
  byte numItems;
  byte *pBuf;
  rtgItem_t *pList;
  uint8 StartIndex = inMsg->asdu[0];

  // Get the number of table items
  NLME_GetRequest( nwkNumRoutingTableEntries, 0, &maxNumItems );

  numItems = maxNumItems - StartIndex;    // Start at the passed in index

  // limit the size of the list
  if ( numItems > ZDO_MAX_RTG_ITEMS )
    numItems = ZDO_MAX_RTG_ITEMS;

  // Allocate the memory to build the table
  pBuf = osal_mem_alloc( (short)(sizeof( rtgItem_t ) * numItems) );

  if ( pBuf )
  {
    // Convert buffer to list
    pList = (rtgItem_t *)pBuf;

    // Loop through items and build list
    for ( x = 0; x < numItems; x++ )
    {
      NLME_GetRequest( nwkRoutingTable, (uint16)(x + StartIndex), (void*)pList );

      // Remap the status to the RoutingTableList Record Format defined in the ZigBee spec
      switch( pList->status )
      {
        case RT_ACTIVE:
          pList->status = ZDO_MGMT_RTG_ENTRY_ACTIVE;
          break;

        case RT_DISC:
          pList->status = ZDO_MGMT_RTG_ENTRY_DISCOVERY_UNDERWAY;
          break;

        case RT_LINK_FAIL:
          pList->status = ZDO_MGMT_RTG_ENTRY_DISCOVERY_FAILED;

        case RT_INIT:
        case RT_REPAIR:
        default:
          pList->status = ZDO_MGMT_RTG_ENTRY_INACTIVE;
          break;
      }

      // Increment pointer to next record
      pList++;
    }

    // Send response
    ZDP_MgmtRtgRsp( inMsg->TransSeq, &(inMsg->srcAddr), ZSuccess, maxNumItems, StartIndex, numItems,
                          (rtgItem_t *)pBuf, false );

    osal_mem_free( pBuf );
  }
}
#endif // defined(ZDO_MGMT_RTG_RESPONSE)  && defined(RTR_NWK)

#if defined ( ZDO_MGMT_BIND_RESPONSE )
/*********************************************************************
 * @fn          ZDO_ProcessMgmtBindReq
 *
 * @brief       This function finishes the processing of the Management
 *              Bind Request and generates the response.
 *
 *   Note:      This function will limit the number of items returned
 *              to ZDO_MAX_BIND_ITEMS items.
 *
 * @param       ResultCountSrcAddr - source of the request
 * @param       msg - pointer to incoming message
 * @param       SecurityUse -
 *
 * @return      none
 */
void ZDO_ProcessMgmtBindReq( zdoIncomingMsg_t *inMsg )
{
#if defined ( REFLECTOR )
  byte x;
  uint16 maxNumItems;
  uint16 numItems;
  byte *pBuf = NULL;
  apsBindingItem_t *pList;
  uint8 StartIndex = inMsg->asdu[0];

  // Get the number of table items
  APSME_GetRequest( apsNumBindingTableEntries, 0, (byte*)(&maxNumItems) );

  if ( maxNumItems > StartIndex )
    numItems = maxNumItems - StartIndex;    // Start at the passed in index
  else
    numItems = 0;

  // limit the size of the list
  if ( numItems > ZDO_MAX_BIND_ITEMS )
    numItems = ZDO_MAX_BIND_ITEMS;

  // Allocate the memory to build the table
  if ( numItems )
    pBuf = osal_mem_alloc( sizeof( apsBindingItem_t ) * numItems );

  if ( pBuf )
  {
    // Convert buffer to list
    pList = (apsBindingItem_t *)pBuf;

    // Loop through items and build list
    for ( x = 0; x < numItems; x++ )
    {
      APSME_GetRequest( apsBindingTable, (x + StartIndex), (void*)pList );
      pList++;
    }
  }

  // Send response
  ZDP_MgmtBindRsp( inMsg->TransSeq, &(inMsg->srcAddr), ZSuccess, (byte)maxNumItems, StartIndex, (byte)numItems,
                        (apsBindingItem_t *)pBuf, false );

  if ( pBuf )
  {
    osal_mem_free( pBuf );
  }
#endif
}
#endif // ZDO_MGMT_BIND_RESPONSE

#if defined ( ZDO_MGMT_JOINDIRECT_RESPONSE ) && defined ( RTR_NWK )
/*********************************************************************
 * @fn          ZDO_ProcessMgmtDirectJoinReq
 *
 * @brief       This function finishes the processing of the Management
 *              Direct Join Request and generates the response.
 *
 * @param       inMsg - incoming message (request)
 *
 * @return      none
 */
void ZDO_ProcessMgmtDirectJoinReq( zdoIncomingMsg_t *inMsg )
{
  uint8 *deviceAddr;
  uint8 capInfo;
  uint8 stat;

  // Parse the message
  deviceAddr = inMsg->asdu;
  capInfo = inMsg->asdu[Z_EXTADDR_LEN];

  stat = (byte) NLME_DirectJoinRequest( deviceAddr, capInfo );

  ZDP_MgmtDirectJoinRsp( inMsg->TransSeq, &(inMsg->srcAddr), stat, false );
}
#endif // ZDO_MGMT_JOINDIRECT_RESPONSE && RTR_NWK

#if defined ( ZDO_MGMT_LEAVE_RESPONSE )
/*********************************************************************
 * @fn          ZDO_ProcessMgmtLeaveReq
 *
 * @brief       This function processes a Management Leave Request
 *              and generates the response.
 *
 * @param       inMsg - incoming message (request)
 *
 * @return      none
 */
void ZDO_ProcessMgmtLeaveReq( zdoIncomingMsg_t *inMsg )
{
  NLME_LeaveReq_t req;
  ZStatus_t       status;
  uint8 *msg = inMsg->asdu;


  if ( ( AddrMgrExtAddrValid( msg ) == FALSE                 ) ||
       ( osal_ExtAddrEqual( msg, NLME_GetExtAddr() ) == TRUE )    )
  {
    // Remove this device
    req.extAddr = NULL;
  }
  else
  {
    // Remove child device
    req.extAddr = msg;
  }

  req.removeChildren = FALSE;
  req.rejoin         = FALSE;
  req.silent         = FALSE;

  status = NLME_LeaveReq( &req );

  ZDP_MgmtLeaveRsp( inMsg->TransSeq, &(inMsg->srcAddr), status, FALSE );
}
#endif // ZDO_MGMT_LEAVE_RESPONSE

#if defined( ZDO_MGMT_PERMIT_JOIN_RESPONSE ) && defined( RTR_NWK )
/*********************************************************************
 * @fn          ZDO_ProcessMgmtPermitJoinReq
 *
 * @brief       This function processes a Management Permit Join Request
 *              and generates the response.
 *
 * @param       inMsg - incoming message (request)
 *
 * @return      none
 */
void ZDO_ProcessMgmtPermitJoinReq( zdoIncomingMsg_t *inMsg )
{
  uint8 stat;
  uint8 duration;
  uint8 tcsig;

  duration = inMsg->asdu[ZDP_MGMT_PERMIT_JOIN_REQ_DURATION];
  tcsig    = inMsg->asdu[ZDP_MGMT_PERMIT_JOIN_REQ_TC_SIG];

  // Set the network layer permit join duration
  stat = (byte) NLME_PermitJoiningRequest( duration );

  // Handle the Trust Center Significance
  if ( tcsig == TRUE )
  {
    ZDSecMgrPermitJoining( duration );
  }

  // Send a response if unicast
  if (inMsg->srcAddr.addr.shortAddr != NWK_BROADCAST_SHORTADDR)
  {
    ZDP_MgmtPermitJoinRsp( inMsg->TransSeq, &(inMsg->srcAddr), stat, false );
  }
}
#endif // ZDO_MGMT_PERMIT_JOIN_RESPONSE && defined( RTR_NWK )

/*
 * This function stub allows the next higher layer to be notified of
 * a permit joining timeout.
 */
#if defined( RTR_NWK )
/*********************************************************************
 * @fn          ZDO_ProcessMgmtPermitJoinTimeout
 *
 * @brief       This function stub allows the next higher layer to be
 *              notified of a permit joining timeout. Currently, this
 *              directly bypasses the APS layer.
 *
 * @param       none
 *
 * @return      none
 */
void ZDO_ProcessMgmtPermitJoinTimeout( void )
{
  #if defined( ZDO_MGMT_PERMIT_JOIN_RESPONSE )
  {
    // Currently, only the ZDSecMgr needs to be notified
    ZDSecMgrPermitJoiningTimeout();
  }
  #endif
}
#endif // defined( RTR_NWK )

#if defined ( ZDO_USERDESC_RESPONSE )
/*********************************************************************
 * @fn          ZDO_ProcessUserDescReq
 *
 * @brief       This function finishes the processing of the User
 *              Descriptor Request and generates the response.
 *
 * @param       inMsg - incoming message (request)
 *
 * @return      none
 */
void ZDO_ProcessUserDescReq( zdoIncomingMsg_t *inMsg )
{
  uint16 aoi = BUILD_UINT16( inMsg->asdu[0], inMsg->asdu[1] );
  UserDescriptorFormat_t userDesc;

  if ( (aoi == ZDAppNwkAddr.addr.shortAddr) && (ZSUCCESS == osal_nv_read(
             ZCD_NV_USERDESC, 0, sizeof(UserDescriptorFormat_t), &userDesc )) )
  {
    ZDP_UserDescRsp( inMsg->TransSeq, &(inMsg->srcAddr), aoi, &userDesc, false );
  }
  else
  {
    ZDP_GenericRsp(inMsg->TransSeq, &(inMsg->srcAddr),
           ZDP_NOT_SUPPORTED, aoi, User_Desc_rsp, inMsg->SecurityUse );
  }
}
#endif // ZDO_USERDESC_RESPONSE

#if defined ( ZDO_USERDESCSET_RESPONSE )
/*********************************************************************
 * @fn          ZDO_ProcessUserDescSet
 *
 * @brief       This function finishes the processing of the User
 *              Descriptor Set and generates the response.
 *
 * @param       inMsg - incoming message (request)
 *
 * @return      none
 */
void ZDO_ProcessUserDescSet( zdoIncomingMsg_t *inMsg )
{
  uint8 *msg;
  uint16 aoi;
  UserDescriptorFormat_t userDesc;
  uint8 outMsg[3];
  uint8 status;

  msg = inMsg->asdu;
  aoi = BUILD_UINT16( msg[0], msg[1] );

  if ( aoi == ZDAppNwkAddr.addr.shortAddr )
  {
    userDesc.len = (msg[2] < AF_MAX_USER_DESCRIPTOR_LEN) ? msg[2] : AF_MAX_USER_DESCRIPTOR_LEN;
    msg ++;  // increment one for the length field

    osal_memcpy( userDesc.desc, &msg[2], userDesc.len );
    osal_nv_write( ZCD_NV_USERDESC, 0, sizeof(UserDescriptorFormat_t), &userDesc );
    if ( userDesc.len != 0 )
    {
      ZDO_Config_Node_Descriptor.UserDescAvail = TRUE;
    }
    else
    {
      ZDO_Config_Node_Descriptor.UserDescAvail = FALSE;
    }

    status = ZDP_SUCCESS;
  }
  else
  {
    status =  ZDP_NOT_SUPPORTED;
  }

  outMsg[0] = status;
  outMsg[1] = LO_UINT16( aoi );
  outMsg[2] = LO_UINT16( aoi );

  ZDP_SendData( &(inMsg->TransSeq), &(inMsg->srcAddr), User_Desc_conf, 3, outMsg,
               inMsg->SecurityUse );
}
#endif // ZDO_USERDESCSET_RESPONSE

#if defined ( ZDO_ENDDEVICE_ANNCE ) && defined(RTR_NWK)
/*********************************************************************
 * @fn          ZDO_ProcessEndDeviceAnnce
 *
 * @brief       This function processes an end device annouce message.
 *
 * @param       inMsg - incoming message
 *
 * @return      none
 */
void ZDO_ProcessEndDeviceAnnce( zdoIncomingMsg_t *inMsg )
{
  ZDO_DeviceAnnce_t Annce;
  associated_devices_t *dev;
  AddrMgrEntry_t addrEntry;

  // Parse incoming message
  ZDO_ParseDeviceAnnce( inMsg, &Annce );

  addrEntry.user = ADDRMGR_USER_DEFAULT;
  addrEntry.nwkAddr = Annce.nwkAddr;
  AddrMgrExtAddrSet( addrEntry.extAddr, Annce.extAddr );
  AddrMgrEntryUpdate( &addrEntry );

  // find device in device list
  dev = AssocGetWithExt( Annce.extAddr );
  if ( dev != NULL )
  {
    // if found and address is different
    if ( dev->shortAddr != Annce.nwkAddr )
    {
      // update device list if device is (was) not our child
      if ( dev->nodeRelation == NEIGHBOR || dev->nodeRelation == OTHER )
      {
        dev->shortAddr = Annce.nwkAddr;
      }
    }
  }
}
#endif // ZDO_ENDDEVICE_ANNCE

/*********************************************************************
 * @fn          ZDO_BuildSimpleDescBuf
 *
 * @brief       Build a byte sequence representation of a Simple Descriptor.
 *
 * @param       buf  - pointer to a byte array big enough for data.
 * @param       desc - SimpleDescriptionFormat_t *
 *
 * @return      none
 */
void ZDO_BuildSimpleDescBuf( byte *buf, SimpleDescriptionFormat_t *desc )
{
  byte cnt;
  uint16 *ptr;

  *buf++ = desc->EndPoint;
  *buf++ = HI_UINT16( desc->AppProfId );
  *buf++ = LO_UINT16( desc->AppProfId );
  *buf++ = HI_UINT16( desc->AppDeviceId );
  *buf++ = LO_UINT16( desc->AppDeviceId );

  *buf++ = (byte)(desc->AppDevVer << 4);

  *buf++ = desc->AppNumInClusters;
  ptr = desc->pAppInClusterList;
  for ( cnt = 0; cnt < desc->AppNumInClusters; ptr++, cnt++ )
  {
    *buf++ = HI_UINT16( *ptr );
    *buf++ = LO_UINT16( *ptr );
  }

  *buf++ = desc->AppNumOutClusters;
  ptr = desc->pAppOutClusterList;
  for ( cnt = 0; cnt < desc->AppNumOutClusters; ptr++, cnt++ )
  {
    *buf++ = HI_UINT16( *ptr );
    *buf++ = LO_UINT16( *ptr );
  }
}

#if defined ( ZDO_COORDINATOR )
/*********************************************************************
 * @fn      ZDO_MatchEndDeviceBind()
 *
 * @brief
 *
 *   Called to match end device binding requests
 *
 * @param  bindReq  - binding request information
 * @param  SecurityUse - Security enable/disable
 *
 * @return  none
 */
void ZDO_MatchEndDeviceBind( ZDEndDeviceBind_t *bindReq )
{
  zAddrType_t dstAddr;
  uint8 sendRsp = FALSE;
  uint8 status;

  // Is this the first request?
  if ( matchED == NULL )
  {
    // Create match info structure

⌨️ 快捷键说明

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