Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / app / clusters / bindings / bindings.cpp
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  * @file
20  * @brief Implementation for the Binding Server Cluster
21  ***************************************************************************/
22
23 #include "af.h"
24
25 #include <app/util/binding-table.h>
26 #include <support/logging/CHIPLogging.h>
27
28 using namespace chip;
29
30 EmberStatus prepareBinding(EmberBindingTableEntry & binding, NodeId nodeId, GroupId groupId, EndpointId endpointId,
31                            ClusterId clusterId)
32 {
33     if (groupId && nodeId)
34     {
35         return EMBER_BAD_ARGUMENT;
36     }
37
38     binding.clusterId    = clusterId;
39     binding.local        = emberAfCurrentCommand()->apsFrame->destinationEndpoint;
40     binding.networkIndex = 0;
41
42     if (groupId)
43     {
44         binding.type    = EMBER_MULTICAST_BINDING;
45         binding.groupId = groupId;
46         binding.remote  = 0;
47     }
48     else
49     {
50         binding.type   = EMBER_UNICAST_BINDING;
51         binding.nodeId = nodeId;
52         binding.remote = endpointId;
53     }
54
55     return EMBER_SUCCESS;
56 }
57
58 EmberStatus getBindingIndex(EmberBindingTableEntry & newEntry, uint8_t * bindingIndex)
59 {
60     EmberBindingTableEntry currentEntry;
61     for (uint8_t i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
62     {
63         emberGetBinding(i, &currentEntry);
64         if (currentEntry.type != EMBER_UNUSED_BINDING && currentEntry == newEntry)
65         {
66             *bindingIndex = i;
67             return EMBER_SUCCESS;
68         }
69     }
70
71     return EMBER_NOT_FOUND;
72 }
73
74 EmberStatus getUnusedBindingIndex(uint8_t * bindingIndex)
75 {
76     EmberBindingTableEntry currentEntry;
77     for (uint8_t i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
78     {
79         emberGetBinding(i, &currentEntry);
80         if (currentEntry.type == EMBER_UNUSED_BINDING)
81         {
82             *bindingIndex = i;
83             return EMBER_SUCCESS;
84         }
85     }
86
87     return EMBER_NOT_FOUND;
88 }
89
90 bool emberAfBindingClusterBindCallback(NodeId nodeId, GroupId groupId, EndpointId endpointId, ClusterId clusterId)
91 {
92     ChipLogDetail(Zcl, "RX: BindCallback");
93
94     EmberBindingTableEntry bindingEntry;
95     if (prepareBinding(bindingEntry, nodeId, groupId, endpointId, clusterId) != EMBER_SUCCESS)
96     {
97         emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
98         return true;
99     }
100
101     uint8_t bindingIndex;
102     if (getBindingIndex(bindingEntry, &bindingIndex) != EMBER_NOT_FOUND)
103     {
104         emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_DUPLICATE_EXISTS);
105         return true;
106     }
107
108     if (getUnusedBindingIndex(&bindingIndex) != EMBER_SUCCESS)
109     {
110         emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INSUFFICIENT_SPACE);
111         return true;
112     }
113
114     emberSetBinding(bindingIndex, &bindingEntry);
115     emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
116     return true;
117 }
118
119 bool emberAfBindingClusterUnbindCallback(NodeId nodeId, GroupId groupId, EndpointId endpointId, ClusterId clusterId)
120 {
121     ChipLogDetail(Zcl, "RX: UnbindCallback");
122
123     EmberBindingTableEntry bindingEntry;
124     if (prepareBinding(bindingEntry, nodeId, groupId, endpointId, clusterId) != EMBER_SUCCESS)
125     {
126         emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
127         return true;
128     }
129
130     uint8_t bindingIndex;
131     if (getBindingIndex(bindingEntry, &bindingIndex) != EMBER_SUCCESS)
132     {
133         emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_NOT_FOUND);
134         return true;
135     }
136
137     emberDeleteBinding(bindingIndex);
138     emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
139     return true;
140 }