3 * Copyright (c) 2020 Project CHIP Authors
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 /****************************************************************************
20 * @brief Implementation for the Binding Server Cluster
21 ***************************************************************************/
25 #include <app/util/binding-table.h>
26 #include <support/logging/CHIPLogging.h>
30 EmberStatus prepareBinding(EmberBindingTableEntry & binding, NodeId nodeId, GroupId groupId, EndpointId endpointId,
33 if (groupId && nodeId)
35 return EMBER_BAD_ARGUMENT;
38 binding.clusterId = clusterId;
39 binding.local = emberAfCurrentCommand()->apsFrame->destinationEndpoint;
40 binding.networkIndex = 0;
44 binding.type = EMBER_MULTICAST_BINDING;
45 binding.groupId = groupId;
50 binding.type = EMBER_UNICAST_BINDING;
51 binding.nodeId = nodeId;
52 binding.remote = endpointId;
58 EmberStatus getBindingIndex(EmberBindingTableEntry & newEntry, uint8_t * bindingIndex)
60 EmberBindingTableEntry currentEntry;
61 for (uint8_t i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
63 emberGetBinding(i, ¤tEntry);
64 if (currentEntry.type != EMBER_UNUSED_BINDING && currentEntry == newEntry)
71 return EMBER_NOT_FOUND;
74 EmberStatus getUnusedBindingIndex(uint8_t * bindingIndex)
76 EmberBindingTableEntry currentEntry;
77 for (uint8_t i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
79 emberGetBinding(i, ¤tEntry);
80 if (currentEntry.type == EMBER_UNUSED_BINDING)
87 return EMBER_NOT_FOUND;
90 bool emberAfBindingClusterBindCallback(NodeId nodeId, GroupId groupId, EndpointId endpointId, ClusterId clusterId)
92 ChipLogDetail(Zcl, "RX: BindCallback");
94 EmberBindingTableEntry bindingEntry;
95 if (prepareBinding(bindingEntry, nodeId, groupId, endpointId, clusterId) != EMBER_SUCCESS)
97 emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
101 uint8_t bindingIndex;
102 if (getBindingIndex(bindingEntry, &bindingIndex) != EMBER_NOT_FOUND)
104 emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_DUPLICATE_EXISTS);
108 if (getUnusedBindingIndex(&bindingIndex) != EMBER_SUCCESS)
110 emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INSUFFICIENT_SPACE);
114 emberSetBinding(bindingIndex, &bindingEntry);
115 emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
119 bool emberAfBindingClusterUnbindCallback(NodeId nodeId, GroupId groupId, EndpointId endpointId, ClusterId clusterId)
121 ChipLogDetail(Zcl, "RX: UnbindCallback");
123 EmberBindingTableEntry bindingEntry;
124 if (prepareBinding(bindingEntry, nodeId, groupId, endpointId, clusterId) != EMBER_SUCCESS)
126 emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
130 uint8_t bindingIndex;
131 if (getBindingIndex(bindingEntry, &bindingIndex) != EMBER_SUCCESS)
133 emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_NOT_FOUND);
137 emberDeleteBinding(bindingIndex);
138 emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);