SlideShare una empresa de Scribd logo
1 de 42
Descargar para leer sin conexión
© 2015 sivann inc. All Rights Reserved© 2015 sivann inc. All Rights Reserved
Pursue of Simplicity
support@sivann.com.tw
ZigBee ZCL Reporting Configuration
Example: TI Z-Stack Home 1.2.1/1.2.2 SampleLight
2
“The ZCL acts as a repository for cluster functionality that
is developed by ZigBee. A developer constructing a new
profile should incorporate relevant ZCL cluster
functionality into the new profile.” [1]
ZCL foundation provides “general commands” for
manipulating attributes and other general tasks that are
not specific to an individual cluster.
Introduction
3
ZCL foundation general commands are provided with TI’s
Z-Stack ZCL APIs.
◦ Commands Read/Write (0x00 – 0x05) are handled in ZCL Foundation
Layer, and TI leaves the features of attribute reporting (0x06 – 0x0A)
for the developers to implement on application-level by their needs.
ZCL Foundation – General Commands
Cmd Id Description
0x00 Read attributes
0x01 Read attributes response
0x02 Write attributes
0x03 Write attributes undivided
0x04 Write attributes response
0x05 Write attributes no response
0x06 Configure reporting
0x07 Configure reporting response
0x08 Read reporting configuration
0x09 Read reporting configuration response
0x0A Report attributes
4
Implement these features within the incoming message handlers
zclSampleLight_ProcessInConfigReportCmd(), .etc.
ZCL_REPORT Feature in zcl_samplelight.c
static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg )
{
switch ( pInMsg->zclHdr.commandID )
{
...
#ifdef ZCL_REPORT
// Attribute Reporting implementation should be added here
case ZCL_CMD_CONFIG_REPORT:
// zclSampleLight_ProcessInConfigReportCmd( pInMsg );
break;
case ZCL_CMD_CONFIG_REPORT_RSP:
// zclSampleLight_ProcessInConfigReportRspCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG:
// zclSampleLight_ProcessInReadReportCfgCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG_RSP:
// zclSampleLight_ProcessInReadReportCfgRspCmd( pInMsg );
break;
case ZCL_CMD_REPORT:
// zclSampleLight_ProcessInReportCmd( pInMsg );
break;
...
typedef struct
{
osal_event_hdr_t hdr;
zclFrameHdr_t zclHdr;
uint16 clusterId;
afAddrType_t srcAddr;
uint8 endPoint;
void *attrCmd;
} zclIncomingMsg_t;
5
Our Goal
Make SampleLight application support the ZCL features of
◦ ZCL_CMD_CONFIG_REPORT
◦ ZCL_CMD_READ_REPORT_CFG
◦ ZCL_CMD_REPORT
SampleLight App
attr_1
attr_2
attr_N
ZCL_CMD_CONFIG_REPORT
ZCL_CMD_CONFIG_REPORT_RSP
ZCL_CMD_READ_REPORT_CFG
ZCL_CMD_READ_REPORT_CFG_RSP
A
Remote
ZigBee
Device
Device A: “I want you to report your
attr_1 and attr_2 in every X
seconds, or upon changing”
B
C
SampleLight: “OK, attr_1 and attr_2
are configured to
report as your request.”
Device B: “Please tell me about your
reporting configurations of
attr_1 and attr_3.”
SampleLight: “My attr_1 is reportable
and attr_3 is unreportable.”
Device C: “Please report your attr_1.”
6
Firmware
Stack version
◦ Z-Stack Home 1.2.1 / 1.2.2 ( http://www.ti.com/tool/z-stack )
Code to modify
◦ C:Texas InstrumentsZ-Stack Home 1.2.1
Componentsstackzcl
zcl.h
zcl.c
ProjectszstackHomeAutomationSampleLightSource
zcl_samplelight_data.c
zcl_samplelight.h
zcl_samplelight.c
https://github.com/sivann/samplelight_cfgreport
7
zcl.h
◦ Define two data types:
zclConfigReportRec_t : “Reporting config. record” for an endpoint
zclConfigReportRecsList : “Reporting config. records list” of all endpoints
zcl.c
◦ A function to register the “Reporting config. table”.
zcl_registerConfigReportRecList()
zcl_samplelight_data.c
◦ Add Config. Report Records to zcl_samplelight_data.c
zclConfigReportRec_t zclSampleLight_ConfigReportRecs[]
zcl_samplelight.h, zcl_samplelight.c
◦ Implementation of zcl attribute reporting features
Steps
8
zcl.h: New Data Types
/*********************************************************************
* TYPEDEFS
*/
// Configure Reporting Command format
...
} zclCfgReportRec_t;
typedef struct
{
uint16 clusterId;
uint16 timeup;
uint8 *lastReportValue;
zclCfgReportRec_t cfgReportRec;
} zclConfigReportRec_t;
/*********************************************************************
* CONSTANTS
*/
...
#define ZCL_FRAME_SERVER_CLIENT_DIR 0x01
/*** Report SEND/RECEIVE Directions ***/
#define ZCL_REPORT_SEND 0x00
#define ZCL_REPORT_RECEIVE 0x01
#ifdef ZCL_REPORT
// Config Report record list item
typedef struct zclConfigReportRecsList
{
struct zclConfigReportRecsList *next;
uint8 endpoint;
uint8 numConfigReportRec;
zclConfigReportRec_t *configReportRecs;
} zclConfigReportRecsList;
#endif // ZCL_REPORT
zclConfigReportRec_t
zclConfigReportRecsList
9
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRecsList
*next
endpoint
numConfigReportRec
*configReportRecs
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRecsList
*next
endpoint
numConfigReportRec
*configReportRecs
Rec_1 Rec_2 Rec_3
Rec_1 Rec_2 Rec_3
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRecsList
*next
endpoint
numConfigReportRec
*configReportRecs
Rec_1 Rec_2 Rec_3
List_for_Endpoint_1
List_for_Endpoint_2
List_for_Endpoint_3
10
zcl.h: Declare Local Variables and Functions
/*********************************************************************
* FUNCTIONS
*/
[...]
extern ZStatus_t zcl_registerAttrList( uint8 endpoint, uint8 numAttr,
CONST zclAttrRec_t attrList[] );
#ifdef ZCL_REPORT
/* Register Application's Config Report table */
extern ZStatus_t zcl_registerConfigReportRecList( uint8 endpoint, uint8 numConfigReportRec,
zclConfigReportRec_t newConfigReportRecList[] );
#endif // ZCL_REPORT
#ifdef ZCL_REPORT
[...]
extern uint8 zclAnalogDataType( uint8 dataType );
[...]
/* Function to find the Config Report Record of an Atribute that matches the parameters */
extern uint8 zclFindConfigReportRec( uint8 endpoint, uint16 clusterID, uint16 attrId,
zclConfigReportRec_t **pConfigReportRec );
extern zclConfigReportRecsList *zclFindConfigReportRecsList( uint8 endpoint );
#endif // ZCL_REPORT
11
Prototype of the Config. Table Register Function
zcl.c: Config. Table Register Function (I)
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRecsList
*next
endpoint
numConfigReportRec
*configReportRecs
Rec_1 Rec_2 Rec_3
ZStatus_t zcl_registerConfigReportRecList( uint8 endpoint,
uint8 numConfigReportRec,
zclConfigReportRec_t newConfigReportRecList[] )
12
zcl.c: Config. Table Register Function (II)
[...]
ZStatus_t zcl_registerCmdList( uint8 endpoint, CONST uint8 cmdListSize,
CONST zclCommandRec_t newCmdList[] )
{
[...]
}
#endif // ZCL_DISCOVER
#ifdef ZCL_REPORT
/*********************************************************************
* @fn zcl_registerConfigReportRecList
* @brief Register an ConfigReportRec List with ZCL Foundation
* @param endpoint - endpoint the attribute list belongs to
* @param numConfigReportRec - number of attributes in list
* @param newConfigReportRecList - array of Attribute records.
* @return ZSuccess if OK
*/
ZStatus_t zcl_registerConfigReportRecList( uint8 endpoint, uint8 numConfigReportRec,
zclConfigReportRec_t newConfigReportRecList[] )
{
zclConfigReportRecsList *pNewItem;
zclConfigReportRecsList *pLoop;
// Fill in the new profile list
pNewItem = zcl_mem_alloc( sizeof( zclConfigReportRecsList ) );
if ( pNewItem == NULL )
{
return (ZMemError);
}
13
pNewItem->next = (zclConfigReportRecsList *)NULL;
pNewItem->endpoint = endpoint;
pNewItem->numConfigReportRec = numConfigReportRec;
pNewItem->configReportRecs = newConfigReportRecList;
// Find spot in list
if ( configReportRecsList == NULL )
{
configReportRecsList = pNewItem;
}
else
{
// Look for end of list
pLoop = configReportRecsList;
while ( pLoop->next != NULL )
{
pLoop = pLoop->next;
}
// Put new item at end of list
pLoop->next = pNewItem;
}
return ( ZSuccess );
}
#endif // ZCL_REPORT
14
Prototype of the Config. Report Recs List Searching
Function
Prototype of the Config. Report Rec Searching Function
zcl.c: Config. Record Searching Function
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRec_t
clusterId
timeup
*lastReportValue
cfgReportRec
zclConfigReportRecsList
*next
endpoint
numConfigReportRec
*configReportRecs
Rec_1 Rec_2 Rec_3
zclConfigReportRecsList *zclFindConfigReportRecsList( uint8 endpoint )
uint8 zclFindConfigReportRec( uint8 endpoint, uint16 clusterID,
uint16 attrId,
zclConfigReportRec_t **pConfigReportRec )
15
Config. Report Recs List Searching Function
/*********************************************************************
* PRIVATE FUNCTIONS
*********************************************************************/
[...]
#ifdef ZCL_REPORT
/*********************************************************************
* @fn zclFindConfigReportRecsList
* @brief Find the right ConfigReport record list for an endpoint
* @param clusterID - endpoint to look for
* @return pointer to record list, NULL if not found
*/
zclConfigReportRecsList *zclFindConfigReportRecsList( uint8 endpoint )
{
zclConfigReportRecsList *pLoop = configReportRecsList;
while ( pLoop != NULL )
{
if ( pLoop->endpoint == endpoint )
{
return ( pLoop );
}
pLoop = pLoop->next;
}
return ( NULL );
}
16
/*********************************************************************
* @fn zclFindConfigReportRec
* @brief Find the configReportRec record that matches the parameters
* @param endpoint - Application's endpoint
* @param clusterID - cluster ID
* @param attrId - attribute looking for
* @param pConfigReportRec - ConfigReportRec record to be returned
* @return TRUE if record found. FALSE, otherwise.
*/
uint8 zclFindConfigReportRec( uint8 endpoint, uint16 clusterID, uint16 attrId,
zclConfigReportRec_t **pConfigReportRec )
{
uint8 x;
zclConfigReportRecsList *pRec = zclFindConfigReportRecsList( endpoint );
if ( pRec != NULL )
{
for ( x = 0; x < pRec->numConfigReportRec; x++ )
{
if ( pRec->configReportRecs[x].clusterId ==
clusterID && pRec->configReportRecs[x].cfgReportRec.attrID == attrId )
{
*pConfigReportRec = &(pRec->configReportRecs[x]);
return ( TRUE );
}
}
}
return ( FALSE );
}
#endif // ZCL_REPORT
Config. Report Rec Searching Function
17
zcl.c is ready. Now, we’re going to name the attributes
from clusters to be configured for reporting.
zcl_sampleligh_data.c: Arrangement
/*********************************************************************
* GLOBAL VARIABLES
*/
const uint8 zclSampleLight_HWRevision = SAMPLELIGHT_HWVERSION;
[...]
uint8 zclSampleLight_OnOffLastReportValue = LIGHT_OFF;
#ifdef ZCL_LEVEL_CTRL
uint8 zclSampleLight_LevelCurrentLevel = ATTR_LEVEL_MIN_LEVEL;
uint8 zclSampleLight_LevelCurrentLevelChange = 50;
uint8 zclSampleLight_LevelLastReportValue = ATTR_LEVEL_MIN_LEVEL;
[...]
#endif
#ifdef ZCL_REPORT
zclConfigReportRec_t zclSampleLight_ConfigReportRecs[] =
{
// See Next Slide
{
...
18
typedef struct
{
uint16 clusterId;
uint16 timeup;
uint8 *lastReportValue;
zclCfgReportRec_t cfgReportRec;
} zclConfigReportRec_t;
typedef struct
{
uint8 direction;
uint16 attrID;
uint8 dataType;
uint16 minReportInt;
uint16 maxReportInt;
uint16 timeoutPeriod;
uint8 *reportableChange;
} zclCfgReportRec_t;
zclConfigReportRec_t zclSampleLight_ConfigReportRecs[] =
{ // *** On/Off Cluster Attr ConfigReportRec ***
{
ZCL_CLUSTER_ID_GEN_ON_OFF,
0xFFFF,
(void *)&zclSampleLight_OnOffLastReportValue,
{ // CfgReportRec
ZCL_REPORT_SEND,
ATTRID_ON_OFF,
ZCL_DATATYPE_BOOLEAN,
0,
0xFFFF,
0,
NULL // need not set for
} // DISCRETE datatype
}
#ifdef ZCL_LEVEL_CTRL
,{
ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
0xFFFF,
(void *)&zclSampleLight_LevelLastReportValue,
{
ZCL_REPORT_SEND,
ATTRID_LEVEL_CURRENT_LEVEL,
ZCL_DATATYPE_UINT8,
0,
0xFFFF,
0,
(void *)&zclSampleLight_LevelCurrentLevelChange
}
}
#endif
};
uint8 CONST zclSampleLight_NumConfigReportRecs =
( sizeof(zclSampleLight_ConfigReportRecs) / sizeof(zclSampleLight_ConfigReportRecs[0]) );
#endif
timeup
clusterId
*lastReportValue
direction
attrID
dataType
minReportInt
maxReportInt
timeoutPeroid
*reportableChange
19
zcl_samplelight.h: Declarations
/*********************************************************************
* VARIABLES
*/
[...]
extern CONST uint8 zclCmdsArraySize;
extern CONST uint8 zclSampleLight_NumConfigReportRecs;
extern zclConfigReportRec_t zclSampleLight_ConfigReportRecs[];
[...]
// OnOff attributes
extern uint8 zclSampleLight_OnOff;
extern uint8 zclSampleLight_OnOffLastReportValue;
// Level Control Attributes
#ifdef ZCL_LEVEL_CTRL
[...]
extern uint8 zclSampleLight_LevelCurrentLevelChange;
extern uint8 zclSampleLight_LevelLastReportValue;
#endif
/*********************************************************************
* CONSTANTS
*/
#define SAMPLELIGHT_ENDPOINT 8
[...]
// Application Events
#define SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT 0x0001
[...]
#define SAMPLELIGHT_START_EZMODE_EVT 0x0040
#define SAMPLELIGHT_CHECK_REPORT_EVT 0x0080
20
zcl_samplelight.c : Declarations
/*********************************************************************
* LOCAL VARIABLES
*/
afAddrType_t zclSampleLight_DstAddr;
uint16 gTimeCounter = 0;
/*********************************************************************
* LOCAL FUNCTIONS
*/
#ifdef ZCL_LEVEL_CTRL
[...]
static void sendZclAttrChangeReport(uint8 srcEp, uint16 clusterId, uint16 attrID,
uint8 *lastReportValue, uint8 *currentValue);
#endif
[...]
#ifdef ZCL_REPORT
[...]
static void zclSampleLight_CheckReportConfig( void );
static uint8 sendZclAttrReport(uint8 srcEp, uint16 clusterID, zclReportCmd_t *pReportCmd,
uint8 dataLen);
static void zclSampleLight_CheckandSendClusterAttrReport( uint16 clusterID,
zclConfigReportRecsList *pConfigReportRecsList );
#endif
21
zcl_samplelight.c : Register the Report Recs
void zclSampleLight_Init( byte task_id )
{
zclSampleLight_TaskID = task_id;
[...]
// Register the application's attribute list
zcl_registerAttrList( SAMPLELIGHT_ENDPOINT, zclSampleLight_NumAttributes,
zclSampleLight_Attrs );
#ifdef ZCL_REPORT
// Register the application's config report record list
zcl_registerConfigReportRecList( SAMPLELIGHT_ENDPOINT, zclSampleLight_NumConfigReportRecs,
zclSampleLight_ConfigReportRecs );
#endif
// Register the Application to receive the unprocessed Foundation command/response messages
zcl_registerForMsg( zclSampleLight_TaskID );
[...]
}
22
Arrange an event handler (for event: SAMPLELIGHT_CHECK_REPORT_EVT)
to check if there is a reportable timeout attribute.
zcl_samplelight.c: Event Handler
uint16 zclSampleLight_event_loop( uint8 task_id, uint16 events )
{
[...]
#ifdef ZCL_LEVEL_CTRL
if ( events & SAMPLELIGHT_LEVEL_CTRL_EVT )
{
zclSampleLight_AdjustLightLevel();
return ( events ^ SAMPLELIGHT_LEVEL_CTRL_EVT );
}
#endif
#ifdef ZCL_REPORT
if ( events & SAMPLELIGHT_CHECK_REPORT_EVT )
{
zclSampleLight_CheckReportConfig( &zclSampleLightSeqNum );
return ( events ^ SAMPLELIGHT_CHECK_REPORT_EVT );
}
#endif
// Discard unknown events
return 0;
}
23
Check If an Reportable Attribute is Timeout
#ifdef ZCL_REPORT
/*********************************************************************
* @fn zclSampleLight_CheckReportConfig
* @brief Check if there is a reportable attribute is timeout to report
* @param none
* @return none
*/
static void zclSampleLight_CheckReportConfig( void )
{
uint8 x, y;
uint8 stopChecking = TRUE;
zclConfigReportRecsList *pConfigReportRecsList = zclFindConfigReportRecsList(SAMPLELIGHT_ENDPOINT);
if ( pConfigReportRecsList != NULL )
{
for ( x = 0; x < pConfigReportRecsList->numConfigReportRec; x++ )
{
uint8 cIdDuplicate = 0;
for ( y = 0; y < x; y++ )
{
if ( pConfigReportRecsList->configReportRecs[x].clusterId ==
pConfigReportRecsList->configReportRecs[y].clusterId ) {
cIdDuplicate = 1;
}
}
if (!cIdDuplicate) {
zclSampleLight_CheckandSendClusterAttrReport( pConfigReportRecsList->
configReportRecs[x].clusterId, pConfigReportRecsList );
}
24
if (pConfigReportRecsList->configReportRecs[x].cfgReportRec.maxReportInt != 0xFFFF) {
stopChecking = FALSE; // at least one attr in this endpoint is setting to report,
} // don't stop checking
}
}
gTimeCounter++; // time ticks every second for attr report
if (!stopChecking) {
osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_CHECK_REPORT_EVT, 1000 );
}
}
static void zclSampleLight_CheckandSendClusterAttrReport( uint16 clusterID,
zclConfigReportRecsList *pConfigReportRecsList )
{
uint8 numAttr = 0;
uint8 x;
uint16 len;
zclReportCmd_t *pReportCmd;
zclConfigReportRec_t *pConfigReportRec = NULL;
zclAttrRec_t attrRec;
for ( x = 0; x < pConfigReportRecsList->numConfigReportRec; x++ )
{
pConfigReportRec = &(pConfigReportRecsList->configReportRecs[x]);
// find out how many attributes are timeout in this cluster
if ( pConfigReportRec->clusterId == clusterID && pConfigReportRec->
cfgReportRec.maxReportInt != 0xFFFF) {
if (pConfigReportRec->timeup == 0xFFFF || pConfigReportRec->timeup == gTimeCounter)
{
numAttr++;
}
}
}
25
if (numAttr != 0) {
// We need to send a report - allocate space for it
len = sizeof( zclReportCmd_t ) + (numAttr * sizeof( zclReport_t ));
pReportCmd = (zclReportCmd_t *)zcl_mem_alloc( len );
pReportCmd->numAttr = numAttr;
}
numAttr = 0;
for ( x = 0; x < pConfigReportRecsList->numConfigReportRec; x++ )
{
zclReport_t *reportRec;
pConfigReportRec = &(pConfigReportRecsList->configReportRecs[x]);
if ( pConfigReportRec->clusterId == clusterID && pConfigReportRec->
cfgReportRec.maxReportInt != 0xFFFF) // need report
{ // timeout to report
if (pConfigReportRec->timeup == 0xFFFF || pConfigReportRec->timeup == gTimeCounter)
{
// fill the record in *pReportCmd
reportRec = &(pReportCmd->attrList[numAttr]);
zcl_memset( reportRec, 0, sizeof( zclReport_t ) );
numAttr++;
zclFindAttrRec( SAMPLELIGHT_ENDPOINT, pConfigReportRec->clusterId,
pConfigReportRec->cfgReportRec.attrID, &attrRec);
reportRec->attrID = attrRec.attr.attrId;
reportRec->dataType = attrRec.attr.dataType;
reportRec->attrData = attrRec.attr.dataPtr;
26
// calculate next timeout value
if (pConfigReportRec->cfgReportRec.minReportInt == 0) {
pConfigReportRec->timeup = gTimeCounter +
pConfigReportRec->cfgReportRec.maxReportInt;
} else {
pConfigReportRec->timeup = gTimeCounter +
pConfigReportRec->cfgReportRec.minReportInt;
}
}
}
}
if (numAttr != 0) {
// send report
sendZclAttrReport( SAMPLELIGHT_ENDPOINT, clusterID, pReportCmd, len);
}
}
#endif
static uint8 sendZclAttrReport(uint8 srcEp, uint16 clusterID, zclReportCmd_t *pReportCmd,
uint8 dataLen)
{
zclIncomingMsg_t *pMsg; // this is for inner-app osal msg, not OTA msg,
// thus we will see that some fields are not important
// pMsg will be released by zclSampleLight_event_loop()
pMsg = (zclIncomingMsg_t *)osal_msg_allocate( sizeof(zclIncomingMsg_t) + (dataLen));
if ( pMsg == NULL )
{
return FALSE; // EMBEDDED RETURN
}
27
if (pMsg) // inner-app osal message
{
pMsg->hdr.event = ZCL_INCOMING_MSG;
pMsg->hdr.status = 0;
//pMsg->zclHdr.fc = NULL; // not important
pMsg->zclHdr.manuCode = 0; // not important
pMsg->zclHdr.transSeqNum = 0; // not important
pMsg->zclHdr.commandID = ZCL_CMD_REPORT; // send this report message to ZCL_CMD_REPORT
// event handler
pMsg->clusterId = clusterID;
pMsg->srcAddr.addrMode = (afAddrMode_t)Addr16Bit;
pMsg->srcAddr.addr.shortAddr = 0; // not important
pMsg->srcAddr.panId = 0; // inner-PAN, not important
pMsg->srcAddr.endPoint = srcEp; // src ep, SAMPLELIGHT_ENDPOINT send to himself
pMsg->endPoint = srcEp; // dest ep, send to SAMPLELIGHT_ENDPOINT himself
pMsg->attrCmd = (zclReportCmd_t *)pReportCmd;
}
osal_msg_send( zclSampleLight_TaskID, (uint8 *)pMsg );
return ( TRUE );
}
case ZCL_CMD_REPORT:
zclSampleLight_ProcessInReportCmd( pInMsg );
break;
28
Call sendZclAttrChangeReport() to send out the
current attribute.
When the Reportable Attribute is Changed
static void zclSampleLight_HandleKeys( byte shift, byte keys )
{
if ( keys & HAL_KEY_SW_1 ) {
giLightScreenMode = LIGHT_MAINMODE;
if (zclSampleLight_OnOffLastReportValue != zclSampleLight_OnOff) {
sendZclAttrChangeReport(SAMPLELIGHT_ENDPOINT, ZCL_CLUSTER_ID_GEN_ON_OFF, ATTRID_ON_OFF,
&zclSampleLight_OnOffLastReportValue, &zclSampleLight_OnOff);
}
}
[...]
static void zclSampleLight_OnOffCB( uint8 cmd )
{
[...]
else if ( cmd == COMMAND_TOGGLE ) {
[...]
}
if (zclSampleLight_OnOffLastReportValue != zclSampleLight_OnOff) {
sendZclAttrChangeReport(SAMPLELIGHT_ENDPOINT, ZCL_CLUSTER_ID_GEN_ON_OFF, ATTRID_ON_OFF,
&zclSampleLight_OnOffLastReportValue, &zclSampleLight_OnOff);
}
[...]
29
static void zclSampleLight_AdjustLightLevel( void )
{
uint8 needReport = FALSE;
[...]
if ( zclSampleLight_LevelRemainingTime == 0)
{
zclSampleLight_LevelCurrentLevel = zclSampleLight_NewLevel;
// check if we need to report by change
if (zclSampleLight_LevelLastReportValue > zclSampleLight_LevelCurrentLevel) {
if (zclSampleLight_LevelLastReportValue - zclSampleLight_LevelCurrentLevel
>= zclSampleLight_LevelCurrentLevelChange) {
needReport = TRUE;
}
} else {
if (zclSampleLight_LevelCurrentLevel - zclSampleLight_LevelLastReportValue
>= zclSampleLight_LevelCurrentLevelChange) {
needReport = TRUE;
}
}
if (needReport) {
sendZclAttrChangeReport(SAMPLELIGHT_ENDPOINT, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL,
ATTRID_LEVEL_CURRENT_LEVEL,
&zclSampleLight_LevelLastReportValue,
&zclSampleLight_LevelCurrentLevel);
}
}
30
/*********************************************************************
* @fn sendZclAttrChangeReport
* @brief Send the attr report when the attr is changed
* @param srcEp - source endpoint
[...]
static void sendZclAttrChangeReport(uint8 srcEp, uint16 clusterId, uint16 attrID,
uint8 *lastReportValue, uint8 *currentValue) {
if (*lastReportValue != *currentValue)
{ // if the current attr value is not equal to the last reported value, report the change
zclReportCmd_t *pReportCmd;
zclReport_t *reportRec;
zclAttrRec_t attrRec;
uint8 len;
len = sizeof( zclReportCmd_t ) + (1 * sizeof( zclReport_t ));
pReportCmd = (zclReportCmd_t *)zcl_mem_alloc( len );
pReportCmd->numAttr = 1;
reportRec = &(pReportCmd->attrList[0]);
zcl_memset( reportRec, 0, sizeof( zclReport_t ) );
zclFindAttrRec( SAMPLELIGHT_ENDPOINT, clusterId, attrID, &attrRec);
reportRec->attrID = attrRec.attr.attrId;
reportRec->dataType = attrRec.attr.dataType;
reportRec->attrData = attrRec.attr.dataPtr;
sendZclAttrReport(SAMPLELIGHT_ENDPOINT, clusterId, pReportCmd, len);
*lastReportValue = *currentValue;
}
}
31
When We Got a Report Cmd
static uint8 zclSampleLight_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
{
zclReportCmd_t *pReportCmd;
// *pReportCmd will be free by handler: zclSampleLight_ProcessIncomingMsg()
pReportCmd = (zclReportCmd_t *)pInMsg->attrCmd;
afAddrType_t dstAddr;
dstAddr.addrMode = (afAddrMode_t)AddrNotPresent; // send report to bound remote endpoints
zcl_SendReportCmd( SAMPLELIGHT_ENDPOINT, &dstAddr, pInMsg->clusterId, pReportCmd,
ZCL_REPORT_SEND, true, zclSampleLightSeqNum++);
// you can send additional reportable attributes as needed
/** zcl_SendReportCmd ( SAMPLELIGHT_ENDPOINT, &dstAddr, ...); **/
// i.e. for Thermostat Cluster that reports LocalTemperature, PICoolingDemand, and PIHeatingDemand.
// see ZIGBEE CLUSTER LIBRARY SPECIFICATION: 6.3.2.5 Attribute Reporting of the Thermostat Cluster
return ( TRUE );
}
32
When We Got a Config Report Cmd
#ifdef ZCL_REPORT
/*********************************************************************
* @fn zclSampleLight_ProcessInConfigReportCmd
* @brief Process the "Profile" Config Report Command
* @param pInMsg - incoming message to process
* @return none
*/
static uint8 zclSampleLight_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg )
{
zclCfgReportCmd_t *pCfgReportCmd;
zclCfgReportRspCmd_t *pCfgReportRspCmd;
uint8 sendRsp = FALSE;
uint16 len;
uint8 j = 0;
uint8 i;
pCfgReportCmd = (zclCfgReportCmd_t *)pInMsg->attrCmd;
if ( pInMsg->zclHdr.commandID == ZCL_CMD_CONFIG_REPORT )
{
// We need to send a response back - allocate space for it
len = sizeof( zclCfgReportRspCmd_t ) + (pCfgReportCmd->numAttr *
sizeof( zclCfgReportStatus_t ));
pCfgReportRspCmd = (zclCfgReportRspCmd_t *)zcl_mem_alloc( len );
if ( pCfgReportRspCmd == NULL ) {
return FALSE; // EMBEDDED RETURN
}
sendRsp = TRUE; // sendRsp is active when we got correct commandID
}
33
for ( i = 0; i < pCfgReportCmd->numAttr; i++ )
{
zclConfigReportRec_t *pConfigReportRec = NULL; // find the rec and store here
zclAttrRec_t attrRec;
zclCfgReportStatus_t *statusRec = &(pCfgReportRspCmd->attrList[i]);
zcl_memset( statusRec, 0, sizeof( zclCfgReportStatus_t ) );
if ( zclFindConfigReportRec( pInMsg->endPoint, pInMsg->clusterId,
pCfgReportCmd->attrList[i].attrID, &pConfigReportRec ) )
{
uint8 status = ZCL_STATUS_SUCCESS;
if ( pCfgReportCmd->attrList[i].dataType != pConfigReportRec->cfgReportRec.dataType ) {
status = ZCL_STATUS_INVALID_DATA_TYPE;
}
else
{
if ( zclFindAttrRec( pInMsg->endPoint, pInMsg->clusterId,
pCfgReportCmd->attrList[i].attrID, &attrRec ) )
{
if ( pCfgReportCmd->attrList[i].dataType != attrRec.attr.dataType ) {
status = ZCL_STATUS_INVALID_DATA_TYPE;
}
else
{
if ( !zcl_AccessCtrlRead( attrRec.attr.accessControl ) )
{
status = ZCL_STATUS_WRITE_ONLY;
}
}
}
}
34
// If successful, store the record, and a CfgReportStatus record shall NOT be generated
if ( sendRsp && status != ZCL_STATUS_SUCCESS )
{
// Attribute is write only or invalid data type - move on to the next record
statusRec->status = status;
statusRec->direction = pCfgReportCmd->attrList[i].direction;
statusRec->attrID = pCfgReportCmd->attrList[i].attrID;
j++;
} else { // success, set the config report rec
pConfigReportRec->cfgReportRec.direction = pCfgReportCmd->attrList[i].direction;
pConfigReportRec->cfgReportRec.minReportInt = pCfgReportCmd->attrList[i].minReportInt;
pConfigReportRec->cfgReportRec.maxReportInt = pCfgReportCmd->attrList[i].maxReportInt;
pConfigReportRec->cfgReportRec.timeoutPeriod = pCfgReportCmd->attrList[i].timeoutPeriod;
pConfigReportRec->timeup = 0xFFFF;
}
}
else
{ // Attribute is not supported - move on to the next configReportRec record
if ( sendRsp )
{
statusRec->status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
statusRec->direction = pCfgReportCmd->attrList[i].direction;
statusRec->attrID = pCfgReportCmd->attrList[i].attrID;
j++;
}
}
} // for loop
35
if ( sendRsp )
{
pCfgReportRspCmd->numAttr = j;
if ( pCfgReportRspCmd->numAttr == 0 )
{
// Since all records were written successful, include a single status record
// in the response command with the status field set to SUCCESS and the
// attribute ID and direction fields omitted.
pCfgReportRspCmd->attrList[0].status = ZCL_STATUS_SUCCESS;
pCfgReportRspCmd->numAttr = 1;
}
zcl_SendConfigReportRspCmd( pInMsg->endPoint, &(pInMsg->srcAddr),
pInMsg->clusterId, pCfgReportRspCmd,
!pInMsg->zclHdr.fc.direction, true,
pInMsg->zclHdr.transSeqNum );
zcl_mem_free( pCfgReportRspCmd );
}
// When configured, check report config immediately
zclSampleLight_CheckReportConfig();
// The SAMPLELIGHT_CHECK_REPORT_EVT will then be triggered again and again
// If we never received the ConfigReportCmd, the SAMPLELIGHT_CHECK_REPORT_EVT has
// no change to be triggered.
// We think this makes sense, since there is no reason for your app to perform
// constantly report unless the app is configured to report.
// If your app just need to automatically report after bootup, you can trigger
// SAMPLELIGHT_CHECK_REPORT_EVT in zclSampleLight_Init().
return TRUE;
}
36
When We Got a Read Report Config Cmd
/*********************************************************************
* @fn zclSampleLight_ProcessInReadReportCfgCmd
* @brief Process the "Profile" Read Report Config Command
* @param pInMsg - incoming message to process
* @return none
*/
static uint8 zclSampleLight_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg )
{
zclReadReportCfgCmd_t *pReadReportCfgCmd;
zclReadReportCfgRspCmd_t *pReadReportCfgRspCmd;
uint8 sendRsp = FALSE;
uint16 len;
uint8 i;
pReadReportCfgCmd = (zclReadReportCfgCmd_t *)pInMsg->attrCmd;
if ( pInMsg->zclHdr.commandID == ZCL_CMD_READ_REPORT_CFG )
{
// We need to send a response back - allocate space for it
len = sizeof( zclReadReportCfgRspCmd_t ) + (pReadReportCfgCmd->numAttr *
sizeof( zclReportCfgRspRec_t ));
pReadReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)zcl_mem_alloc( len );
if ( pReadReportCfgRspCmd == NULL ) {
return FALSE; // EMBEDDED RETURN
}
sendRsp = TRUE; // sendRsp is active when we got correct commandID
}
37
for ( i = 0; i < pReadReportCfgCmd->numAttr; i++ )
{
zclConfigReportRec_t *pConfigReportRec = NULL; // find the rec and store here
zclReportCfgRspRec_t *pReportCfgRspRec = &(pReadReportCfgRspCmd->attrList[i]);
zclAttrRec_t attrRec;
zcl_memset( pReportCfgRspRec, 0, sizeof( zclReportCfgRspRec_t ) );
if ( zclFindConfigReportRec( pInMsg->endPoint, pInMsg->clusterId,
pReadReportCfgCmd->attrList[i].attrID, &pConfigReportRec ) )
{ // if found configReportRec
if ( sendRsp ) {
pReportCfgRspRec->status = ZCL_STATUS_SUCCESS;
pReportCfgRspRec->direction = pConfigReportRec->cfgReportRec.direction;
pReportCfgRspRec->attrID = pConfigReportRec->cfgReportRec.attrID;
pReportCfgRspRec->dataType = pConfigReportRec->cfgReportRec.dataType;
pReportCfgRspRec->minReportInt = pConfigReportRec->cfgReportRec.minReportInt;
pReportCfgRspRec->maxReportInt = pConfigReportRec->cfgReportRec.maxReportInt;
pReportCfgRspRec->timeoutPeriod = pConfigReportRec->cfgReportRec.timeoutPeriod;
pReportCfgRspRec->reportableChange = pConfigReportRec->cfgReportRec.reportableChange;
}
}
else
{
// if not found configReportRec, check if the attribute is an un-reportable
// or an un-supported one
uint8 status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
if ( zclFindAttrRec( pInMsg->endPoint, pInMsg->clusterId,
pReadReportCfgCmd->attrList[i].attrID, &attrRec ) )
{
// if found the attr rec, it is there but un-reportable
status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE;
}
38
// Attribute is not supported - move on to the next configReportRec record
if ( sendRsp )
{
pReportCfgRspRec->status = status;
pReportCfgRspRec->direction = pReadReportCfgCmd->attrList[i].direction;
pReportCfgRspRec->attrID = pReadReportCfgCmd->attrList[i].attrID;
}
}
} // for loop
if ( sendRsp )
{
pReadReportCfgRspCmd->numAttr = pReadReportCfgCmd->numAttr;
zcl_SendReadReportCfgRspCmd( pInMsg->endPoint, &(pInMsg->srcAddr), pInMsg->clusterId,
pReadReportCfgRspCmd, !pInMsg->zclHdr.fc.direction, true,
pInMsg->zclHdr.transSeqNum );
zcl_mem_free( pReadReportCfgRspCmd );
}
return TRUE;
}
/*********************************************************************
* @fn zclSampleLight_ProcessInReportCmd
*
[...]
#endif // ZCL_REPORT
39
Don’t Forget to Uncomment Handlers
static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg )
{
switch ( pInMsg->zclHdr.commandID )
{
[...]
#ifdef ZCL_REPORT
// Attribute Reporting implementation should be added here
case ZCL_CMD_CONFIG_REPORT:
zclSampleLight_ProcessInConfigReportCmd( pInMsg );
break;
case ZCL_CMD_CONFIG_REPORT_RSP:
// zclSampleLight_ProcessInConfigReportRspCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG:
zclSampleLight_ProcessInReadReportCfgCmd( pInMsg );
break;
case ZCL_CMD_READ_REPORT_CFG_RSP:
// zclSampleLight_ProcessInReadReportCfgRspCmd( pInMsg );
break;
case ZCL_CMD_REPORT:
zclSampleLight_ProcessInReportCmd( pInMsg );
break;
#endif
[...]
40
Print out the time stamp and messages received by
the host.
You must perform ‘binding’ first, or you’ll not receive
anything. (Report is sending out with ‘AddrNotPresent‘, z-stack will find out the addresses of
the bound devices)
Test Results (I)
Cluster: GenOnOff (0x0006)
Attribute: OnOff (0x0000)
Reporting period = 3 secs
3 secs
3 secs
3 secs
3 secs
Cluster: GenOnOff (0x0006)
Attribute: OnOff (0x0000)
Reporting period = 5 secs
- Suddenly turn on or turn off the light
5 secs
5 secs
5 secs
Changing of the OnOff Attr.
was reported
Changing of the OnOff Attr.
was reported
41
Test Results (II)
10 secs
10 secs
10 secs
Report of level changing
10 secs
10 secs
10 secs
10 secs
Report of level changing
10 secs
10 secs
Report of level changing
Cluster: GenLevelControl (0x0008)
Attribute: CurrentLevel (0x0000)
Reporting period = 10 secs
Amount of Change to Report = 20
- Suddenly change the light level
∆ = 199 ∆ = 170
∆ = -10
(not reported)
∆ = -160
42
[1] Z-Stack ZigBee Cluster Library Application Programming Interface,
Texas Instruments
References

Más contenido relacionado

La actualidad más candente

如何設計電腦 -- 還有讓電腦變快的那些方法
如何設計電腦  -- 還有讓電腦變快的那些方法如何設計電腦  -- 還有讓電腦變快的那些方法
如何設計電腦 -- 還有讓電腦變快的那些方法鍾誠 陳鍾誠
 
用十分鐘搞懂《離散數學》
用十分鐘搞懂《離散數學》用十分鐘搞懂《離散數學》
用十分鐘搞懂《離散數學》鍾誠 陳鍾誠
 
射頻電子 - [第三章] 史密斯圖與阻抗匹配
射頻電子 - [第三章] 史密斯圖與阻抗匹配射頻電子 - [第三章] 史密斯圖與阻抗匹配
射頻電子 - [第三章] 史密斯圖與阻抗匹配Simen Li
 
區塊鏈 (比特幣背後的關鍵技術) -- 十分鐘系列
區塊鏈  (比特幣背後的關鍵技術)   -- 十分鐘系列區塊鏈  (比特幣背後的關鍵技術)   -- 十分鐘系列
區塊鏈 (比特幣背後的關鍵技術) -- 十分鐘系列鍾誠 陳鍾誠
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性Hibiki Yamashiro
 
計算機結構 (習題:Nand2tetris硬體部分)
計算機結構  (習題:Nand2tetris硬體部分)計算機結構  (習題:Nand2tetris硬體部分)
計算機結構 (習題:Nand2tetris硬體部分)鍾誠 陳鍾誠
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺MITSUNARI Shigeo
 
用十分鐘理解 《神經網路發展史》
用十分鐘理解 《神經網路發展史》用十分鐘理解 《神經網路發展史》
用十分鐘理解 《神經網路發展史》鍾誠 陳鍾誠
 
用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論
用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論
用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論鍾誠 陳鍾誠
 
用十分鐘搞懂 《資管、資工、電子、電機、機械》 這些科系到底在學些甚麼?
用十分鐘搞懂  《資管、資工、電子、電機、機械》  這些科系到底在學些甚麼?用十分鐘搞懂  《資管、資工、電子、電機、機械》  這些科系到底在學些甚麼?
用十分鐘搞懂 《資管、資工、電子、電機、機械》 這些科系到底在學些甚麼?鍾誠 陳鍾誠
 
人工智慧與神經網路 (還有深度學習的進展)
人工智慧與神經網路  (還有深度學習的進展)人工智慧與神經網路  (還有深度學習的進展)
人工智慧與神經網路 (還有深度學習的進展)鍾誠 陳鍾誠
 
用十分鐘開始理解深度學習技術 (從 dnn.js 專案出發)
用十分鐘開始理解深度學習技術  (從 dnn.js 專案出發)用十分鐘開始理解深度學習技術  (從 dnn.js 專案出發)
用十分鐘開始理解深度學習技術 (從 dnn.js 專案出發)鍾誠 陳鍾誠
 
深入淺出C語言
深入淺出C語言深入淺出C語言
深入淺出C語言Simen Li
 
ROS2勉強会 4章前半
ROS2勉強会 4章前半ROS2勉強会 4章前半
ROS2勉強会 4章前半tomohiro kuwano
 
最佳化問題的公理化方法
最佳化問題的公理化方法最佳化問題的公理化方法
最佳化問題的公理化方法鍾誠 陳鍾誠
 
怎樣才算是一個合格的資工系畢業生
怎樣才算是一個合格的資工系畢業生怎樣才算是一個合格的資工系畢業生
怎樣才算是一個合格的資工系畢業生鍾誠 陳鍾誠
 

La actualidad más candente (20)

如何設計電腦 -- 還有讓電腦變快的那些方法
如何設計電腦  -- 還有讓電腦變快的那些方法如何設計電腦  -- 還有讓電腦變快的那些方法
如何設計電腦 -- 還有讓電腦變快的那些方法
 
用十分鐘搞懂《離散數學》
用十分鐘搞懂《離散數學》用十分鐘搞懂《離散數學》
用十分鐘搞懂《離散數學》
 
射頻電子 - [第三章] 史密斯圖與阻抗匹配
射頻電子 - [第三章] 史密斯圖與阻抗匹配射頻電子 - [第三章] 史密斯圖與阻抗匹配
射頻電子 - [第三章] 史密斯圖與阻抗匹配
 
區塊鏈 (比特幣背後的關鍵技術) -- 十分鐘系列
區塊鏈  (比特幣背後的關鍵技術)   -- 十分鐘系列區塊鏈  (比特幣背後的關鍵技術)   -- 十分鐘系列
區塊鏈 (比特幣背後的關鍵技術) -- 十分鐘系列
 
競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性競技プログラミングにおけるコードの書き方とその利便性
競技プログラミングにおけるコードの書き方とその利便性
 
計算機結構 (習題:Nand2tetris硬體部分)
計算機結構  (習題:Nand2tetris硬體部分)計算機結構  (習題:Nand2tetris硬體部分)
計算機結構 (習題:Nand2tetris硬體部分)
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺
 
用十分鐘理解 《神經網路發展史》
用十分鐘理解 《神經網路發展史》用十分鐘理解 《神經網路發展史》
用十分鐘理解 《神經網路發展史》
 
5G O-RAN 架構介紹
5G O-RAN 架構介紹5G O-RAN 架構介紹
5G O-RAN 架構介紹
 
用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論
用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論
用十分鐘瞭解《線性代數、向量微積分》以及電磁學理論
 
用十分鐘搞懂 《資管、資工、電子、電機、機械》 這些科系到底在學些甚麼?
用十分鐘搞懂  《資管、資工、電子、電機、機械》  這些科系到底在學些甚麼?用十分鐘搞懂  《資管、資工、電子、電機、機械》  這些科系到底在學些甚麼?
用十分鐘搞懂 《資管、資工、電子、電機、機械》 這些科系到底在學些甚麼?
 
為何學數學?
為何學數學?為何學數學?
為何學數學?
 
人工智慧與神經網路 (還有深度學習的進展)
人工智慧與神經網路  (還有深度學習的進展)人工智慧與神經網路  (還有深度學習的進展)
人工智慧與神經網路 (還有深度學習的進展)
 
高橋流微積分
高橋流微積分高橋流微積分
高橋流微積分
 
用十分鐘開始理解深度學習技術 (從 dnn.js 專案出發)
用十分鐘開始理解深度學習技術  (從 dnn.js 專案出發)用十分鐘開始理解深度學習技術  (從 dnn.js 專案出發)
用十分鐘開始理解深度學習技術 (從 dnn.js 專案出發)
 
深入淺出C語言
深入淺出C語言深入淺出C語言
深入淺出C語言
 
Binary indexed tree
Binary indexed treeBinary indexed tree
Binary indexed tree
 
ROS2勉強会 4章前半
ROS2勉強会 4章前半ROS2勉強会 4章前半
ROS2勉強会 4章前半
 
最佳化問題的公理化方法
最佳化問題的公理化方法最佳化問題的公理化方法
最佳化問題的公理化方法
 
怎樣才算是一個合格的資工系畢業生
怎樣才算是一個合格的資工系畢業生怎樣才算是一個合格的資工系畢業生
怎樣才算是一個合格的資工系畢業生
 

Destacado

電路學 - [第一章] 電路元件與基本定律
電路學 - [第一章] 電路元件與基本定律電路學 - [第一章] 電路元件與基本定律
電路學 - [第一章] 電路元件與基本定律Simen Li
 
電路學 - [第二章] 電路分析方法
電路學 - [第二章] 電路分析方法電路學 - [第二章] 電路分析方法
電路學 - [第二章] 電路分析方法Simen Li
 
ESP8266 and IOT
ESP8266 and IOTESP8266 and IOT
ESP8266 and IOTdega1999
 
NodeMCU ESP8266 workshop 1
NodeMCU ESP8266 workshop 1NodeMCU ESP8266 workshop 1
NodeMCU ESP8266 workshop 1Andy Gelme
 
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬Simen Li
 
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬Simen Li
 
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬Simen Li
 
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計Simen Li
 
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬Simen Li
 
Agilent ADS 模擬手冊 [實習2] 放大器設計
Agilent ADS 模擬手冊 [實習2]  放大器設計Agilent ADS 模擬手冊 [實習2]  放大器設計
Agilent ADS 模擬手冊 [實習2] 放大器設計Simen Li
 
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬Simen Li
 

Destacado (11)

電路學 - [第一章] 電路元件與基本定律
電路學 - [第一章] 電路元件與基本定律電路學 - [第一章] 電路元件與基本定律
電路學 - [第一章] 電路元件與基本定律
 
電路學 - [第二章] 電路分析方法
電路學 - [第二章] 電路分析方法電路學 - [第二章] 電路分析方法
電路學 - [第二章] 電路分析方法
 
ESP8266 and IOT
ESP8266 and IOTESP8266 and IOT
ESP8266 and IOT
 
NodeMCU ESP8266 workshop 1
NodeMCU ESP8266 workshop 1NodeMCU ESP8266 workshop 1
NodeMCU ESP8266 workshop 1
 
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
射頻電子實驗手冊 - [實驗8] 低雜訊放大器模擬
 
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
射頻電子實驗手冊 - [實驗7] 射頻放大器模擬
 
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
射頻電子實驗手冊 [實驗6] 阻抗匹配模擬
 
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
Agilent ADS 模擬手冊 [實習1] 基本操作與射頻放大器設計
 
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
Agilent ADS 模擬手冊 [實習3] 壓控振盪器模擬
 
Agilent ADS 模擬手冊 [實習2] 放大器設計
Agilent ADS 模擬手冊 [實習2]  放大器設計Agilent ADS 模擬手冊 [實習2]  放大器設計
Agilent ADS 模擬手冊 [實習2] 放大器設計
 
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
射頻電子實驗手冊 [實驗1 ~ 5] ADS入門, 傳輸線模擬, 直流模擬, 暫態模擬, 交流模擬
 

Similar a Implementation of the ZigBee ZCL Reporting Configuration Features

[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack FirmwareSimen Li
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)Simen Li
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationWei-Ren Chen
 
Lee 2020 what the clock !
Lee 2020  what the clock !Lee 2020  what the clock !
Lee 2020 what the clock !Neil Armstrong
 
Kapacitor - Real Time Data Processing Engine
Kapacitor - Real Time Data Processing EngineKapacitor - Real Time Data Processing Engine
Kapacitor - Real Time Data Processing EnginePrashant Vats
 
(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_net(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_netNico Ludwig
 
Caffe studying 2017
Caffe studying 2017Caffe studying 2017
Caffe studying 2017Te-Yen Liu
 
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit SydneyAutoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit SydneyAmazon Web Services
 
Query Your Streaming Data on Kafka using SQL: Why, How, and What
Query Your Streaming Data on Kafka using SQL: Why, How, and WhatQuery Your Streaming Data on Kafka using SQL: Why, How, and What
Query Your Streaming Data on Kafka using SQL: Why, How, and WhatHostedbyConfluent
 
OpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developersOpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developersConnor McDonald
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVMSylvain Wallez
 
Zabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet MensZabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet MensNETWAYS
 
Samsung WebCL Prototype API
Samsung WebCL Prototype APISamsung WebCL Prototype API
Samsung WebCL Prototype APIRyo Jin
 
Lessons Learnt from Running Thousands of On-demand Spark Applications
Lessons Learnt from Running Thousands of On-demand Spark ApplicationsLessons Learnt from Running Thousands of On-demand Spark Applications
Lessons Learnt from Running Thousands of On-demand Spark ApplicationsItai Yaffe
 
ez-clang C++ REPL for bare-metal embedded devices
ez-clang C++ REPL for bare-metal embedded devicesez-clang C++ REPL for bare-metal embedded devices
ez-clang C++ REPL for bare-metal embedded devicesStefan Gränitz
 

Similar a Implementation of the ZigBee ZCL Reporting Configuration Features (20)

[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
[ZigBee 嵌入式系統] ZigBee 應用實作 - 使用 TI Z-Stack Firmware
 
Vlsi lab2
Vlsi lab2Vlsi lab2
Vlsi lab2
 
Qe Reference
Qe ReferenceQe Reference
Qe Reference
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (3)
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
Part II: LLVM Intermediate Representation
Part II: LLVM Intermediate RepresentationPart II: LLVM Intermediate Representation
Part II: LLVM Intermediate Representation
 
Sycl 1.2 Reference Card
Sycl 1.2 Reference CardSycl 1.2 Reference Card
Sycl 1.2 Reference Card
 
Lee 2020 what the clock !
Lee 2020  what the clock !Lee 2020  what the clock !
Lee 2020 what the clock !
 
OpenCL 2.2 Reference Guide
OpenCL 2.2 Reference GuideOpenCL 2.2 Reference Guide
OpenCL 2.2 Reference Guide
 
Kapacitor - Real Time Data Processing Engine
Kapacitor - Real Time Data Processing EngineKapacitor - Real Time Data Processing Engine
Kapacitor - Real Time Data Processing Engine
 
(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_net(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_net
 
Caffe studying 2017
Caffe studying 2017Caffe studying 2017
Caffe studying 2017
 
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit SydneyAutoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
Autoscaling Your Kubernetes Workloads (Sponsored by Datadog) - AWS Summit Sydney
 
Query Your Streaming Data on Kafka using SQL: Why, How, and What
Query Your Streaming Data on Kafka using SQL: Why, How, and WhatQuery Your Streaming Data on Kafka using SQL: Why, How, and What
Query Your Streaming Data on Kafka using SQL: Why, How, and What
 
OpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developersOpenWorld Sep14 12c for_developers
OpenWorld Sep14 12c for_developers
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
Zabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet MensZabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet Mens
 
Samsung WebCL Prototype API
Samsung WebCL Prototype APISamsung WebCL Prototype API
Samsung WebCL Prototype API
 
Lessons Learnt from Running Thousands of On-demand Spark Applications
Lessons Learnt from Running Thousands of On-demand Spark ApplicationsLessons Learnt from Running Thousands of On-demand Spark Applications
Lessons Learnt from Running Thousands of On-demand Spark Applications
 
ez-clang C++ REPL for bare-metal embedded devices
ez-clang C++ REPL for bare-metal embedded devicesez-clang C++ REPL for bare-metal embedded devices
ez-clang C++ REPL for bare-metal embedded devices
 

Más de Simen Li

2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)Simen Li
 
全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版Simen Li
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterSimen Li
 
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013Simen Li
 
Phase-locked Loops - Theory and Design
Phase-locked Loops - Theory and DesignPhase-locked Loops - Theory and Design
Phase-locked Loops - Theory and DesignSimen Li
 
專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧Simen Li
 
ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作Simen Li
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)Simen Li
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)Simen Li
 
[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階Simen Li
 
Multiband Transceivers - [Chapter 7] Spec. Table
Multiband Transceivers - [Chapter 7]  Spec. TableMultiband Transceivers - [Chapter 7]  Spec. Table
Multiband Transceivers - [Chapter 7] Spec. TableSimen Li
 
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...Simen Li
 
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band TransceiversMultiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band TransceiversSimen Li
 
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless RadiosMultiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless RadiosSimen Li
 
Multiband Transceivers - [Chapter 5] Software-Defined Radios
Multiband Transceivers - [Chapter 5]  Software-Defined RadiosMultiband Transceivers - [Chapter 5]  Software-Defined Radios
Multiband Transceivers - [Chapter 5] Software-Defined RadiosSimen Li
 
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3]  Basic Concept of Comm. SystemsMultiband Transceivers - [Chapter 3]  Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. SystemsSimen Li
 
Multiband Transceivers - [Chapter 2] Noises and Linearities
Multiband Transceivers - [Chapter 2]  Noises and LinearitiesMultiband Transceivers - [Chapter 2]  Noises and Linearities
Multiband Transceivers - [Chapter 2] Noises and LinearitiesSimen Li
 
Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1] Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1] Simen Li
 
RF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked LoopsRF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked LoopsSimen Li
 

Más de Simen Li (19)

2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
2018 VLSI/CAD Symposium Tutorial (Aug. 7, 20:00-21:00 Room 3F-VII)
 
全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版全端物聯網探索之旅 - 重點整理版
全端物聯網探索之旅 - 重點整理版
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitter
 
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
Voltage Controlled Oscillator Design - Short Course at NKFUST, 2013
 
Phase-locked Loops - Theory and Design
Phase-locked Loops - Theory and DesignPhase-locked Loops - Theory and Design
Phase-locked Loops - Theory and Design
 
專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧專題製作發想與報告撰寫技巧
專題製作發想與報告撰寫技巧
 
ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作ADF4113 Frequency Synthesizer 驅動程式實作
ADF4113 Frequency Synthesizer 驅動程式實作
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (2)
 
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
[嵌入式系統] MCS-51 實驗 - 使用 IAR (1)
 
[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階[嵌入式系統] 嵌入式系統進階
[嵌入式系統] 嵌入式系統進階
 
Multiband Transceivers - [Chapter 7] Spec. Table
Multiband Transceivers - [Chapter 7]  Spec. TableMultiband Transceivers - [Chapter 7]  Spec. Table
Multiband Transceivers - [Chapter 7] Spec. Table
 
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...Multiband Transceivers - [Chapter 7]  Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
Multiband Transceivers - [Chapter 7] Multi-mode/Multi-band GSM/GPRS/TDMA/AMP...
 
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band TransceiversMultiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
Multiband Transceivers - [Chapter 6] Multi-mode and Multi-band Transceivers
 
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless RadiosMultiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
Multiband Transceivers - [Chapter 4] Design Parameters of Wireless Radios
 
Multiband Transceivers - [Chapter 5] Software-Defined Radios
Multiband Transceivers - [Chapter 5]  Software-Defined RadiosMultiband Transceivers - [Chapter 5]  Software-Defined Radios
Multiband Transceivers - [Chapter 5] Software-Defined Radios
 
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3]  Basic Concept of Comm. SystemsMultiband Transceivers - [Chapter 3]  Basic Concept of Comm. Systems
Multiband Transceivers - [Chapter 3] Basic Concept of Comm. Systems
 
Multiband Transceivers - [Chapter 2] Noises and Linearities
Multiband Transceivers - [Chapter 2]  Noises and LinearitiesMultiband Transceivers - [Chapter 2]  Noises and Linearities
Multiband Transceivers - [Chapter 2] Noises and Linearities
 
Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1] Multiband Transceivers - [Chapter 1]
Multiband Transceivers - [Chapter 1]
 
RF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked LoopsRF Module Design - [Chapter 8] Phase-Locked Loops
RF Module Design - [Chapter 8] Phase-Locked Loops
 

Último

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...Nitya salvi
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durbanmasabamasaba
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
SHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions PresentationSHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions PresentationShrmpro
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...masabamasaba
 

Último (20)

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban%in Durban+277-882-255-28 abortion pills for sale in Durban
%in Durban+277-882-255-28 abortion pills for sale in Durban
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
SHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions PresentationSHRMPro HRMS Software Solutions Presentation
SHRMPro HRMS Software Solutions Presentation
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 

Implementation of the ZigBee ZCL Reporting Configuration Features

  • 1. © 2015 sivann inc. All Rights Reserved© 2015 sivann inc. All Rights Reserved Pursue of Simplicity support@sivann.com.tw ZigBee ZCL Reporting Configuration Example: TI Z-Stack Home 1.2.1/1.2.2 SampleLight
  • 2. 2 “The ZCL acts as a repository for cluster functionality that is developed by ZigBee. A developer constructing a new profile should incorporate relevant ZCL cluster functionality into the new profile.” [1] ZCL foundation provides “general commands” for manipulating attributes and other general tasks that are not specific to an individual cluster. Introduction
  • 3. 3 ZCL foundation general commands are provided with TI’s Z-Stack ZCL APIs. ◦ Commands Read/Write (0x00 – 0x05) are handled in ZCL Foundation Layer, and TI leaves the features of attribute reporting (0x06 – 0x0A) for the developers to implement on application-level by their needs. ZCL Foundation – General Commands Cmd Id Description 0x00 Read attributes 0x01 Read attributes response 0x02 Write attributes 0x03 Write attributes undivided 0x04 Write attributes response 0x05 Write attributes no response 0x06 Configure reporting 0x07 Configure reporting response 0x08 Read reporting configuration 0x09 Read reporting configuration response 0x0A Report attributes
  • 4. 4 Implement these features within the incoming message handlers zclSampleLight_ProcessInConfigReportCmd(), .etc. ZCL_REPORT Feature in zcl_samplelight.c static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg ) { switch ( pInMsg->zclHdr.commandID ) { ... #ifdef ZCL_REPORT // Attribute Reporting implementation should be added here case ZCL_CMD_CONFIG_REPORT: // zclSampleLight_ProcessInConfigReportCmd( pInMsg ); break; case ZCL_CMD_CONFIG_REPORT_RSP: // zclSampleLight_ProcessInConfigReportRspCmd( pInMsg ); break; case ZCL_CMD_READ_REPORT_CFG: // zclSampleLight_ProcessInReadReportCfgCmd( pInMsg ); break; case ZCL_CMD_READ_REPORT_CFG_RSP: // zclSampleLight_ProcessInReadReportCfgRspCmd( pInMsg ); break; case ZCL_CMD_REPORT: // zclSampleLight_ProcessInReportCmd( pInMsg ); break; ... typedef struct { osal_event_hdr_t hdr; zclFrameHdr_t zclHdr; uint16 clusterId; afAddrType_t srcAddr; uint8 endPoint; void *attrCmd; } zclIncomingMsg_t;
  • 5. 5 Our Goal Make SampleLight application support the ZCL features of ◦ ZCL_CMD_CONFIG_REPORT ◦ ZCL_CMD_READ_REPORT_CFG ◦ ZCL_CMD_REPORT SampleLight App attr_1 attr_2 attr_N ZCL_CMD_CONFIG_REPORT ZCL_CMD_CONFIG_REPORT_RSP ZCL_CMD_READ_REPORT_CFG ZCL_CMD_READ_REPORT_CFG_RSP A Remote ZigBee Device Device A: “I want you to report your attr_1 and attr_2 in every X seconds, or upon changing” B C SampleLight: “OK, attr_1 and attr_2 are configured to report as your request.” Device B: “Please tell me about your reporting configurations of attr_1 and attr_3.” SampleLight: “My attr_1 is reportable and attr_3 is unreportable.” Device C: “Please report your attr_1.”
  • 6. 6 Firmware Stack version ◦ Z-Stack Home 1.2.1 / 1.2.2 ( http://www.ti.com/tool/z-stack ) Code to modify ◦ C:Texas InstrumentsZ-Stack Home 1.2.1 Componentsstackzcl zcl.h zcl.c ProjectszstackHomeAutomationSampleLightSource zcl_samplelight_data.c zcl_samplelight.h zcl_samplelight.c https://github.com/sivann/samplelight_cfgreport
  • 7. 7 zcl.h ◦ Define two data types: zclConfigReportRec_t : “Reporting config. record” for an endpoint zclConfigReportRecsList : “Reporting config. records list” of all endpoints zcl.c ◦ A function to register the “Reporting config. table”. zcl_registerConfigReportRecList() zcl_samplelight_data.c ◦ Add Config. Report Records to zcl_samplelight_data.c zclConfigReportRec_t zclSampleLight_ConfigReportRecs[] zcl_samplelight.h, zcl_samplelight.c ◦ Implementation of zcl attribute reporting features Steps
  • 8. 8 zcl.h: New Data Types /********************************************************************* * TYPEDEFS */ // Configure Reporting Command format ... } zclCfgReportRec_t; typedef struct { uint16 clusterId; uint16 timeup; uint8 *lastReportValue; zclCfgReportRec_t cfgReportRec; } zclConfigReportRec_t; /********************************************************************* * CONSTANTS */ ... #define ZCL_FRAME_SERVER_CLIENT_DIR 0x01 /*** Report SEND/RECEIVE Directions ***/ #define ZCL_REPORT_SEND 0x00 #define ZCL_REPORT_RECEIVE 0x01 #ifdef ZCL_REPORT // Config Report record list item typedef struct zclConfigReportRecsList { struct zclConfigReportRecsList *next; uint8 endpoint; uint8 numConfigReportRec; zclConfigReportRec_t *configReportRecs; } zclConfigReportRecsList; #endif // ZCL_REPORT zclConfigReportRec_t zclConfigReportRecsList
  • 9. 9 zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRecsList *next endpoint numConfigReportRec *configReportRecs zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRecsList *next endpoint numConfigReportRec *configReportRecs Rec_1 Rec_2 Rec_3 Rec_1 Rec_2 Rec_3 zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRecsList *next endpoint numConfigReportRec *configReportRecs Rec_1 Rec_2 Rec_3 List_for_Endpoint_1 List_for_Endpoint_2 List_for_Endpoint_3
  • 10. 10 zcl.h: Declare Local Variables and Functions /********************************************************************* * FUNCTIONS */ [...] extern ZStatus_t zcl_registerAttrList( uint8 endpoint, uint8 numAttr, CONST zclAttrRec_t attrList[] ); #ifdef ZCL_REPORT /* Register Application's Config Report table */ extern ZStatus_t zcl_registerConfigReportRecList( uint8 endpoint, uint8 numConfigReportRec, zclConfigReportRec_t newConfigReportRecList[] ); #endif // ZCL_REPORT #ifdef ZCL_REPORT [...] extern uint8 zclAnalogDataType( uint8 dataType ); [...] /* Function to find the Config Report Record of an Atribute that matches the parameters */ extern uint8 zclFindConfigReportRec( uint8 endpoint, uint16 clusterID, uint16 attrId, zclConfigReportRec_t **pConfigReportRec ); extern zclConfigReportRecsList *zclFindConfigReportRecsList( uint8 endpoint ); #endif // ZCL_REPORT
  • 11. 11 Prototype of the Config. Table Register Function zcl.c: Config. Table Register Function (I) zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRecsList *next endpoint numConfigReportRec *configReportRecs Rec_1 Rec_2 Rec_3 ZStatus_t zcl_registerConfigReportRecList( uint8 endpoint, uint8 numConfigReportRec, zclConfigReportRec_t newConfigReportRecList[] )
  • 12. 12 zcl.c: Config. Table Register Function (II) [...] ZStatus_t zcl_registerCmdList( uint8 endpoint, CONST uint8 cmdListSize, CONST zclCommandRec_t newCmdList[] ) { [...] } #endif // ZCL_DISCOVER #ifdef ZCL_REPORT /********************************************************************* * @fn zcl_registerConfigReportRecList * @brief Register an ConfigReportRec List with ZCL Foundation * @param endpoint - endpoint the attribute list belongs to * @param numConfigReportRec - number of attributes in list * @param newConfigReportRecList - array of Attribute records. * @return ZSuccess if OK */ ZStatus_t zcl_registerConfigReportRecList( uint8 endpoint, uint8 numConfigReportRec, zclConfigReportRec_t newConfigReportRecList[] ) { zclConfigReportRecsList *pNewItem; zclConfigReportRecsList *pLoop; // Fill in the new profile list pNewItem = zcl_mem_alloc( sizeof( zclConfigReportRecsList ) ); if ( pNewItem == NULL ) { return (ZMemError); }
  • 13. 13 pNewItem->next = (zclConfigReportRecsList *)NULL; pNewItem->endpoint = endpoint; pNewItem->numConfigReportRec = numConfigReportRec; pNewItem->configReportRecs = newConfigReportRecList; // Find spot in list if ( configReportRecsList == NULL ) { configReportRecsList = pNewItem; } else { // Look for end of list pLoop = configReportRecsList; while ( pLoop->next != NULL ) { pLoop = pLoop->next; } // Put new item at end of list pLoop->next = pNewItem; } return ( ZSuccess ); } #endif // ZCL_REPORT
  • 14. 14 Prototype of the Config. Report Recs List Searching Function Prototype of the Config. Report Rec Searching Function zcl.c: Config. Record Searching Function zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRec_t clusterId timeup *lastReportValue cfgReportRec zclConfigReportRecsList *next endpoint numConfigReportRec *configReportRecs Rec_1 Rec_2 Rec_3 zclConfigReportRecsList *zclFindConfigReportRecsList( uint8 endpoint ) uint8 zclFindConfigReportRec( uint8 endpoint, uint16 clusterID, uint16 attrId, zclConfigReportRec_t **pConfigReportRec )
  • 15. 15 Config. Report Recs List Searching Function /********************************************************************* * PRIVATE FUNCTIONS *********************************************************************/ [...] #ifdef ZCL_REPORT /********************************************************************* * @fn zclFindConfigReportRecsList * @brief Find the right ConfigReport record list for an endpoint * @param clusterID - endpoint to look for * @return pointer to record list, NULL if not found */ zclConfigReportRecsList *zclFindConfigReportRecsList( uint8 endpoint ) { zclConfigReportRecsList *pLoop = configReportRecsList; while ( pLoop != NULL ) { if ( pLoop->endpoint == endpoint ) { return ( pLoop ); } pLoop = pLoop->next; } return ( NULL ); }
  • 16. 16 /********************************************************************* * @fn zclFindConfigReportRec * @brief Find the configReportRec record that matches the parameters * @param endpoint - Application's endpoint * @param clusterID - cluster ID * @param attrId - attribute looking for * @param pConfigReportRec - ConfigReportRec record to be returned * @return TRUE if record found. FALSE, otherwise. */ uint8 zclFindConfigReportRec( uint8 endpoint, uint16 clusterID, uint16 attrId, zclConfigReportRec_t **pConfigReportRec ) { uint8 x; zclConfigReportRecsList *pRec = zclFindConfigReportRecsList( endpoint ); if ( pRec != NULL ) { for ( x = 0; x < pRec->numConfigReportRec; x++ ) { if ( pRec->configReportRecs[x].clusterId == clusterID && pRec->configReportRecs[x].cfgReportRec.attrID == attrId ) { *pConfigReportRec = &(pRec->configReportRecs[x]); return ( TRUE ); } } } return ( FALSE ); } #endif // ZCL_REPORT Config. Report Rec Searching Function
  • 17. 17 zcl.c is ready. Now, we’re going to name the attributes from clusters to be configured for reporting. zcl_sampleligh_data.c: Arrangement /********************************************************************* * GLOBAL VARIABLES */ const uint8 zclSampleLight_HWRevision = SAMPLELIGHT_HWVERSION; [...] uint8 zclSampleLight_OnOffLastReportValue = LIGHT_OFF; #ifdef ZCL_LEVEL_CTRL uint8 zclSampleLight_LevelCurrentLevel = ATTR_LEVEL_MIN_LEVEL; uint8 zclSampleLight_LevelCurrentLevelChange = 50; uint8 zclSampleLight_LevelLastReportValue = ATTR_LEVEL_MIN_LEVEL; [...] #endif #ifdef ZCL_REPORT zclConfigReportRec_t zclSampleLight_ConfigReportRecs[] = { // See Next Slide { ...
  • 18. 18 typedef struct { uint16 clusterId; uint16 timeup; uint8 *lastReportValue; zclCfgReportRec_t cfgReportRec; } zclConfigReportRec_t; typedef struct { uint8 direction; uint16 attrID; uint8 dataType; uint16 minReportInt; uint16 maxReportInt; uint16 timeoutPeriod; uint8 *reportableChange; } zclCfgReportRec_t; zclConfigReportRec_t zclSampleLight_ConfigReportRecs[] = { // *** On/Off Cluster Attr ConfigReportRec *** { ZCL_CLUSTER_ID_GEN_ON_OFF, 0xFFFF, (void *)&zclSampleLight_OnOffLastReportValue, { // CfgReportRec ZCL_REPORT_SEND, ATTRID_ON_OFF, ZCL_DATATYPE_BOOLEAN, 0, 0xFFFF, 0, NULL // need not set for } // DISCRETE datatype } #ifdef ZCL_LEVEL_CTRL ,{ ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL, 0xFFFF, (void *)&zclSampleLight_LevelLastReportValue, { ZCL_REPORT_SEND, ATTRID_LEVEL_CURRENT_LEVEL, ZCL_DATATYPE_UINT8, 0, 0xFFFF, 0, (void *)&zclSampleLight_LevelCurrentLevelChange } } #endif }; uint8 CONST zclSampleLight_NumConfigReportRecs = ( sizeof(zclSampleLight_ConfigReportRecs) / sizeof(zclSampleLight_ConfigReportRecs[0]) ); #endif timeup clusterId *lastReportValue direction attrID dataType minReportInt maxReportInt timeoutPeroid *reportableChange
  • 19. 19 zcl_samplelight.h: Declarations /********************************************************************* * VARIABLES */ [...] extern CONST uint8 zclCmdsArraySize; extern CONST uint8 zclSampleLight_NumConfigReportRecs; extern zclConfigReportRec_t zclSampleLight_ConfigReportRecs[]; [...] // OnOff attributes extern uint8 zclSampleLight_OnOff; extern uint8 zclSampleLight_OnOffLastReportValue; // Level Control Attributes #ifdef ZCL_LEVEL_CTRL [...] extern uint8 zclSampleLight_LevelCurrentLevelChange; extern uint8 zclSampleLight_LevelLastReportValue; #endif /********************************************************************* * CONSTANTS */ #define SAMPLELIGHT_ENDPOINT 8 [...] // Application Events #define SAMPLELIGHT_IDENTIFY_TIMEOUT_EVT 0x0001 [...] #define SAMPLELIGHT_START_EZMODE_EVT 0x0040 #define SAMPLELIGHT_CHECK_REPORT_EVT 0x0080
  • 20. 20 zcl_samplelight.c : Declarations /********************************************************************* * LOCAL VARIABLES */ afAddrType_t zclSampleLight_DstAddr; uint16 gTimeCounter = 0; /********************************************************************* * LOCAL FUNCTIONS */ #ifdef ZCL_LEVEL_CTRL [...] static void sendZclAttrChangeReport(uint8 srcEp, uint16 clusterId, uint16 attrID, uint8 *lastReportValue, uint8 *currentValue); #endif [...] #ifdef ZCL_REPORT [...] static void zclSampleLight_CheckReportConfig( void ); static uint8 sendZclAttrReport(uint8 srcEp, uint16 clusterID, zclReportCmd_t *pReportCmd, uint8 dataLen); static void zclSampleLight_CheckandSendClusterAttrReport( uint16 clusterID, zclConfigReportRecsList *pConfigReportRecsList ); #endif
  • 21. 21 zcl_samplelight.c : Register the Report Recs void zclSampleLight_Init( byte task_id ) { zclSampleLight_TaskID = task_id; [...] // Register the application's attribute list zcl_registerAttrList( SAMPLELIGHT_ENDPOINT, zclSampleLight_NumAttributes, zclSampleLight_Attrs ); #ifdef ZCL_REPORT // Register the application's config report record list zcl_registerConfigReportRecList( SAMPLELIGHT_ENDPOINT, zclSampleLight_NumConfigReportRecs, zclSampleLight_ConfigReportRecs ); #endif // Register the Application to receive the unprocessed Foundation command/response messages zcl_registerForMsg( zclSampleLight_TaskID ); [...] }
  • 22. 22 Arrange an event handler (for event: SAMPLELIGHT_CHECK_REPORT_EVT) to check if there is a reportable timeout attribute. zcl_samplelight.c: Event Handler uint16 zclSampleLight_event_loop( uint8 task_id, uint16 events ) { [...] #ifdef ZCL_LEVEL_CTRL if ( events & SAMPLELIGHT_LEVEL_CTRL_EVT ) { zclSampleLight_AdjustLightLevel(); return ( events ^ SAMPLELIGHT_LEVEL_CTRL_EVT ); } #endif #ifdef ZCL_REPORT if ( events & SAMPLELIGHT_CHECK_REPORT_EVT ) { zclSampleLight_CheckReportConfig( &zclSampleLightSeqNum ); return ( events ^ SAMPLELIGHT_CHECK_REPORT_EVT ); } #endif // Discard unknown events return 0; }
  • 23. 23 Check If an Reportable Attribute is Timeout #ifdef ZCL_REPORT /********************************************************************* * @fn zclSampleLight_CheckReportConfig * @brief Check if there is a reportable attribute is timeout to report * @param none * @return none */ static void zclSampleLight_CheckReportConfig( void ) { uint8 x, y; uint8 stopChecking = TRUE; zclConfigReportRecsList *pConfigReportRecsList = zclFindConfigReportRecsList(SAMPLELIGHT_ENDPOINT); if ( pConfigReportRecsList != NULL ) { for ( x = 0; x < pConfigReportRecsList->numConfigReportRec; x++ ) { uint8 cIdDuplicate = 0; for ( y = 0; y < x; y++ ) { if ( pConfigReportRecsList->configReportRecs[x].clusterId == pConfigReportRecsList->configReportRecs[y].clusterId ) { cIdDuplicate = 1; } } if (!cIdDuplicate) { zclSampleLight_CheckandSendClusterAttrReport( pConfigReportRecsList-> configReportRecs[x].clusterId, pConfigReportRecsList ); }
  • 24. 24 if (pConfigReportRecsList->configReportRecs[x].cfgReportRec.maxReportInt != 0xFFFF) { stopChecking = FALSE; // at least one attr in this endpoint is setting to report, } // don't stop checking } } gTimeCounter++; // time ticks every second for attr report if (!stopChecking) { osal_start_timerEx( zclSampleLight_TaskID, SAMPLELIGHT_CHECK_REPORT_EVT, 1000 ); } } static void zclSampleLight_CheckandSendClusterAttrReport( uint16 clusterID, zclConfigReportRecsList *pConfigReportRecsList ) { uint8 numAttr = 0; uint8 x; uint16 len; zclReportCmd_t *pReportCmd; zclConfigReportRec_t *pConfigReportRec = NULL; zclAttrRec_t attrRec; for ( x = 0; x < pConfigReportRecsList->numConfigReportRec; x++ ) { pConfigReportRec = &(pConfigReportRecsList->configReportRecs[x]); // find out how many attributes are timeout in this cluster if ( pConfigReportRec->clusterId == clusterID && pConfigReportRec-> cfgReportRec.maxReportInt != 0xFFFF) { if (pConfigReportRec->timeup == 0xFFFF || pConfigReportRec->timeup == gTimeCounter) { numAttr++; } } }
  • 25. 25 if (numAttr != 0) { // We need to send a report - allocate space for it len = sizeof( zclReportCmd_t ) + (numAttr * sizeof( zclReport_t )); pReportCmd = (zclReportCmd_t *)zcl_mem_alloc( len ); pReportCmd->numAttr = numAttr; } numAttr = 0; for ( x = 0; x < pConfigReportRecsList->numConfigReportRec; x++ ) { zclReport_t *reportRec; pConfigReportRec = &(pConfigReportRecsList->configReportRecs[x]); if ( pConfigReportRec->clusterId == clusterID && pConfigReportRec-> cfgReportRec.maxReportInt != 0xFFFF) // need report { // timeout to report if (pConfigReportRec->timeup == 0xFFFF || pConfigReportRec->timeup == gTimeCounter) { // fill the record in *pReportCmd reportRec = &(pReportCmd->attrList[numAttr]); zcl_memset( reportRec, 0, sizeof( zclReport_t ) ); numAttr++; zclFindAttrRec( SAMPLELIGHT_ENDPOINT, pConfigReportRec->clusterId, pConfigReportRec->cfgReportRec.attrID, &attrRec); reportRec->attrID = attrRec.attr.attrId; reportRec->dataType = attrRec.attr.dataType; reportRec->attrData = attrRec.attr.dataPtr;
  • 26. 26 // calculate next timeout value if (pConfigReportRec->cfgReportRec.minReportInt == 0) { pConfigReportRec->timeup = gTimeCounter + pConfigReportRec->cfgReportRec.maxReportInt; } else { pConfigReportRec->timeup = gTimeCounter + pConfigReportRec->cfgReportRec.minReportInt; } } } } if (numAttr != 0) { // send report sendZclAttrReport( SAMPLELIGHT_ENDPOINT, clusterID, pReportCmd, len); } } #endif static uint8 sendZclAttrReport(uint8 srcEp, uint16 clusterID, zclReportCmd_t *pReportCmd, uint8 dataLen) { zclIncomingMsg_t *pMsg; // this is for inner-app osal msg, not OTA msg, // thus we will see that some fields are not important // pMsg will be released by zclSampleLight_event_loop() pMsg = (zclIncomingMsg_t *)osal_msg_allocate( sizeof(zclIncomingMsg_t) + (dataLen)); if ( pMsg == NULL ) { return FALSE; // EMBEDDED RETURN }
  • 27. 27 if (pMsg) // inner-app osal message { pMsg->hdr.event = ZCL_INCOMING_MSG; pMsg->hdr.status = 0; //pMsg->zclHdr.fc = NULL; // not important pMsg->zclHdr.manuCode = 0; // not important pMsg->zclHdr.transSeqNum = 0; // not important pMsg->zclHdr.commandID = ZCL_CMD_REPORT; // send this report message to ZCL_CMD_REPORT // event handler pMsg->clusterId = clusterID; pMsg->srcAddr.addrMode = (afAddrMode_t)Addr16Bit; pMsg->srcAddr.addr.shortAddr = 0; // not important pMsg->srcAddr.panId = 0; // inner-PAN, not important pMsg->srcAddr.endPoint = srcEp; // src ep, SAMPLELIGHT_ENDPOINT send to himself pMsg->endPoint = srcEp; // dest ep, send to SAMPLELIGHT_ENDPOINT himself pMsg->attrCmd = (zclReportCmd_t *)pReportCmd; } osal_msg_send( zclSampleLight_TaskID, (uint8 *)pMsg ); return ( TRUE ); } case ZCL_CMD_REPORT: zclSampleLight_ProcessInReportCmd( pInMsg ); break;
  • 28. 28 Call sendZclAttrChangeReport() to send out the current attribute. When the Reportable Attribute is Changed static void zclSampleLight_HandleKeys( byte shift, byte keys ) { if ( keys & HAL_KEY_SW_1 ) { giLightScreenMode = LIGHT_MAINMODE; if (zclSampleLight_OnOffLastReportValue != zclSampleLight_OnOff) { sendZclAttrChangeReport(SAMPLELIGHT_ENDPOINT, ZCL_CLUSTER_ID_GEN_ON_OFF, ATTRID_ON_OFF, &zclSampleLight_OnOffLastReportValue, &zclSampleLight_OnOff); } } [...] static void zclSampleLight_OnOffCB( uint8 cmd ) { [...] else if ( cmd == COMMAND_TOGGLE ) { [...] } if (zclSampleLight_OnOffLastReportValue != zclSampleLight_OnOff) { sendZclAttrChangeReport(SAMPLELIGHT_ENDPOINT, ZCL_CLUSTER_ID_GEN_ON_OFF, ATTRID_ON_OFF, &zclSampleLight_OnOffLastReportValue, &zclSampleLight_OnOff); } [...]
  • 29. 29 static void zclSampleLight_AdjustLightLevel( void ) { uint8 needReport = FALSE; [...] if ( zclSampleLight_LevelRemainingTime == 0) { zclSampleLight_LevelCurrentLevel = zclSampleLight_NewLevel; // check if we need to report by change if (zclSampleLight_LevelLastReportValue > zclSampleLight_LevelCurrentLevel) { if (zclSampleLight_LevelLastReportValue - zclSampleLight_LevelCurrentLevel >= zclSampleLight_LevelCurrentLevelChange) { needReport = TRUE; } } else { if (zclSampleLight_LevelCurrentLevel - zclSampleLight_LevelLastReportValue >= zclSampleLight_LevelCurrentLevelChange) { needReport = TRUE; } } if (needReport) { sendZclAttrChangeReport(SAMPLELIGHT_ENDPOINT, ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL, ATTRID_LEVEL_CURRENT_LEVEL, &zclSampleLight_LevelLastReportValue, &zclSampleLight_LevelCurrentLevel); } }
  • 30. 30 /********************************************************************* * @fn sendZclAttrChangeReport * @brief Send the attr report when the attr is changed * @param srcEp - source endpoint [...] static void sendZclAttrChangeReport(uint8 srcEp, uint16 clusterId, uint16 attrID, uint8 *lastReportValue, uint8 *currentValue) { if (*lastReportValue != *currentValue) { // if the current attr value is not equal to the last reported value, report the change zclReportCmd_t *pReportCmd; zclReport_t *reportRec; zclAttrRec_t attrRec; uint8 len; len = sizeof( zclReportCmd_t ) + (1 * sizeof( zclReport_t )); pReportCmd = (zclReportCmd_t *)zcl_mem_alloc( len ); pReportCmd->numAttr = 1; reportRec = &(pReportCmd->attrList[0]); zcl_memset( reportRec, 0, sizeof( zclReport_t ) ); zclFindAttrRec( SAMPLELIGHT_ENDPOINT, clusterId, attrID, &attrRec); reportRec->attrID = attrRec.attr.attrId; reportRec->dataType = attrRec.attr.dataType; reportRec->attrData = attrRec.attr.dataPtr; sendZclAttrReport(SAMPLELIGHT_ENDPOINT, clusterId, pReportCmd, len); *lastReportValue = *currentValue; } }
  • 31. 31 When We Got a Report Cmd static uint8 zclSampleLight_ProcessInReportCmd( zclIncomingMsg_t *pInMsg ) { zclReportCmd_t *pReportCmd; // *pReportCmd will be free by handler: zclSampleLight_ProcessIncomingMsg() pReportCmd = (zclReportCmd_t *)pInMsg->attrCmd; afAddrType_t dstAddr; dstAddr.addrMode = (afAddrMode_t)AddrNotPresent; // send report to bound remote endpoints zcl_SendReportCmd( SAMPLELIGHT_ENDPOINT, &dstAddr, pInMsg->clusterId, pReportCmd, ZCL_REPORT_SEND, true, zclSampleLightSeqNum++); // you can send additional reportable attributes as needed /** zcl_SendReportCmd ( SAMPLELIGHT_ENDPOINT, &dstAddr, ...); **/ // i.e. for Thermostat Cluster that reports LocalTemperature, PICoolingDemand, and PIHeatingDemand. // see ZIGBEE CLUSTER LIBRARY SPECIFICATION: 6.3.2.5 Attribute Reporting of the Thermostat Cluster return ( TRUE ); }
  • 32. 32 When We Got a Config Report Cmd #ifdef ZCL_REPORT /********************************************************************* * @fn zclSampleLight_ProcessInConfigReportCmd * @brief Process the "Profile" Config Report Command * @param pInMsg - incoming message to process * @return none */ static uint8 zclSampleLight_ProcessInConfigReportCmd( zclIncomingMsg_t *pInMsg ) { zclCfgReportCmd_t *pCfgReportCmd; zclCfgReportRspCmd_t *pCfgReportRspCmd; uint8 sendRsp = FALSE; uint16 len; uint8 j = 0; uint8 i; pCfgReportCmd = (zclCfgReportCmd_t *)pInMsg->attrCmd; if ( pInMsg->zclHdr.commandID == ZCL_CMD_CONFIG_REPORT ) { // We need to send a response back - allocate space for it len = sizeof( zclCfgReportRspCmd_t ) + (pCfgReportCmd->numAttr * sizeof( zclCfgReportStatus_t )); pCfgReportRspCmd = (zclCfgReportRspCmd_t *)zcl_mem_alloc( len ); if ( pCfgReportRspCmd == NULL ) { return FALSE; // EMBEDDED RETURN } sendRsp = TRUE; // sendRsp is active when we got correct commandID }
  • 33. 33 for ( i = 0; i < pCfgReportCmd->numAttr; i++ ) { zclConfigReportRec_t *pConfigReportRec = NULL; // find the rec and store here zclAttrRec_t attrRec; zclCfgReportStatus_t *statusRec = &(pCfgReportRspCmd->attrList[i]); zcl_memset( statusRec, 0, sizeof( zclCfgReportStatus_t ) ); if ( zclFindConfigReportRec( pInMsg->endPoint, pInMsg->clusterId, pCfgReportCmd->attrList[i].attrID, &pConfigReportRec ) ) { uint8 status = ZCL_STATUS_SUCCESS; if ( pCfgReportCmd->attrList[i].dataType != pConfigReportRec->cfgReportRec.dataType ) { status = ZCL_STATUS_INVALID_DATA_TYPE; } else { if ( zclFindAttrRec( pInMsg->endPoint, pInMsg->clusterId, pCfgReportCmd->attrList[i].attrID, &attrRec ) ) { if ( pCfgReportCmd->attrList[i].dataType != attrRec.attr.dataType ) { status = ZCL_STATUS_INVALID_DATA_TYPE; } else { if ( !zcl_AccessCtrlRead( attrRec.attr.accessControl ) ) { status = ZCL_STATUS_WRITE_ONLY; } } } }
  • 34. 34 // If successful, store the record, and a CfgReportStatus record shall NOT be generated if ( sendRsp && status != ZCL_STATUS_SUCCESS ) { // Attribute is write only or invalid data type - move on to the next record statusRec->status = status; statusRec->direction = pCfgReportCmd->attrList[i].direction; statusRec->attrID = pCfgReportCmd->attrList[i].attrID; j++; } else { // success, set the config report rec pConfigReportRec->cfgReportRec.direction = pCfgReportCmd->attrList[i].direction; pConfigReportRec->cfgReportRec.minReportInt = pCfgReportCmd->attrList[i].minReportInt; pConfigReportRec->cfgReportRec.maxReportInt = pCfgReportCmd->attrList[i].maxReportInt; pConfigReportRec->cfgReportRec.timeoutPeriod = pCfgReportCmd->attrList[i].timeoutPeriod; pConfigReportRec->timeup = 0xFFFF; } } else { // Attribute is not supported - move on to the next configReportRec record if ( sendRsp ) { statusRec->status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; statusRec->direction = pCfgReportCmd->attrList[i].direction; statusRec->attrID = pCfgReportCmd->attrList[i].attrID; j++; } } } // for loop
  • 35. 35 if ( sendRsp ) { pCfgReportRspCmd->numAttr = j; if ( pCfgReportRspCmd->numAttr == 0 ) { // Since all records were written successful, include a single status record // in the response command with the status field set to SUCCESS and the // attribute ID and direction fields omitted. pCfgReportRspCmd->attrList[0].status = ZCL_STATUS_SUCCESS; pCfgReportRspCmd->numAttr = 1; } zcl_SendConfigReportRspCmd( pInMsg->endPoint, &(pInMsg->srcAddr), pInMsg->clusterId, pCfgReportRspCmd, !pInMsg->zclHdr.fc.direction, true, pInMsg->zclHdr.transSeqNum ); zcl_mem_free( pCfgReportRspCmd ); } // When configured, check report config immediately zclSampleLight_CheckReportConfig(); // The SAMPLELIGHT_CHECK_REPORT_EVT will then be triggered again and again // If we never received the ConfigReportCmd, the SAMPLELIGHT_CHECK_REPORT_EVT has // no change to be triggered. // We think this makes sense, since there is no reason for your app to perform // constantly report unless the app is configured to report. // If your app just need to automatically report after bootup, you can trigger // SAMPLELIGHT_CHECK_REPORT_EVT in zclSampleLight_Init(). return TRUE; }
  • 36. 36 When We Got a Read Report Config Cmd /********************************************************************* * @fn zclSampleLight_ProcessInReadReportCfgCmd * @brief Process the "Profile" Read Report Config Command * @param pInMsg - incoming message to process * @return none */ static uint8 zclSampleLight_ProcessInReadReportCfgCmd( zclIncomingMsg_t *pInMsg ) { zclReadReportCfgCmd_t *pReadReportCfgCmd; zclReadReportCfgRspCmd_t *pReadReportCfgRspCmd; uint8 sendRsp = FALSE; uint16 len; uint8 i; pReadReportCfgCmd = (zclReadReportCfgCmd_t *)pInMsg->attrCmd; if ( pInMsg->zclHdr.commandID == ZCL_CMD_READ_REPORT_CFG ) { // We need to send a response back - allocate space for it len = sizeof( zclReadReportCfgRspCmd_t ) + (pReadReportCfgCmd->numAttr * sizeof( zclReportCfgRspRec_t )); pReadReportCfgRspCmd = (zclReadReportCfgRspCmd_t *)zcl_mem_alloc( len ); if ( pReadReportCfgRspCmd == NULL ) { return FALSE; // EMBEDDED RETURN } sendRsp = TRUE; // sendRsp is active when we got correct commandID }
  • 37. 37 for ( i = 0; i < pReadReportCfgCmd->numAttr; i++ ) { zclConfigReportRec_t *pConfigReportRec = NULL; // find the rec and store here zclReportCfgRspRec_t *pReportCfgRspRec = &(pReadReportCfgRspCmd->attrList[i]); zclAttrRec_t attrRec; zcl_memset( pReportCfgRspRec, 0, sizeof( zclReportCfgRspRec_t ) ); if ( zclFindConfigReportRec( pInMsg->endPoint, pInMsg->clusterId, pReadReportCfgCmd->attrList[i].attrID, &pConfigReportRec ) ) { // if found configReportRec if ( sendRsp ) { pReportCfgRspRec->status = ZCL_STATUS_SUCCESS; pReportCfgRspRec->direction = pConfigReportRec->cfgReportRec.direction; pReportCfgRspRec->attrID = pConfigReportRec->cfgReportRec.attrID; pReportCfgRspRec->dataType = pConfigReportRec->cfgReportRec.dataType; pReportCfgRspRec->minReportInt = pConfigReportRec->cfgReportRec.minReportInt; pReportCfgRspRec->maxReportInt = pConfigReportRec->cfgReportRec.maxReportInt; pReportCfgRspRec->timeoutPeriod = pConfigReportRec->cfgReportRec.timeoutPeriod; pReportCfgRspRec->reportableChange = pConfigReportRec->cfgReportRec.reportableChange; } } else { // if not found configReportRec, check if the attribute is an un-reportable // or an un-supported one uint8 status = ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; if ( zclFindAttrRec( pInMsg->endPoint, pInMsg->clusterId, pReadReportCfgCmd->attrList[i].attrID, &attrRec ) ) { // if found the attr rec, it is there but un-reportable status = ZCL_STATUS_UNREPORTABLE_ATTRIBUTE; }
  • 38. 38 // Attribute is not supported - move on to the next configReportRec record if ( sendRsp ) { pReportCfgRspRec->status = status; pReportCfgRspRec->direction = pReadReportCfgCmd->attrList[i].direction; pReportCfgRspRec->attrID = pReadReportCfgCmd->attrList[i].attrID; } } } // for loop if ( sendRsp ) { pReadReportCfgRspCmd->numAttr = pReadReportCfgCmd->numAttr; zcl_SendReadReportCfgRspCmd( pInMsg->endPoint, &(pInMsg->srcAddr), pInMsg->clusterId, pReadReportCfgRspCmd, !pInMsg->zclHdr.fc.direction, true, pInMsg->zclHdr.transSeqNum ); zcl_mem_free( pReadReportCfgRspCmd ); } return TRUE; } /********************************************************************* * @fn zclSampleLight_ProcessInReportCmd * [...] #endif // ZCL_REPORT
  • 39. 39 Don’t Forget to Uncomment Handlers static void zclSampleLight_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg ) { switch ( pInMsg->zclHdr.commandID ) { [...] #ifdef ZCL_REPORT // Attribute Reporting implementation should be added here case ZCL_CMD_CONFIG_REPORT: zclSampleLight_ProcessInConfigReportCmd( pInMsg ); break; case ZCL_CMD_CONFIG_REPORT_RSP: // zclSampleLight_ProcessInConfigReportRspCmd( pInMsg ); break; case ZCL_CMD_READ_REPORT_CFG: zclSampleLight_ProcessInReadReportCfgCmd( pInMsg ); break; case ZCL_CMD_READ_REPORT_CFG_RSP: // zclSampleLight_ProcessInReadReportCfgRspCmd( pInMsg ); break; case ZCL_CMD_REPORT: zclSampleLight_ProcessInReportCmd( pInMsg ); break; #endif [...]
  • 40. 40 Print out the time stamp and messages received by the host. You must perform ‘binding’ first, or you’ll not receive anything. (Report is sending out with ‘AddrNotPresent‘, z-stack will find out the addresses of the bound devices) Test Results (I) Cluster: GenOnOff (0x0006) Attribute: OnOff (0x0000) Reporting period = 3 secs 3 secs 3 secs 3 secs 3 secs Cluster: GenOnOff (0x0006) Attribute: OnOff (0x0000) Reporting period = 5 secs - Suddenly turn on or turn off the light 5 secs 5 secs 5 secs Changing of the OnOff Attr. was reported Changing of the OnOff Attr. was reported
  • 41. 41 Test Results (II) 10 secs 10 secs 10 secs Report of level changing 10 secs 10 secs 10 secs 10 secs Report of level changing 10 secs 10 secs Report of level changing Cluster: GenLevelControl (0x0008) Attribute: CurrentLevel (0x0000) Reporting period = 10 secs Amount of Change to Report = 20 - Suddenly change the light level ∆ = 199 ∆ = 170 ∆ = -10 (not reported) ∆ = -160
  • 42. 42 [1] Z-Stack ZigBee Cluster Library Application Programming Interface, Texas Instruments References