1+ #include "scene_cluster.h"
2+ #include "relay_cluster.h"
3+ #include "cluster_common.h"
4+
5+ zigbee_scene_cluster * scene_cluster_by_endpoint [10 ] = {};
6+
7+ static void store_scene (zcl_sceneEntry_t * scene_entry , zigbee_scene_cluster * cluster );
8+ static void recall_scene (zcl_sceneEntry_t * scene_entry , zigbee_scene_cluster * cluster );
9+
10+ static const u8 scene_name_support = 0x01 ;
11+
12+ void scene_cluster_add_to_endpoint (zigbee_scene_cluster * cluster , zigbee_endpoint * endpoint )
13+ {
14+ SETUP_ATTR (0 , ZCL_ATTRID_SCENE_SCENE_COUNT , ZCL_DATA_TYPE_UINT8 , ACCESS_CONTROL_READ , cluster -> scene_count );
15+ SETUP_ATTR (1 , ZCL_ATTRID_SCENE_CURRENT_SCENE , ZCL_DATA_TYPE_UINT8 , ACCESS_CONTROL_READ , cluster -> current_scene );
16+ SETUP_ATTR (2 , ZCL_ATTRID_SCENE_CURRENT_GROUP , ZCL_DATA_TYPE_UINT16 , ACCESS_CONTROL_READ , cluster -> current_group );
17+ SETUP_ATTR (3 , ZCL_ATTRID_SCENE_SCENE_VALID , ZCL_DATA_TYPE_BOOLEAN , ACCESS_CONTROL_READ , cluster -> scene_valid );
18+ SETUP_ATTR (4 , ZCL_ATTRID_SCENE_NAME_SUPPORT , ZCL_DATA_TYPE_BITMAP8 , ACCESS_CONTROL_READ , scene_name_support );
19+ SETUP_ATTR (5 , ZCL_ATTRID_SCENE_LAST_CONFIG_BY , ZCL_DATA_TYPE_IEEE_ADDR , ACCESS_CONTROL_READ , cluster -> last_configured_by );
20+ SETUP_ATTR (6 , ZCL_ATTRID_GLOBAL_CLUSTER_REVISION , ZCL_DATA_TYPE_UINT16 , ACCESS_CONTROL_READ , zcl_attr_global_clusterRevision );
21+
22+ zigbee_endpoint_add_cluster (endpoint , 1 , ZCL_CLUSTER_GEN_SCENES );
23+ zcl_specClusterInfo_t * info = zigbee_endpoint_reserve_info (endpoint );
24+ info -> clusterId = ZCL_CLUSTER_GEN_SCENES ;
25+ info -> manuCode = MANUFACTURER_CODE_NONE ;
26+ info -> attrNum = SCENE_CLUSTER_ATTR_NUM ;
27+ info -> attrTbl = cluster -> attr_infos ;
28+ info -> clusterRegisterFunc = zcl_scene_register ;
29+ info -> clusterAppCb = scene_cluster_callback ;
30+ }
31+
32+ status_t scene_cluster_callback (zclIncomingAddrInfo_t * pAddrInfo , u8 cmdId , void * cmdPayload )
33+ {
34+ zigbee_scene_cluster * cluster = scene_cluster_by_endpoint [pAddrInfo -> dstEp ];
35+
36+ status_t status = ZCL_STA_SUCCESS ;
37+
38+ if (pAddrInfo -> dirCluster == ZCL_FRAME_CLIENT_SERVER_DIR )
39+ {
40+ switch (cmdId )
41+ {
42+ case ZCL_CMD_SCENE_STORE_SCENE :
43+ store_scene (cmdPayload , cluster );
44+ break ;
45+ case ZCL_CMD_SCENE_RECALL_SCENE :
46+ recall_scene (cmdPayload , cluster );
47+ break ;
48+ default :
49+ break ;
50+ }
51+ }
52+ else
53+ {
54+ status = ZCL_STA_UNSUP_CLUSTER_COMMAND ;
55+ }
56+
57+ return status ;
58+ }
59+
60+ static void recall_scene (zcl_sceneEntry_t * scene_entry , zigbee_scene_cluster * cluster )
61+ {
62+ u8 * pData = scene_entry -> extField ;
63+ u16 clusterID = 0xFFFF ;
64+ u8 extLen = 0 ;
65+
66+ while (pData < scene_entry -> extField + scene_entry -> extFieldLen ) {
67+ clusterID = BUILD_U16 (pData [0 ], pData [1 ]);
68+ pData += 2 ;//cluster id
69+
70+ extLen = * pData ++ ;//length
71+
72+ if (clusterID == ZCL_CLUSTER_GEN_ON_OFF && cluster -> relay_cluster ) {
73+ if (extLen >= 1 ) {
74+ u8 onOff = * pData ++ ;
75+
76+ relay_cluster_set_on_off (cluster -> relay_cluster , onOff , true);
77+ extLen -- ;
78+ }
79+ }
80+
81+ pData += extLen ;
82+ }
83+ }
84+
85+ static void store_scene (zcl_sceneEntry_t * scene_entry , zigbee_scene_cluster * cluster )
86+ {
87+ u8 extLen = 0 ;
88+
89+ if (cluster -> relay_cluster ) {
90+ bool on_off = cluster -> relay_cluster -> on_off ;
91+
92+ scene_entry -> extField [extLen ++ ] = LO_UINT16 (ZCL_CLUSTER_GEN_ON_OFF );
93+ scene_entry -> extField [extLen ++ ] = HI_UINT16 (ZCL_CLUSTER_GEN_ON_OFF );
94+ scene_entry -> extField [extLen ++ ] = sizeof (u8 );
95+ scene_entry -> extField [extLen ++ ] = on_off ;
96+ }
97+
98+ // Add other clusters to save here...
99+
100+ scene_entry -> extFieldLen = extLen ;
101+ }
0 commit comments