smart-green-house/project_ZigBee/Components/stack/zcl/zcl_ss.c

1521 lines
46 KiB
C
Raw Permalink Normal View History

2023-10-28 18:00:47 +08:00
/**************************************************************************************************
Filename: zcl_ss.c
Revised: $Date: 2010-02-09 15:28:14 -0800 (Tue, 09 Feb 2010) $
Revision: $Revision: 21679 $
Description: Zigbee Cluster Library - Security and Safety ( SS )
Copyright 2006-2010 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED <EFBFBD>AS IS<EFBFBD> WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
**************************************************************************************************/
/*******************************************************************************
* INCLUDES
*/
#include "ZComDef.h"
#include "OSAL.h"
#include "zcl.h"
#include "zcl_general.h"
#include "zcl_ss.h"
#if defined ( INTER_PAN )
#include "stub_aps.h"
#endif
/*******************************************************************************
* MACROS
*/
#define zclSS_ZoneTypeSupported( a ) ( (a) == SS_IAS_ZONE_TYPE_STANDARD_CIE || \
(a) == SS_IAS_ZONE_TYPE_MOTION_SENSOR || \
(a) == SS_IAS_ZONE_TYPE_CONTACT_SWITCH || \
(a) == SS_IAS_ZONE_TYPE_FIRE_SENSOR || \
(a) == SS_IAS_ZONE_TYPE_WATER_SENSOR || \
(a) == SS_IAS_ZONE_TYPE_GAS_SENSOR || \
(a) == SS_IAS_ZONE_TYPE_PERSONAL_EMERGENCY_DEVICE || \
(a) == SS_IAS_ZONE_TYPE_VIBRATION_MOVEMENT_SENSOR || \
(a) == SS_IAS_ZONE_TYPE_REMOTE_CONTROL || \
(a) == SS_IAS_ZONE_TYPE_KEY_FOB || \
(a) == SS_IAS_ZONE_TYPE_KEYPAD || \
(a) == SS_IAS_ZONE_TYPE_STANDARD_WARNING_DEVICE )
/*******************************************************************************
* CONSTANTS
*/
/*******************************************************************************
* TYPEDEFS
*/
typedef struct zclSSCBRec
{
struct zclSSCBRec *next;
uint8 endpoint; // Used to link it into the endpoint descriptor
zclSS_AppCallbacks_t *CBs; // Pointer to Callback function
} zclSSCBRec_t;
typedef struct zclSS_ZoneItem
{
struct zclSS_ZoneItem *next;
uint8 endpoint; // Used to link it into the endpoint descriptor
IAS_ACE_ZoneTable_t zone; // Zone info
} zclSS_ZoneItem_t;
/*******************************************************************************
* GLOBAL VARIABLES
*/
const uint8 zclSS_UknownIeeeAddress[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/*******************************************************************************
* GLOBAL FUNCTIONS
*/
/*******************************************************************************
* LOCAL VARIABLES
*/
static zclSSCBRec_t *zclSSCBs = (zclSSCBRec_t *)NULL;
static uint8 zclSSPluginRegisted = FALSE;
#if defined(ZCL_ZONE) || defined(ZCL_ACE)
static zclSS_ZoneItem_t *zclSS_ZoneTable = (zclSS_ZoneItem_t *)NULL;
#endif // ZCL_ZONE || ZCL_ACE
/*******************************************************************************
* LOCAL FUNCTIONS
*/
static ZStatus_t zclSS_HdlIncoming( zclIncoming_t *pInHdlrMsg );
static ZStatus_t zclSS_HdlInSpecificCommands( zclIncoming_t *pInMsg );
static zclSS_AppCallbacks_t *zclSS_FindCallbacks( uint8 endpoint );
#ifdef ZCL_ZONE
static ZStatus_t zclSS_ProcessInZoneStatusCmdsServer( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static ZStatus_t zclSS_ProcessInZoneStatusCmdsClient( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ZoneStatus_ChangeNotification( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static ZStatus_t zclSS_ProcessInCmd_ZoneStatus_EnrollRequest( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ZoneStatus_EnrollResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
#endif // ZCL_ZONE
#ifdef ZCL_ACE
static ZStatus_t zclSS_ProcessInACECmdsServer( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static ZStatus_t zclSS_ProcessInACECmdsClient( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static ZStatus_t zclSS_ProcessInCmd_ACE_Arm( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ACE_Bypass( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ACE_Emergency( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ACE_Fire( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ACE_Panic( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneIDMap( zclIncoming_t *pInMsg );
static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneInformation( zclIncoming_t *pInMsg );
static void zclSS_ProcessInCmd_ACE_ArmResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_ACE_GetZoneInformationResponse( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
#endif // ZCL_ACE
#ifdef ZCL_WD
static ZStatus_t zclSS_ProcessInWDCmds( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_WD_StartWarning( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
static void zclSS_ProcessInCmd_WD_Squawk( zclIncoming_t *pInMsg, zclSS_AppCallbacks_t *pCBs );
#endif // ZCL_WD
#ifdef ZCL_ZONE
static uint8 zclSS_GetNextFreeZoneID( void );
static ZStatus_t zclSS_AddZone( uint8 endpoint, IAS_ACE_ZoneTable_t *zone );
static uint8 zclSS_CountAllZones( void );
static uint8 zclSS_ZoneIDAvailable( uint8 zoneID );
#endif // ZCL_ZONE
#if defined(ZCL_ZONE) || defined(ZCL_ACE)
static IAS_ACE_ZoneTable_t *zclSS_FindZone( uint8 endpoint, uint8 zoneID );
#endif // ZCL_ZONE || ZCL_ACE
/******************************************************************************
* @fn zclSS_RegisterCmdCallbacks
*
* @brief Register an applications command callbacks
*
* @param endpoint - application's endpoint
* @param callbacks - pointer to the callback record.
*
* @return ZMemError if not able to allocate
*/
ZStatus_t zclSS_RegisterCmdCallbacks( uint8 endpoint, zclSS_AppCallbacks_t *callbacks )
{
zclSSCBRec_t *pNewItem;
zclSSCBRec_t *pLoop;
// Register as a ZCL Plugin
if ( !zclSSPluginRegisted )
{
zcl_registerPlugin( ZCL_CLUSTER_ID_SS_IAS_ZONE,
ZCL_CLUSTER_ID_SS_IAS_WD,
zclSS_HdlIncoming );
zclSSPluginRegisted = TRUE;
}
// Fill in the new profile list
pNewItem = osal_mem_alloc( sizeof( zclSSCBRec_t ) );
if ( pNewItem == NULL )
return (ZMemError);
pNewItem->next = (zclSSCBRec_t *)NULL;
pNewItem->endpoint = endpoint;
pNewItem->CBs = callbacks;
// Find spot in list
if ( zclSSCBs == NULL )
{
zclSSCBs = pNewItem;
}
else
{
// Look for end of list
pLoop = zclSSCBs;
while ( pLoop->next != NULL )
pLoop = pLoop->next;
// Put new item at end of list
pLoop->next = pNewItem;
}
return ( ZSuccess );
}
#ifdef ZCL_ZONE
/*******************************************************************************
* @fn zclSS_Send_IAS_ZoneStatusChangeNotificationCmd
*
* @brief Call to send out a Change Notification Command
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param zoneStatus - current zone status - bit map
* @param extendedStatus - bit map, currently set to All zeros ( reserved)
*
* @return ZStatus_t
*/
ZStatus_t zclSS_IAS_Send_ZoneStatusChangeNotificationCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint16 zoneStatus, uint8 extendedStatus,
uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[3];
buf[0] = LO_UINT16( zoneStatus );
buf[1] = HI_UINT16( zoneStatus );
buf[2] = extendedStatus;
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ZONE,
COMMAND_SS_IAS_ZONE_STATUS_CHANGE_NOTIFICATION, TRUE,
ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 3, buf );
}
/*******************************************************************************
* @fn zclSS_Send_IAS_ZoneStatusEnrollRequestCmd
*
* @brief Call to send out a Enroll Request Command
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param zoneType - current value of Zone Type attribute
* @param manufacturerCode - manuf. code from node descriptor for the device
*
* @return ZStatus_t
*/
ZStatus_t zclSS_IAS_Send_ZoneStatusEnrollRequestCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint16 zoneType, uint16 manufacturerCode,
uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[4];
buf[0] = LO_UINT16( zoneType );
buf[1] = HI_UINT16( zoneType );
buf[2] = LO_UINT16( manufacturerCode );
buf[3] = HI_UINT16( manufacturerCode );
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ZONE,
COMMAND_SS_IAS_ZONE_STATUS_ENROLL_REQUEST, TRUE,
ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 4, buf );
}
/*******************************************************************************
* @fn zclSS_IAS_Send_ZoneStatusEnrollResponseCmd
*
* @brief Call to send out a Enroll Response Command
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param responseCode - value of response Code
* @param zoneID - index to the zone table of the CIE
*
* @return ZStatus_t
*/
ZStatus_t zclSS_IAS_Send_ZoneStatusEnrollResponseCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint8 responseCode, uint8 zoneID,
uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[2];
buf[0] = responseCode;
buf[1] = zoneID;
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ZONE,
COMMAND_SS_IAS_ZONE_STATUS_ENROLL_RESPONSE, TRUE,
ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 2, buf );
}
#endif // ZCL_ZONE
#ifdef ZCL_ACE
/*******************************************************************************
* @fn zclSS_Send_IAS_ACE_ArmCmd
*
* @brief Call to send out a Arm Command ( IAS ACE Cluster )
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param armMode - value of armMode
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_ACE_ArmCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint8 armMode, uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[1];
buf[0] = armMode;
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
COMMAND_SS_IAS_ACE_ARM, TRUE,
ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 1, buf );
}
/*********************************************************************
* @fn zclSS_Send_IAS_ACE_BypassCmd
*
* @brief Call to send out a Bypass Command ( IAS ACE Cluster )
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param numberOfZones - one byte
* @param bypassBuf - zone IDs array of 256 entries one byte each
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_ACE_BypassCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint8 numberOfZones, uint8 *bypassBuf,
uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 *buf;
uint8 *pBuf;
uint8 len = 1 + numberOfZones;
ZStatus_t stat;
buf = osal_mem_alloc( len );
if ( buf )
{
pBuf = buf;
*pBuf++ = numberOfZones;
osal_memcpy( pBuf, bypassBuf, numberOfZones );
stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
COMMAND_SS_IAS_ACE_BYPASS, TRUE,
ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, len, buf );
osal_mem_free( buf );
}
else
stat = ZFailure;
return ( stat );
}
/*********************************************************************
* @fn zclSS_Send_IAS_ACE_GetZoneInformationCmd
*
* @brief Call to send out a Get Zone Information Command ( IAS ACE Cluster )
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param zoneID - 8 bit value from 0 to 255
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_ACE_GetZoneInformationCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint8 zoneID, uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[1];
buf[0] = zoneID;
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION, TRUE,
ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 1, buf );
}
/*******************************************************************************
* @fn zclSS_Send_IAS_ACE_ArmRespponse
*
* @brief Call to send out a Arm Response Command ( IAS ACE Cluster )
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param armNotification
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_ACE_ArmResponse( uint8 srcEP, afAddrType_t *dstAddr,
uint8 armNotification, uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[1];
buf[0] = armNotification;
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
COMMAND_SS_IAS_ACE_ARM_RESPONSE, TRUE,
ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, 1, buf );
}
/*********************************************************************
* @fn zclSS_Send_IAS_ACE_GetZoneIDMapResponseCmd
*
* @brief Call to send out a Get Zone ID Map Response Cmd ( IAS ACE Cluster )
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param zoneIDMap - pointer to an array of 16 uint16
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_ACE_GetZoneIDMapResponseCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint16 *zoneIDMap, uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 *buf;
uint8 *pIndex;
uint8 j,len = 32;
ZStatus_t stat;
buf = osal_mem_alloc( len );
if ( buf )
{
pIndex = buf;
for( j = 0; j < 16; j++ )
{
*pIndex++ = LO_UINT16( *zoneIDMap );
*pIndex++ = HI_UINT16( *zoneIDMap++ );
}
stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP_RESPONSE, TRUE,
ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, len, buf );
osal_mem_free( buf );
}
else
stat = ZMemError;
return ( stat );
}
/*******************************************************************************
* @fn zclSS_Send_IAS_ACE_GetZoneInformationResponseCmd
*
* @brief Call to send out Get Zone Information Response Cmd (IAS ACE Cluster)
*
* @param srcEP - Sending application's endpoint
* @param dstAddr - where you want the message to go
* @param zoneID - 8 bit value from 0 to 255
* @param zoneType - 16 bit
* @param ieeeAddress - pointer to 64 bit address ( 8bytes*8)
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_ACE_GetZoneInformationResponseCmd( uint8 srcEP, afAddrType_t *dstAddr,
uint8 zoneID, uint16 zoneType, uint8 *ieeeAddress,
uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 *buf;
uint8 len = 11; // zoneID (1) + zoneType (2) + zoneAddress (8)
ZStatus_t stat;
buf = osal_mem_alloc( len );
if ( buf )
{
buf[0] = zoneID;
buf[1] = LO_UINT16( zoneType);
buf[2] = HI_UINT16( zoneType);
osal_cpyExtAddr( &buf[3], ieeeAddress );
stat = zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_ACE,
COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION_RESPONSE, TRUE,
ZCL_FRAME_SERVER_CLIENT_DIR, disableDefaultRsp, 0, seqNum, len, buf );
osal_mem_free( buf );
}
else
stat = ZMemError;
return ( stat );
}
#endif // ZCL_ACE
#ifdef ZCL_WD
/*******************************************************************************
* @fn zclSS_Send_IAS_WD_StartWarningCmd
*
* @brief Call to send out a Start Warning Command (IAS WD Cluster)
*
* @param warning - 3 bytes of type zclCmdSSWDStartWarningPayload_t
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_WD_StartWarningCmd( uint8 srcEP, afAddrType_t *dstAddr,
zclCmdSSWDStartWarningPayload_t *warning,
uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[3];
buf[0] = warning->warningmessage.warningbyte;
buf[1] = LO_UINT16( warning->duration );
buf[2] = HI_UINT16( warning->duration );
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_WD,
COMMAND_SS_IAS_WD_START_WARNING, TRUE,
ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 3, buf );
}
/******************************************************************************
* @fn zclSS_Send_IAS_WD_StartWarningCmd
*
* @brief Call to send out a Squawk Command ( IAS WD Cluster )
*
* @param squawk - one byte of type zclCmdSSWDSquawkPayload_t
*
* @return ZStatus_t
*/
ZStatus_t zclSS_Send_IAS_WD_SquawkCmd( uint8 srcEP, afAddrType_t *dstAddr,
zclCmdSSWDSquawkPayload_t *squawk,
uint8 disableDefaultRsp, uint8 seqNum )
{
uint8 buf[1];
buf[0] = squawk->squawkbyte;
return zcl_SendCommand( srcEP, dstAddr, ZCL_CLUSTER_ID_SS_IAS_WD,
COMMAND_SS_IAS_WD_SQUAWK, TRUE,
ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, seqNum, 1, buf);
}
#endif // ZCL_WD
/*********************************************************************
* @fn zclSS_FindCallbacks
*
* @brief Find the callbacks for an endpoint
*
* @param endpoint
*
* @return pointer to the callbacks
*/
static zclSS_AppCallbacks_t *zclSS_FindCallbacks( uint8 endpoint )
{
zclSSCBRec_t *pCBs;
pCBs = zclSSCBs;
while ( pCBs )
{
if ( pCBs->endpoint == endpoint )
return ( pCBs->CBs );
pCBs = pCBs->next;
}
return ( (zclSS_AppCallbacks_t *)NULL );
}
/*********************************************************************
* @fn zclSS_HdlIncoming
*
* @brief Callback from ZCL to process incoming Commands specific
* to this cluster library or Profile commands for attributes
* that aren't in the attribute list
*
* @param pInMsg - pointer to the incoming message
* @param logicalClusterID
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_HdlIncoming( zclIncoming_t *pInMsg )
{
ZStatus_t stat = ZSuccess;
#if defined ( INTER_PAN )
if ( StubAPS_InterPan( pInMsg->msg->srcAddr.panId, pInMsg->msg->srcAddr.endPoint ) )
return ( stat ); // Cluster not supported thru Inter-PAN
#endif
if ( zcl_ClusterCmd( pInMsg->hdr.fc.type ) )
{
// Is this a manufacturer specific command?
if ( pInMsg->hdr.fc.manuSpecific == 0 )
{
stat = zclSS_HdlInSpecificCommands( pInMsg );
}
else
{
// We don't support any manufacturer specific command -- ignore it.
stat = ZFailure;
}
}
else
{
// Handle all the normal (Read, Write...) commands
stat = ZFailure;
}
return ( stat );
}
/*********************************************************************
* @fn zclSS_HdlInSpecificCommands
*
* @brief Callback from ZCL to process incoming Commands specific
* to this cluster library
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_HdlInSpecificCommands( zclIncoming_t *pInMsg )
{
ZStatus_t stat = ZSuccess;
zclSS_AppCallbacks_t *pCBs;
// make sure endpoint exists
pCBs = (void*)zclSS_FindCallbacks( pInMsg->msg->endPoint );
if ( pCBs == NULL )
return ( ZFailure );
switch ( pInMsg->msg->clusterId )
{
#ifdef ZCL_ZONE
case ZCL_CLUSTER_ID_SS_IAS_ZONE:
if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
stat = zclSS_ProcessInZoneStatusCmdsServer( pInMsg, pCBs );
else
stat = zclSS_ProcessInZoneStatusCmdsClient( pInMsg, pCBs );
break;
#endif // ZCL_ZONE
#ifdef ZCL_ACE
case ZCL_CLUSTER_ID_SS_IAS_ACE:
if ( zcl_ServerCmd( pInMsg->hdr.fc.direction ) )
stat = zclSS_ProcessInACECmdsServer( pInMsg, pCBs );
else
stat = zclSS_ProcessInACECmdsClient( pInMsg, pCBs );
break;
#endif // ZCL_ACE
#ifdef ZCL_WD
case ZCL_CLUSTER_ID_SS_IAS_WD:
stat = zclSS_ProcessInWDCmds( pInMsg, pCBs );
break;
#endif // ZCL_WD
default:
stat = ZFailure;
break;
}
return ( stat );
}
#ifdef ZCL_ZONE
/*********************************************************************
* @fn zclSS_ProcessInZoneStatusCmdsServer
*
* @brief Callback from ZCL to process incoming Commands specific
* to this cluster library on a command ID basis
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_ProcessInZoneStatusCmdsServer( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
ZStatus_t stat = ZSuccess;
if ( pInMsg->hdr.commandID == COMMAND_SS_IAS_ZONE_STATUS_ENROLL_RESPONSE )
zclSS_ProcessInCmd_ZoneStatus_EnrollResponse( pInMsg, pCBs );
else
stat = ZFailure;
return ( stat );
}
/*********************************************************************
* @fn zclSS_ProcessInZoneStatusCmdsClient
*
* @brief Callback from ZCL to process incoming Commands specific
* to this cluster library on a command ID basis
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_ProcessInZoneStatusCmdsClient( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
ZStatus_t stat = ZSuccess;
switch ( pInMsg->hdr.commandID )
{
case COMMAND_SS_IAS_ZONE_STATUS_CHANGE_NOTIFICATION:
zclSS_ProcessInCmd_ZoneStatus_ChangeNotification( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ZONE_STATUS_ENROLL_REQUEST:
stat = zclSS_ProcessInCmd_ZoneStatus_EnrollRequest( pInMsg, pCBs );
break;
default:
stat = ZFailure;
break;
}
return ( stat );
}
#endif // ZCL_ZONE
#ifdef ZCL_ACE
/*********************************************************************
* @fn zclSS_ProcessInACECmdsServer
*
* @brief Callback from ZCL to process incoming Commands specific
* to this cluster library on a command ID basis
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_ProcessInACECmdsServer( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
ZStatus_t stat = ZSuccess;
switch ( pInMsg->hdr.commandID )
{
case COMMAND_SS_IAS_ACE_ARM:
stat = zclSS_ProcessInCmd_ACE_Arm( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ACE_BYPASS:
zclSS_ProcessInCmd_ACE_Bypass( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ACE_EMERGENCY:
zclSS_ProcessInCmd_ACE_Emergency( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ACE_FIRE:
zclSS_ProcessInCmd_ACE_Fire( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ACE_PANIC:
zclSS_ProcessInCmd_ACE_Panic( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP:
stat = zclSS_ProcessInCmd_ACE_GetZoneIDMap( pInMsg );
break;
case COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION:
stat = zclSS_ProcessInCmd_ACE_GetZoneInformation( pInMsg );
break;
default:
stat = ZFailure;
break;
}
return ( stat );
}
/*********************************************************************
* @fn zclSS_ProcessInACECmdsClient
*
* @brief Callback from ZCL to process incoming Commands specific
* to this cluster library on a command ID basis
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_ProcessInACECmdsClient( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
ZStatus_t stat = ZSuccess;
switch ( pInMsg->hdr.commandID )
{
case COMMAND_SS_IAS_ACE_ARM_RESPONSE:
zclSS_ProcessInCmd_ACE_ArmResponse( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP_RESPONSE:
zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION_RESPONSE:
zclSS_ProcessInCmd_ACE_GetZoneInformationResponse( pInMsg, pCBs );
break;
default:
stat = ZFailure;
break;
}
return ( stat );
}
#endif // ZCL_ACE
#ifdef ZCL_ZONE
/*********************************************************************
* @fn zclSS_AddZone
*
* @brief Add a zone for an endpoint
*
* @param endpoint -
* @param zone - new zone item
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_AddZone( uint8 endpoint, IAS_ACE_ZoneTable_t *zone )
{
zclSS_ZoneItem_t *pNewItem;
zclSS_ZoneItem_t *pLoop;
// Fill in the new profile list
pNewItem = osal_mem_alloc( sizeof( zclSS_ZoneItem_t ) );
if ( pNewItem == NULL )
return ( ZMemError );
// Fill in the plugin record.
pNewItem->next = (zclSS_ZoneItem_t *)NULL;
pNewItem->endpoint = endpoint;
osal_memcpy( (uint8*)&(pNewItem->zone), (uint8*)zone, sizeof ( IAS_ACE_ZoneTable_t ));
// Find spot in list
if ( zclSS_ZoneTable == NULL )
{
zclSS_ZoneTable = pNewItem;
}
else
{
// Look for end of list
pLoop = zclSS_ZoneTable;
while ( pLoop->next != NULL )
pLoop = pLoop->next;
// Put new item at end of list
pLoop->next = pNewItem;
}
return ( ZSuccess );
}
/*********************************************************************
* @fn zclSS_CountAllZones
*
* @brief Count the total number of zones
*
* @param none
*
* @return number of zones
*/
uint8 zclSS_CountAllZones( void )
{
zclSS_ZoneItem_t *pLoop;
uint8 cnt = 0;
// Look for end of list
pLoop = zclSS_ZoneTable;
while ( pLoop )
{
cnt++;
pLoop = pLoop->next;
}
return ( cnt );
}
/*********************************************************************
* @fn zclSS_GetNextFreeZoneID
*
* @brief Get the next free zone ID
*
* @param none
*
* @return free zone ID (0-254)
*/
static uint8 zclSS_GetNextFreeZoneID( void )
{
static uint8 nextAvailZoneID = 0;
if ( zclSS_ZoneIDAvailable( nextAvailZoneID ) == FALSE )
{
uint8 zoneID = nextAvailZoneID;
// Look for next available zone ID
do
{
if ( ++zoneID == ZCL_SS_MAX_ZONE_ID )
zoneID = 0; // roll over
} while ( (zoneID != nextAvailZoneID) && (zclSS_ZoneIDAvailable( nextAvailZoneID ) == FALSE) );
// Did we found a free zone ID?
if ( zoneID != nextAvailZoneID )
nextAvailZoneID = zoneID;
}
return ( nextAvailZoneID );
}
/*********************************************************************
* @fn zclSS_ZoneIDAvailable
*
* @brief Check to see whether zoneID is available for use
*
* @param zoneID - ID to look for zone
*
* @return TRUE if zoneID is available, FALSE otherwise
*/
static uint8 zclSS_ZoneIDAvailable( uint8 zoneID )
{
zclSS_ZoneItem_t *pLoop;
if ( zoneID < ZCL_SS_MAX_ZONE_ID )
{
pLoop = zclSS_ZoneTable;
while ( pLoop )
{
if ( pLoop->zone.zoneID == zoneID )
{
return ( FALSE );
}
pLoop = pLoop->next;
}
// Zone ID not in use
return ( TRUE );
}
return ( FALSE );
}
#endif // ZCL_ZONE
#if defined(ZCL_ZONE) || defined(ZCL_ACE)
/*********************************************************************
* @fn zclSS_FindZone
*
* @brief Find a zone with endpoint and ZoneID
*
* @param endpoint -
* @param zoneID - ID to look for zone
*
* @return a pointer to the zone information, NULL if not found
*/
static IAS_ACE_ZoneTable_t *zclSS_FindZone( uint8 endpoint, uint8 zoneID )
{
zclSS_ZoneItem_t *pLoop;
// Look for end of list
pLoop = zclSS_ZoneTable;
while ( pLoop )
{
if ( pLoop->endpoint == endpoint && pLoop->zone.zoneID == zoneID )
{
return ( &(pLoop->zone) );
}
pLoop = pLoop->next;
}
return ( (IAS_ACE_ZoneTable_t *)NULL );
}
/*********************************************************************
* @fn zclSS_RemoveZone
*
* @brief Remove a zone with endpoint and zoneID
*
* @param endpoint -
* @param zoneID - ID to look for zone
*
* @return TRUE if removed, FALSE if not found
*/
uint8 zclSS_RemoveZone( uint8 endpoint, uint8 zoneID )
{
zclSS_ZoneItem_t *pLoop;
zclSS_ZoneItem_t *pPrev;
// Look for end of list
pLoop = zclSS_ZoneTable;
pPrev = NULL;
while ( pLoop )
{
if ( pLoop->endpoint == endpoint && pLoop->zone.zoneID == zoneID )
{
if ( pPrev == NULL )
zclSS_ZoneTable = pLoop->next;
else
pPrev->next = pLoop->next;
// Free the memory
osal_mem_free( pLoop );
return ( TRUE );
}
pPrev = pLoop;
pLoop = pLoop->next;
}
return ( FALSE );
}
/*********************************************************************
* @fn zclSS_UpdateZoneAddress
*
* @brief Update Zone Address for zoneID
*
* @param endpoint -
* @param zoneID - ID to look for zone
* @param ieeeAddr - Device IEEE Address
*
* @return none
*/
void zclSS_UpdateZoneAddress( uint8 endpoint, uint8 zoneID, uint8 *ieeeAddr )
{
IAS_ACE_ZoneTable_t *zone;
zone = zclSS_FindZone( endpoint, zoneID );
if ( zone != NULL )
{
// Update the zone address
osal_cpyExtAddr( zone->zoneAddress, ieeeAddr );
}
}
#endif // ZCL_ZONE || ZCL_ACE
#ifdef ZCL_ZONE
/*******************************************************************************
* @fn zclSS_ProcessInCmd_ZoneStatus_ChangeNotification
*
* @brief Process in the received StatusChangeNotification Command.
*
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static void zclSS_ProcessInCmd_ZoneStatus_ChangeNotification( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ZONE_STATUS_CHANGE_NOTIFICATION )
return; // Error ignore the command
if ( pCBs->pfnChangeNotification )
{
zclZoneChangeNotif_t cmd;
cmd.zoneStatus = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
cmd.extendedStatus = pInMsg->pData[2];
pCBs->pfnChangeNotification( &cmd );
}
}
/*******************************************************************************
* @fn zclSS_ProcessInCmd_ZoneStatus_EnrollRequest
*
* @brief Process in the received StatusEnrollRequest Command.
*
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_ProcessInCmd_ZoneStatus_EnrollRequest( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
IAS_ACE_ZoneTable_t zone;
uint16 zoneType;
uint16 manuCode;
uint8 zoneID;
uint8 status;
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ZONE_STATUS_ENROLL_REQUEST )
return ( ZFailure ); // Error ignore the command
zoneType = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
manuCode = BUILD_UINT16( pInMsg->pData[2], pInMsg->pData[3] );
if ( zclSS_ZoneTypeSupported( zoneType ) )
{
// What if the entry already exists?????
if ( zclSS_CountAllZones() < ZCL_SS_MAX_ZONES-1 )
{
// Add zone to the table
zoneID = zclSS_GetNextFreeZoneID();
zone.zoneID = zoneID;
zone.zoneType = zoneType;
// The application will fill in the right IEEE Address later
osal_cpyExtAddr( zone.zoneAddress, (void *)zclSS_UknownIeeeAddress );
if ( zclSS_AddZone( pInMsg->msg->endPoint, &zone ) == ZSuccess )
{
status = ZCL_STATUS_SUCCESS;
}
else
{
// CIE does not permit new zones to enroll at this time
status = SS_IAS_ZONE_STATUS_ENROLL_RESPONSE_CODE_NO_ENROLL_PERMIT;
}
}
else
{
// CIE reached its limit of number of enrolled zones
status = SS_IAS_ZONE_STATUS_ENROLL_RESPONSE_CODE_TOO_MANY_ZONES;
}
}
else
{
// Zone type is not known to CIE and is not supported
status = SS_IAS_ZONE_STATUS_ENROLL_RESPONSE_CODE_NOT_SUPPORTED;
}
// Send a response back
zclSS_IAS_Send_ZoneStatusEnrollResponseCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
status, zoneID, true, pInMsg->hdr.transSeqNum );
if ( status == ZCL_STATUS_SUCCESS )
{
// Callback the application so it can fill in the Device IEEE Address
if ( pCBs->pfnEnrollRequest )
{
zclZoneEnrollReq_t req;
req.srcAddr = &(pInMsg->msg->srcAddr);
req.zoneID = zoneID;
req.zoneType = zoneType;
req.manufacturerCode = manuCode;
pCBs->pfnEnrollRequest( &req );
}
}
return ( ZCL_STATUS_CMD_HAS_RSP );
}
/*******************************************************************************
* @fn zclSS_ProcessInCmd_ZoneStatus_EnrollResponse
*
* @brief Process in the received STATUS_ENROLL_RESPONSE Command.
*
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static void zclSS_ProcessInCmd_ZoneStatus_EnrollResponse( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ZONE_STATUS_ENROLL_RESPONSE )
return; // Error ignore the command
if ( pCBs->pfnEnrollResponse )
{
zclZoneEnrollRsp_t rsp;
rsp.responseCode = pInMsg->pData[0];
rsp.zoneID = pInMsg->pData[1];
pCBs->pfnEnrollResponse( &rsp );
}
}
#endif // ZCL_ZONE
#ifdef ZCL_ACE
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_Arm
*
* @brief Process in the received Arm Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static ZStatus_t zclSS_ProcessInCmd_ACE_Arm( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
uint8 armNotification;
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_ARM )
return ( ZFailure ); // Error ignore the command
if ( pCBs->pfnACE_Arm )
{
armNotification = pCBs->pfnACE_Arm( pInMsg->pData[0] );
// Send a response back
zclSS_Send_IAS_ACE_ArmResponse( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
armNotification, true, pInMsg->hdr.transSeqNum );
}
return ( ZCL_STATUS_CMD_HAS_RSP );
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_Bypass
*
* @brief Process in the received Bypass Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_ACE_Bypass( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_BYPASS )
return; // Error ignore the command
if ( pCBs->pfnACE_Bypass )
{
zclACEBypass_t cmd;
cmd.numberOfZones = pInMsg->pData[0];
cmd.bypassBuf = &(pInMsg->pData[1]);
pCBs->pfnACE_Bypass( &cmd ) ;
}
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_Emergency
*
* @brief Process in the received Emergency Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_ACE_Emergency( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_EMERGENCY )
return; // Error ignore the command
if ( pCBs->pfnACE_Emergency )
pCBs->pfnACE_Emergency();
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_Fire
*
* @brief Process in the received Fire Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_ACE_Fire( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_FIRE )
return; // Error ignore the command
if ( pCBs->pfnACE_Fire )
pCBs->pfnACE_Fire();
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_Panic
*
* @brief Process in the received Panic Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_ACE_Panic( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_PANIC )
return; // Error ignore the command
if ( pCBs->pfnACE_Panic )
pCBs->pfnACE_Panic();
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_GetZoneIDMap
*
* @brief Process in the received GetZoneIDMap Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneIDMap( zclIncoming_t *pInMsg )
{
uint16 zoneIDMap[16];
uint16 mapSection;
uint8 zoneID;
uint8 i, j;
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP )
return ( ZFailure ); // Error ignore the command
for ( i = 0; i < 16; i++ )
{
mapSection = 0;
// Find out Zone IDs that are allocated for this map section
for ( j = 0; j < 16; j++ )
{
zoneID = 16 * i + j;
if ( zclSS_FindZone( pInMsg->msg->endPoint, zoneID ) != NULL )
{
// Set the corresponding bit
mapSection |= (0x01 << j );
}
}
zoneIDMap[i] = mapSection;
}
// Send a response back
zclSS_Send_IAS_ACE_GetZoneIDMapResponseCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
zoneIDMap, true, pInMsg->hdr.transSeqNum );
return ( ZCL_STATUS_CMD_HAS_RSP );
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_GetZoneInformation
*
* @brief Process in the received GetZoneInformation Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static ZStatus_t zclSS_ProcessInCmd_ACE_GetZoneInformation( zclIncoming_t *pInMsg )
{
IAS_ACE_ZoneTable_t zone;
IAS_ACE_ZoneTable_t *pZone;
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION )
return ( ZFailure ); // Error ignore the command
pZone = zclSS_FindZone( pInMsg->msg->endPoint, pInMsg->pData[0] );
if ( pZone == NULL )
{
// Zone not found
pZone = &zone;
pZone->zoneID = pInMsg->pData[0];
pZone->zoneType = SS_IAS_ZONE_TYPE_INVALID_ZONE_TYPE;
osal_cpyExtAddr( pZone->zoneAddress, (void *)zclSS_UknownIeeeAddress );
}
// Send a response back
zclSS_Send_IAS_ACE_GetZoneInformationResponseCmd( pInMsg->msg->endPoint, &(pInMsg->msg->srcAddr),
pZone->zoneID, pZone->zoneType,
pZone->zoneAddress, true, pInMsg->hdr.transSeqNum );
return ( ZCL_STATUS_CMD_HAS_RSP );
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_ArmResponse
*
* @brief Process in the received Arm Response Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_ACE_ArmResponse( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_ARM_RESPONSE )
return; // Error ignore the command
if ( pCBs->pfnACE_ArmResponse )
pCBs->pfnACE_ArmResponse(pInMsg->pData[0]);
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse
*
* @brief Process in the received GetZoneIDMapResponse Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_ACE_GetZoneIDMapResponse( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
uint16 *buf;
uint16 *pIndex;
uint8 *pData;
uint8 i, len = 32; // 16 fields of 2 octects
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_ID_MAP_RESPONSE )
return; // Error ignore the command
buf = osal_mem_alloc( len );
if ( buf )
{
pIndex = buf;
pData = pInMsg->pData;
for ( i = 0; i < 16; i++ )
{
*pIndex++ = BUILD_UINT16( pData[0], pData[1] );
pData += 2;
}
if ( pCBs->pfnACE_GetZoneIDMapResponse )
pCBs->pfnACE_GetZoneIDMapResponse( buf );
osal_mem_free( buf );
}
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_ACE_GetZoneInformationResponse
*
* @brief Process in the received GetZoneInformationResponse Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_ACE_GetZoneInformationResponse( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_ACE_GET_ZONE_INFORMATION_RESPONSE )
return; // Error ignore the command
if ( pCBs->pfnACE_GetZoneInformationResponse )
{
zclACEGetZoneInfoRsp_t rsp;
rsp.zoneID = pInMsg->pData[0];
rsp.zoneType = BUILD_UINT16( pInMsg->pData[1], pInMsg->pData[2] );
rsp.ieeeAddr = &(pInMsg->pData[3]);
pCBs->pfnACE_GetZoneInformationResponse( &rsp );
}
}
#endif // ZCL_ACE
#ifdef ZCL_WD
/*********************************************************************
* @fn zclSS_ProcessInWDCmds
*
* @brief Callback from ZCL to process incoming Commands specific
* to this cluster library on a command ID basis
* @param pInMsg - pointer to the incoming message
*
* @return ZStatus_t
*/
static ZStatus_t zclSS_ProcessInWDCmds( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
ZStatus_t stat = ZSuccess;
switch ( pInMsg->hdr.commandID )
{
case COMMAND_SS_IAS_WD_START_WARNING:
zclSS_ProcessInCmd_WD_StartWarning( pInMsg, pCBs );
break;
case COMMAND_SS_IAS_WD_SQUAWK:
zclSS_ProcessInCmd_WD_Squawk( pInMsg, pCBs );
break;
default:
stat = ZFailure;
break;
}
return ( stat );
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_WD_StartWarning
*
* @brief Process in the received StartWarning Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_WD_StartWarning( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_WD_START_WARNING )
return; // Error ignore the command
if ( pCBs->pfnWD_StartWarning )
{
zclWDStartWarning_t cmd;
cmd.warnings.warningbyte = pInMsg->pData[0];
cmd.duration = BUILD_UINT16( pInMsg->pData[1], pInMsg->pData[2] );
pCBs->pfnWD_StartWarning( &cmd );
}
}
/*********************************************************************
* @fn zclSS_ProcessInCmd_WD_Squawk
*
* @brief Process in the received Squawk Command.
*
* @param pInMsg - pointer to the incoming message
*
*/
static void zclSS_ProcessInCmd_WD_Squawk( zclIncoming_t *pInMsg,
zclSS_AppCallbacks_t *pCBs )
{
zclCmdSSWDSquawkPayload_t squawk;
if ( pInMsg->hdr.commandID != COMMAND_SS_IAS_WD_SQUAWK )
return; // Error ignore the command
if ( pCBs->pfnWD_Squawk )
{
squawk.squawkbyte = pInMsg->pData[0];
pCBs->pfnWD_Squawk( squawk );
}
}
#endif // ZCL_WD
/*******************************************************************************
*******************************************************************************/