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

📄 zdobject.c

📁 Zigbee2006入门(源代码+文档讲解+系统推荐)
💻 C
📖 第 1 页 / 共 5 页
字号:
/*********************************************************************
    Filename:       ZDObject.c
    Revised:        $Date: 2007-05-14 17:34:18 -0700 (Mon, 14 May 2007) $
    Revision:       $Revision: 14296 $

    Description:

      This Zigbee Device Object.

    Notes:

    Copyright (c) 2006 by Texas Instruments, Inc.
    All Rights Reserved.  Permission to use, reproduce, copy, prepare
    derivative works, modify, distribute, perform, display or sell this
    software and/or its documentation for any purpose is prohibited
    without the express written consent of Texas Instruments, Inc.
*********************************************************************/

/*********************************************************************
 * INCLUDES
 */
#include "ZComdef.h"
#include "OSAL.h"
#include "OSAL_Nv.h"
#include "rtg.h"
#include "NLMEDE.h"
#include "nwk_globals.h"
#include "APS.h"
#include "APSMEDE.h"
#include "AssocList.h"
#include "BindingTable.h"
#include "AddrMgr.h"
#include "AF.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "ZDConfig.h"
#include "ZDCache.h"
#include "ZDSecMgr.h"
#include "ZDApp.h"
#include "nwk_util.h"   // NLME_IsAddressBroadcast()
#include "ZGlobals.h"

#if defined( LCD_SUPPORTED )
  #include "OnBoard.h"
#endif

/* HAL */
#include "hal_lcd.h"

/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * CONSTANTS
 */
// NLME Stub Implementations
#define ZDO_ProcessMgmtPermitJoinTimeout NLME_PermitJoiningTimeout

// Status fields used by ZDO_ProcessMgmtRtgReq
#define ZDO_MGMT_RTG_ENTRY_ACTIVE             0x00
#define ZDO_MGMT_RTG_ENTRY_DISCOVERY_UNDERWAY 0x01
#define ZDO_MGMT_RTG_ENTRY_DISCOVERY_FAILED   0x02
#define ZDO_MGMT_RTG_ENTRY_INACTIVE           0x03

/*********************************************************************
 * TYPEDEFS
 */
#if defined ( REFLECTOR )
typedef struct
{
  byte SrcTransSeq;
  zAddrType_t SrcAddr;
  uint16 LocalCoordinator;
  byte epIntf;
  uint16 ProfileID;
  byte numInClusters;
  uint16 *inClusters;
  byte numOutClusters;
  uint16 *outClusters;
  byte SecurityUse;
  byte status;
} ZDO_EDBind_t;
#endif // defined ( REFLECTOR )

#if defined ( ZDO_COORDINATOR )
enum
{
  ZDMATCH_INIT,           // Initialized
  ZDMATCH_WAIT_REQ,       // Received first request, waiting for second
  ZDMATCH_SENDING_BINDS   // Received both requests, sending unbind/binds
};

enum
{
  ZDMATCH_REASON_START,
  ZDMATCH_REASON_TIMEOUT,
  ZDMATCH_REASON_UNBIND_RSP,
  ZDMATCH_REASON_BIND_RSP
};

enum
{
  ZDMATCH_SENDING_NOT,
  ZDMATCH_SENDING_UNBIND,
  ZDMATCH_SENDING_BIND
};

typedef struct
{
  ZDEndDeviceBind_t ed1;
  ZDEndDeviceBind_t ed2;
  uint8  state;            // One of the above states
  uint8  sending;         // 0 - not sent, 1 - unbind, 2 bind - expecting response
  uint8  transSeq;
  uint8  ed1numMatched;
  uint16 *ed1Matched;
  uint8  ed2numMatched;
  uint16 *ed2Matched;
} ZDMatchEndDeviceBind_t;
#endif

/*********************************************************************
 * GLOBAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL VARIABLES
 */

/*********************************************************************
 * EXTERNAL FUNCTIONS
 */

/*********************************************************************
 * LOCAL VARIABLES
 */
static uint16 ZDOBuildBuf[26];  // temp area to build data without allocation

#if defined ( REFLECTOR )
static ZDO_EDBind_t *ZDO_EDBind;     // Null when not used
#endif

#if defined ( MANAGED_SCAN )
  uint32 managedScanNextChannel = 0;
  uint32 managedScanChannelMask = 0;
  uint8  managedScanTimesPerChannel = 0;
#endif

#if defined ( ZDO_COORDINATOR )
  ZDMatchEndDeviceBind_t *matchED = (ZDMatchEndDeviceBind_t *)NULL;
#endif

/*********************************************************************
 * LOCAL FUNCTIONS
 */
static void ZDODeviceSetup( void );
static uint16 *ZDO_CreateAlignedUINT16List(uint8 num, uint8 *buf);
#if defined ( MANAGED_SCAN )
  static void ZDOManagedScan_Next( void );
