📄 zdobject.c
字号:
/*********************************************************************
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 + -