Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / app / clusters / zll-scenes-server / zll-scenes-server.c
1 /**
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /**
19  *
20  *    Copyright (c) 2020 Silicon Labs
21  *
22  *    Licensed under the Apache License, Version 2.0 (the "License");
23  *    you may not use this file except in compliance with the License.
24  *    You may obtain a copy of the License at
25  *
26  *        http://www.apache.org/licenses/LICENSE-2.0
27  *
28  *    Unless required by applicable law or agreed to in writing, software
29  *    distributed under the License is distributed on an "AS IS" BASIS,
30  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  *    See the License for the specific language governing permissions and
32  *    limitations under the License.
33  */
34
35 /**
36  * @file
37  * @brief Routines for the ZLL Scenes Server plugin.
38  *******************************************************************************
39  * # License
40  * <b>Copyright 2018 Silicon Laboratories Inc.
41  * www.silabs.com</b>
42  *******************************************************************************
43  *
44  * The licensor of this software is Silicon
45  * Laboratories Inc. Your use of this software is
46  * governed by the terms of Silicon Labs Master
47  * Software License Agreement (MSLA) available at
48  * www.silabs.com/about-us/legal/master-software-license-agreement.
49  * This software is distributed to you in Source Code
50  * format and is governed by the sections of the MSLA
51  * applicable to Source Code.
52  *
53  ******************************************************************************/
54
55 #include "../../include/af.h"
56 #include "../scenes/scenes.h"
57
58 #define ZCL_SCENES_CLUSTER_MODE_COPY_ALL_SCENES_MASK EMBER_BIT(0)
59
60 bool emberAfScenesClusterEnhancedAddSceneCallback(uint16_t groupId, uint8_t sceneId, uint16_t transitionTime, uint8_t * sceneName,
61                                                   uint8_t * extensionFieldSets)
62 {
63     return emberAfPluginScenesServerParseAddScene(emberAfCurrentCommand(), groupId, sceneId, transitionTime, sceneName,
64                                                   extensionFieldSets);
65 }
66
67 bool emberAfScenesClusterEnhancedViewSceneCallback(uint16_t groupId, uint8_t sceneId)
68 {
69     return emberAfPluginScenesServerParseViewScene(emberAfCurrentCommand(), groupId, sceneId);
70 }
71
72 bool emberAfScenesClusterCopySceneCallback(uint8_t mode, uint16_t groupIdFrom, uint8_t sceneIdFrom, uint16_t groupIdTo,
73                                            uint8_t sceneIdTo)
74 {
75     EmberStatus sendStatus;
76     EmberAfStatus status = EMBER_ZCL_STATUS_INVALID_FIELD;
77     bool copyAllScenes   = (mode & ZCL_SCENES_CLUSTER_MODE_COPY_ALL_SCENES_MASK);
78     uint8_t i;
79
80     emberAfScenesClusterPrintln("RX: CopyScene 0x%x, 0x%2x, 0x%x, 0x%2x, 0x%x", mode, groupIdFrom, sceneIdFrom, groupIdTo,
81                                 sceneIdTo);
82
83     // If a group id is specified but this endpoint isn't in it, take no action.
84     if ((groupIdFrom != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID &&
85          !emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(), groupIdFrom)) ||
86         (groupIdTo != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID &&
87          !emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(), groupIdTo)))
88     {
89         status = EMBER_ZCL_STATUS_INVALID_FIELD;
90         goto kickout;
91     }
92
93     for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
94     {
95         EmberAfSceneTableEntry from;
96         emberAfPluginScenesServerRetrieveSceneEntry(from, i);
97         if (from.endpoint == emberAfCurrentEndpoint() && from.groupId == groupIdFrom &&
98             (copyAllScenes || from.sceneId == sceneIdFrom))
99         {
100             uint8_t j, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;
101             for (j = 0; j < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; j++)
102             {
103                 EmberAfSceneTableEntry to;
104                 if (i == j)
105                 {
106                     continue;
107                 }
108                 emberAfPluginScenesServerRetrieveSceneEntry(to, j);
109                 if (to.endpoint == emberAfCurrentEndpoint() && to.groupId == groupIdTo &&
110                     to.sceneId == (copyAllScenes ? from.sceneId : sceneIdTo))
111                 {
112                     index = j;
113                     break;
114                 }
115                 else if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX && to.endpoint == EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID)
116                 {
117                     index = j;
118                 }
119             }
120
121             // If the target index is still zero, the table is full.
122             if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX)
123             {
124                 status = EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
125                 goto kickout;
126             }
127
128             // Save the "from" entry to the "to" index.  This makes a copy of "from"
129             // with the correct group and scene ids and leaves the original in tact.
130             from.groupId = groupIdTo;
131             if (!copyAllScenes)
132             {
133                 from.sceneId = sceneIdTo;
134             }
135             emberAfPluginScenesServerSaveSceneEntry(from, index);
136
137             if (j != index)
138             {
139                 emberAfPluginScenesServerIncrNumSceneEntriesInUse();
140                 emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
141             }
142
143             // If we aren't copying all scenes, we can stop here.
144             status = EMBER_ZCL_STATUS_SUCCESS;
145             if (!copyAllScenes)
146             {
147                 goto kickout;
148             }
149         }
150     }
151
152 kickout:
153     // Copy Scene commands are only responded to when they are addressed to a
154     // single device.
155     if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
156     {
157         emberAfFillCommandScenesClusterCopySceneResponse(status, groupIdFrom, sceneIdFrom);
158         sendStatus = emberAfSendResponse();
159         if (EMBER_SUCCESS != sendStatus)
160         {
161             emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "copy_scene", sendStatus);
162         }
163     }
164     return true;
165 }
166
167 EmberAfStatus emberAfPluginZllScenesServerRecallSceneZllExtensions(uint8_t endpoint)
168 {
169     bool globalSceneControl = true;
170     EmberAfStatus status    = emberAfWriteServerAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_GLOBAL_SCENE_CONTROL_ATTRIBUTE_ID,
171                                                        (uint8_t *) &globalSceneControl, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
172     if (status != EMBER_ZCL_STATUS_SUCCESS)
173     {
174         emberAfScenesClusterPrintln("ERR: writing global scene control %x", status);
175     }
176     return status;
177 }