#endif
#if defined ( REFLECTOR )
  static void ZDO_RemoveEndDeviceBind( void );
  static void ZDO_SendEDBindRsp( byte TransSeq, zAddrType_t *dstAddr, byte Status, byte secUse );
#endif
#if defined ( REFLECTOR ) || defined( ZDO_COORDINATOR )
  static byte ZDO_CompareClusterLists( byte numList1, uint16 *list1,
                                byte numList2, uint16 *list2, uint16 *pMatches );
#endif
#if defined ( ZDO_COORDINATOR )
  static void ZDO_RemoveMatchMemory( void );
  static uint8 ZDO_CopyMatchInfo( ZDEndDeviceBind_t *destReq, ZDEndDeviceBind_t *srcReq );
  static uint8 ZDMatchSendState( uint8 reason, uint8 status, uint8 TransSeq );
  static void ZDO_EndDeviceBindMatchTimeoutCB( void );
#endif

/*********************************************************************
 * @fn          ZDO_Init
 *
 * @brief       ZDObject and ZDProfile initialization.
 *
 * @param       none
 *
 * @return      none
 */
void ZDO_Init( void )
{
  // Initialize ZD items
  #if defined ( REFLECTOR )
  ZDO_EDBind = NULL;
  #endif

  // Setup the device - type of device to create.
  ZDODeviceSetup();

  // Initialize ZigBee Device Security Manager
  ZDSecMgrInit();
}

#if defined ( MANAGED_SCAN )
/*********************************************************************
 * @fn      ZDOManagedScan_Next()
 *
 * @brief   Setup a managed scan.
 *
 * @param   none
 *
 * @return  none
 */
static void ZDOManagedScan_Next( void )
{
  // Is it the first time
  if ( managedScanNextChannel == 0 && managedScanTimesPerChannel == 0 )
  {
    // Setup the defaults
    managedScanNextChannel  = 1;

    while( managedScanNextChannel && (zgDefaultChannelList & managedScanNextChannel) == 0 )
      managedScanNextChannel <<= 1;

    managedScanChannelMask = managedScanNextChannel;
    managedScanTimesPerChannel = MANAGEDSCAN_TIMES_PRE_CHANNEL;
  }
  else
  {
    // Do we need to go to the next channel
    if ( managedScanTimesPerChannel == 0 )
    {
      // Find next active channel
      managedScanChannelMask  = managedScanNextChannel;
      managedScanTimesPerChannel = MANAGEDSCAN_TIMES_PRE_CHANNEL;
    }
    else
    {
      managedScanTimesPerChannel--;

      if ( managedScanTimesPerChannel == 0 )
      {
        managedScanNextChannel  <<= 1;
        while( managedScanNextChannel && (zgDefaultChannelList & managedScanNextChannel) == 0 )
          managedScanNextChannel <<= 1;

        if ( managedScanNextChannel == 0 )
          zdoDiscCounter  = NUM_DISC_ATTEMPTS + 1; // Stop
      }
    }
  }
}
#endif // MANAGED_SCAN

/*********************************************************************
 * @fn      ZDODeviceSetup()
 *
 * @brief   Call set functions depending on the type of device compiled.
 *
 * @param   none
 *
 * @return  none
 */
static void ZDODeviceSetup( void )
{
#if defined( ZDO_COORDINATOR )
  NLME_CoordinatorInit();
#endif

#if defined ( REFLECTOR )
  #if defined ( ZDO_COORDINATOR )
    APS_ReflectorInit( APS_REFLECTOR_PUBLIC );
  #else
    APS_ReflectorInit( APS_REFLECTOR_PRIVATE );
  #endif
#endif

#if !defined( ZDO_COORDINATOR ) || defined( SOFT_START )
  NLME_DeviceJoiningInit();
#endif
}

/*********************************************************************
 * @fn          ZDO_StartDevice
 *
 * @brief       This function starts a device in a network.
 *
 * @param       logicalType     - Device type to start
 *              startMode       - indicates mode of device startup
 *              beaconOrder     - indicates time betwen beacons
 *              superframeOrder - indicates length of active superframe
 *
 * @return      none
 */
