3 * Copyright (c) 2021 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 // THIS FILE IS GENERATED BY ZAP
22 #include "af-structs.h"
23 #include "app/util/util.h"
24 #include "call-command-handler.h"
26 #include "cluster-id.h"
27 #include "command-id.h"
31 EmberAfStatus emberAfBasicClusterServerCommandParse(EmberAfClusterCommand * cmd);
32 EmberAfStatus emberAfNetworkCommissioningClusterServerCommandParse(EmberAfClusterCommand * cmd);
33 EmberAfStatus emberAfOnOffClusterServerCommandParse(EmberAfClusterCommand * cmd);
35 static EmberAfStatus status(bool wasHandled, bool clusterExists, bool mfgSpecific)
39 return EMBER_ZCL_STATUS_SUCCESS;
43 return EMBER_ZCL_STATUS_UNSUP_MANUF_CLUSTER_COMMAND;
45 else if (clusterExists)
47 return EMBER_ZCL_STATUS_UNSUP_COMMAND;
51 return EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER;
55 // Main command parsing controller.
56 EmberAfStatus emberAfClusterSpecificCommandParse(EmberAfClusterCommand * cmd)
58 EmberAfStatus result = status(false, false, cmd->mfgSpecific);
59 if (cmd->direction == (uint8_t) ZCL_DIRECTION_SERVER_TO_CLIENT &&
60 emberAfContainsClientWithMfgCode(cmd->apsFrame->destinationEndpoint, cmd->apsFrame->clusterId, cmd->mfgCode))
62 switch (cmd->apsFrame->clusterId)
65 // Unrecognized cluster ID, error status will apply.
69 else if (cmd->direction == (uint8_t) ZCL_DIRECTION_CLIENT_TO_SERVER &&
70 emberAfContainsServerWithMfgCode(cmd->apsFrame->destinationEndpoint, cmd->apsFrame->clusterId, cmd->mfgCode))
72 switch (cmd->apsFrame->clusterId)
74 case ZCL_BASIC_CLUSTER_ID:
75 // No commands are enabled for cluster Basic
76 result = status(false, true, cmd->mfgSpecific);
78 case ZCL_NETWORK_COMMISSIONING_CLUSTER_ID:
79 result = emberAfNetworkCommissioningClusterServerCommandParse(cmd);
81 case ZCL_ON_OFF_CLUSTER_ID:
82 result = emberAfOnOffClusterServerCommandParse(cmd);
85 // Unrecognized cluster ID, error status will apply.
92 // Cluster specific command parsing
94 EmberAfStatus emberAfNetworkCommissioningClusterServerCommandParse(EmberAfClusterCommand * cmd)
96 bool wasHandled = false;
98 if (!cmd->mfgSpecific)
100 switch (cmd->commandId)
102 case ZCL_ADD_THREAD_NETWORK_COMMAND_ID: {
103 uint16_t payloadOffset = cmd->payloadStartIndex;
104 chip::ByteSpan operationalDataset;
108 if (cmd->bufLen < payloadOffset + 1u)
110 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
113 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
114 operationalDataset = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
116 payloadOffset = static_cast<uint16_t>(payloadOffset + operationalDataset.size() + 1u);
117 if (cmd->bufLen < payloadOffset + 8)
119 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
121 breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
122 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
123 if (cmd->bufLen < payloadOffset + 4)
125 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
127 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
129 wasHandled = emberAfNetworkCommissioningClusterAddThreadNetworkCallback(operationalDataset, breadcrumb, timeoutMs);
132 case ZCL_ADD_WI_FI_NETWORK_COMMAND_ID: {
133 uint16_t payloadOffset = cmd->payloadStartIndex;
135 chip::ByteSpan credentials;
139 if (cmd->bufLen < payloadOffset + 1u)
141 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
144 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
145 ssid = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
147 payloadOffset = static_cast<uint16_t>(payloadOffset + ssid.size() + 1u);
148 if (cmd->bufLen < payloadOffset + 1u)
150 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
153 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
154 credentials = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
156 payloadOffset = static_cast<uint16_t>(payloadOffset + credentials.size() + 1u);
157 if (cmd->bufLen < payloadOffset + 8)
159 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
161 breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
162 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
163 if (cmd->bufLen < payloadOffset + 4)
165 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
167 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
169 wasHandled = emberAfNetworkCommissioningClusterAddWiFiNetworkCallback(ssid, credentials, breadcrumb, timeoutMs);
172 case ZCL_DISABLE_NETWORK_COMMAND_ID: {
173 uint16_t payloadOffset = cmd->payloadStartIndex;
174 chip::ByteSpan networkID;
178 if (cmd->bufLen < payloadOffset + 1u)
180 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
183 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
184 networkID = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
186 payloadOffset = static_cast<uint16_t>(payloadOffset + networkID.size() + 1u);
187 if (cmd->bufLen < payloadOffset + 8)
189 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
191 breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
192 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
193 if (cmd->bufLen < payloadOffset + 4)
195 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
197 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
199 wasHandled = emberAfNetworkCommissioningClusterDisableNetworkCallback(networkID, breadcrumb, timeoutMs);
202 case ZCL_ENABLE_NETWORK_COMMAND_ID: {
203 uint16_t payloadOffset = cmd->payloadStartIndex;
204 chip::ByteSpan networkID;
208 if (cmd->bufLen < payloadOffset + 1u)
210 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
213 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
214 networkID = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
216 payloadOffset = static_cast<uint16_t>(payloadOffset + networkID.size() + 1u);
217 if (cmd->bufLen < payloadOffset + 8)
219 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
221 breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
222 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
223 if (cmd->bufLen < payloadOffset + 4)
225 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
227 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
229 wasHandled = emberAfNetworkCommissioningClusterEnableNetworkCallback(networkID, breadcrumb, timeoutMs);
232 case ZCL_GET_LAST_NETWORK_COMMISSIONING_RESULT_COMMAND_ID: {
233 uint16_t payloadOffset = cmd->payloadStartIndex;
236 if (cmd->bufLen < payloadOffset + 4)
238 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
240 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
242 wasHandled = emberAfNetworkCommissioningClusterGetLastNetworkCommissioningResultCallback(timeoutMs);
245 case ZCL_REMOVE_NETWORK_COMMAND_ID: {
246 uint16_t payloadOffset = cmd->payloadStartIndex;
247 chip::ByteSpan NetworkID;
251 if (cmd->bufLen < payloadOffset + 1u)
253 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
256 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
257 NetworkID = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
259 payloadOffset = static_cast<uint16_t>(payloadOffset + NetworkID.size() + 1u);
260 if (cmd->bufLen < payloadOffset + 8)
262 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
264 Breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
265 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
266 if (cmd->bufLen < payloadOffset + 4)
268 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
270 TimeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
272 wasHandled = emberAfNetworkCommissioningClusterRemoveNetworkCallback(NetworkID, Breadcrumb, TimeoutMs);
275 case ZCL_SCAN_NETWORKS_COMMAND_ID: {
276 uint16_t payloadOffset = cmd->payloadStartIndex;
281 if (cmd->bufLen < payloadOffset + 1u)
283 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
286 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
287 ssid = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
289 payloadOffset = static_cast<uint16_t>(payloadOffset + ssid.size() + 1u);
290 if (cmd->bufLen < payloadOffset + 8)
292 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
294 breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
295 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
296 if (cmd->bufLen < payloadOffset + 4)
298 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
300 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
302 wasHandled = emberAfNetworkCommissioningClusterScanNetworksCallback(ssid, breadcrumb, timeoutMs);
305 case ZCL_UPDATE_THREAD_NETWORK_COMMAND_ID: {
306 uint16_t payloadOffset = cmd->payloadStartIndex;
307 chip::ByteSpan operationalDataset;
311 if (cmd->bufLen < payloadOffset + 1u)
313 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
316 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
317 operationalDataset = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
319 payloadOffset = static_cast<uint16_t>(payloadOffset + operationalDataset.size() + 1u);
320 if (cmd->bufLen < payloadOffset + 8)
322 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
324 breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
325 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
326 if (cmd->bufLen < payloadOffset + 4)
328 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
330 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
332 wasHandled = emberAfNetworkCommissioningClusterUpdateThreadNetworkCallback(operationalDataset, breadcrumb, timeoutMs);
335 case ZCL_UPDATE_WI_FI_NETWORK_COMMAND_ID: {
336 uint16_t payloadOffset = cmd->payloadStartIndex;
338 chip::ByteSpan credentials;
342 if (cmd->bufLen < payloadOffset + 1u)
344 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
347 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
348 ssid = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
350 payloadOffset = static_cast<uint16_t>(payloadOffset + ssid.size() + 1u);
351 if (cmd->bufLen < payloadOffset + 1u)
353 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
356 uint8_t * rawData = emberAfGetString(cmd->buffer, payloadOffset, cmd->bufLen);
357 credentials = chip::ByteSpan(rawData + 1u, emberAfStringLength(rawData));
359 payloadOffset = static_cast<uint16_t>(payloadOffset + credentials.size() + 1u);
360 if (cmd->bufLen < payloadOffset + 8)
362 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
364 breadcrumb = emberAfGetInt64u(cmd->buffer, payloadOffset, cmd->bufLen);
365 payloadOffset = static_cast<uint16_t>(payloadOffset + 8);
366 if (cmd->bufLen < payloadOffset + 4)
368 return EMBER_ZCL_STATUS_MALFORMED_COMMAND;
370 timeoutMs = emberAfGetInt32u(cmd->buffer, payloadOffset, cmd->bufLen);
372 wasHandled = emberAfNetworkCommissioningClusterUpdateWiFiNetworkCallback(ssid, credentials, breadcrumb, timeoutMs);
376 // Unrecognized command ID, error status will apply.
381 return status(wasHandled, true, cmd->mfgSpecific);
383 EmberAfStatus emberAfOnOffClusterServerCommandParse(EmberAfClusterCommand * cmd)
385 bool wasHandled = false;
387 if (!cmd->mfgSpecific)
389 switch (cmd->commandId)
391 case ZCL_OFF_COMMAND_ID: {
392 wasHandled = emberAfOnOffClusterOffCallback();
395 case ZCL_ON_COMMAND_ID: {
396 wasHandled = emberAfOnOffClusterOnCallback();
399 case ZCL_TOGGLE_COMMAND_ID: {
400 wasHandled = emberAfOnOffClusterToggleCallback();
404 // Unrecognized command ID, error status will apply.
409 return status(wasHandled, true, cmd->mfgSpecific);