void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )
{
  ZStatus_t ret;

  ret = ZUnsupportedMode;

#if defined(ZDO_COORDINATOR)
  if ( logicalType == NODETYPE_COORDINATOR )
  {
    if ( startMode == MODE_HARD )
    {
      devState = DEV_COORD_STARTING;
      ret = NLME_NetworkFormationRequest( zgConfigPANID, zgDefaultChannelList,
                                          zgDefaultStartingScanDuration, beaconOrder,
                                          superframeOrder, false );
    }
    else if ( startMode == MODE_RESUME )
    {
      // Just start the coordinator
      devState = DEV_COORD_STARTING;
      ret = NLME_StartRouterRequest( beaconOrder, beaconOrder, false );
    }
    else
    {
#if defined( LCD_SUPPORTED )
      HalLcdWriteScreen( "StartDevice ERR", "MODE unknown" );
#endif
    }
  }
#endif  // !ZDO_COORDINATOR

#if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )
  if ( logicalType == NODETYPE_ROUTER || logicalType == NODETYPE_DEVICE )
  {
    if ( (startMode == MODE_JOIN) || (startMode == MODE_REJOIN) )
    {
      devState = DEV_NWK_DISC;

  #if defined( MANAGED_SCAN )
      ZDOManagedScan_Next();
      ret = NLME_NetworkDiscoveryRequest( managedScanChannelMask, BEACON_ORDER_15_MSEC );
  #else
      ret = NLME_NetworkDiscoveryRequest( zgDefaultChannelList, zgDefaultStartingScanDuration );
  #endif
    }
    else if ( startMode == MODE_RESUME )
    {
      if ( logicalType == NODETYPE_ROUTER )
      {
        ZMacScanCnf_t scanCnf;
        devState = DEV_NWK_ORPHAN;

        /* if router and nvram is available, fake successful orphan scan */
        scanCnf.hdr.Status = ZSUCCESS;
        scanCnf.ScanType = ZMAC_ORPHAN_SCAN;
        scanCnf.UnscannedChannels = 0;
        scanCnf.ResultListSize = 0;
        nwk_ScanJoiningOrphan(&scanCnf);

        ret = ZSuccess;
      }
      else
      {
        devState = DEV_NWK_ORPHAN;
        ret = NLME_OrphanJoinRequest( zgDefaultChannelList,
                                      zgDefaultStartingScanDuration );
      }
    }
    else
    {
#if defined( LCD_SUPPORTED )
      HalLcdWriteScreen( "StartDevice ERR", "MODE unknown" );
#endif
    }
  }
#endif  //!ZDO COORDINATOR || SOFT_START

  // configure the Security Manager for type of device
  ZDSecMgrConfig();

  if ( ret != ZSuccess )
    osal_start_timer( ZDO_NETWORK_INIT, NWK_RETRY_DELAY );
}

/*********************************************************************
 * @fn      ZDO_UpdateNwkStatus()
 *
 * @brief
 *
 *   This function will send an update message to each registered
 *   application endpoint/interface about a network status change.
 *
 * @param   none
 *
 * @return  none
 */
void ZDO_UpdateNwkStatus( devStates_t state )
{
  // Endpoint/Interface descriptor list.
  epList_t *epDesc = epList;
  byte bufLen = sizeof(osal_event_hdr_t);
  osal_event_hdr_t *msgPtr;

  ZDAppNwkAddr.addr.shortAddr = NLME_GetShortAddr();
  (void)NLME_GetExtAddr();  // Load the saveExtAddr pointer.

  while ( epDesc )
  {
    if ( epDesc->epDesc->endPoint != ZDO_EP )
    {
      msgPtr = (osal_event_hdr_t *)osal_msg_allocate( bufLen );
      if ( msgPtr )
      {
        msgPtr->event = ZDO_STATE_CHANGE; // Command ID
        msgPtr->status = (byte)state;

        osal_msg_send( *(epDesc->epDesc->task_id), (byte *)msgPtr );
      }
    }
    epDesc = epDesc->nextDesc;
  }
}

#if defined ( REFLECTOR )
/*********************************************************************
 * @fn          ZDO_RemoveEndDeviceBind
 *
 * @brief       Remove the end device bind
 *
 * @param  none
 *
 * @return      none
 */
static void ZDO_RemoveEndDeviceBind( void )
{
  if ( ZDO_EDBind )
  {
    // Free the RAM
    if ( ZDO_EDBind->inClusters )
      osal_mem_free( ZDO_EDBind->inClusters );
    if ( ZDO_EDBind->outClusters )
      osal_mem_free( ZDO_EDBind->outClusters );
    osal_mem_free( ZDO_EDBind );
    ZDO_EDBind = NULL;
  }
}
#endif // REFLECTOR

#if defined ( REFLECTOR )
/*********************************************************************
 * @fn          ZDO_RemoveEndDeviceBind
 *
 * @brief       Remove the end device bind
 *
 * @param  none
 *
 * @return      none
 */
static void ZDO_SendEDBindRsp( byte TransSeq, zAddrType_t *dstAddr, byte Status, byte secUse )
{
  ZDP_EndDeviceBindRsp( TransSeq, dstAddr, Status, secUse );

#if defined( LCD_SUPPORTED )
  HalLcdWriteString( "End Device Bind", HAL_LCD_LINE_1 );
  if ( Status == ZDP_SUCCESS )
    HalLcdWriteString( "Success Sent", HAL_LCD_LINE_2 );

⌨️ 快捷键说明

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