Apply Upstream code (2021-03-15)
[platform/upstream/connectedhomeip.git] / src / app / zap-templates / templates / app / CHIPClientCallbacks-src.zapt
1 {{> header}}
2
3 #include "gen/CHIPClientCallbacks.h"
4
5 #include "gen/enums.h"
6 #include <app/util/af.h>
7 #include <app/util/af-enums.h>
8 #include <app/util/basic-types.h>
9 #include <app/util/CHIPDeviceCallbacksMgr.h>
10 #include <core/CHIPEncoding.h>
11 #include <support/SafeInt.h>
12 #include <support/logging/CHIPLogging.h>
13
14 using namespace ::chip;
15
16 #define CHECK_MESSAGE_LENGTH(value)                                                                                                \
17     if (!chip::CanCastTo<uint16_t>(value))                                                                                         \
18     {                                                                                                                              \
19         ChipLogError(Zcl, "CHECK_MESSAGE_LENGTH expects a uint16_t value, got: %d", value);                                        \
20         if (onFailureCallback != nullptr)                                                                                          \
21         {                                                                                                                          \
22             Callback::Callback<DefaultFailureCallback> * cb =                                                                      \
23                 Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);                                     \
24             cb->mCall(cb->mContext, static_cast<uint8_t>(EMBER_ZCL_STATUS_INVALID_VALUE));                                         \
25         }                                                                                                                          \
26         return true;                                                                                                               \
27     }                                                                                                                              \
28                                                                                                                                    \
29     if (messageLen < value)                                                                                                        \
30     {                                                                                                                              \
31         ChipLogError(Zcl, "Unexpected response length: %d", messageLen);                                                           \
32         if (onFailureCallback != nullptr)                                                                                          \
33         {                                                                                                                          \
34             Callback::Callback<DefaultFailureCallback> * cb =                                                                      \
35                 Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);                                     \
36             cb->mCall(cb->mContext, static_cast<uint8_t>(EMBER_ZCL_STATUS_INVALID_VALUE));                                         \
37         }                                                                                                                          \
38         return true;                                                                                                               \
39     }                                                                                                                              \
40                                                                                                                                    \
41     messageLen = static_cast<uint16_t>(messageLen - static_cast<uint16_t>(value));
42
43 #define GET_RESPONSE_CALLBACKS(name)                                                                                               \
44     Callback::Cancelable * onSuccessCallback = nullptr;                                                                            \
45     Callback::Cancelable * onFailureCallback = nullptr;                                                                            \
46     NodeId sourceId                          = emberAfCurrentCommand()->source;                                                    \
47     uint8_t sequenceNumber                   = emberAfCurrentCommand()->seqNum;                                                    \
48     CHIP_ERROR err = gCallbacks.GetResponseCallback(sourceId, sequenceNumber, &onSuccessCallback, &onFailureCallback);             \
49                                                                                                                                    \
50     if (CHIP_NO_ERROR != err)                                                                                                      \
51     {                                                                                                                              \
52         if (onSuccessCallback == nullptr)                                                                                          \
53         {                                                                                                                          \
54             ChipLogDetail(Zcl, "%s: Missing success callback", name);                                                              \
55         }                                                                                                                          \
56                                                                                                                                    \
57         if (onFailureCallback == nullptr)                                                                                          \
58         {                                                                                                                          \
59             ChipLogDetail(Zcl, "%s: Missing failure callback", name);                                                              \
60         }                                                                                                                          \
61                                                                                                                                    \
62         return true;                                                                                                               \
63     }
64
65 #define GET_REPORT_CALLBACK(name)                                                                                                  \
66     Callback::Cancelable * onReportCallback = nullptr;                                                                             \
67     CHIP_ERROR err = gCallbacks.GetReportCallback(sourceId, endpointId, clusterId, attributeId, &onReportCallback);                \
68                                                                                                                                    \
69     if (CHIP_NO_ERROR != err)                                                                                                      \
70     {                                                                                                                              \
71         if (onReportCallback == nullptr)                                                                                           \
72         {                                                                                                                          \
73             ChipLogDetail(Zcl, "%s: Missing report callback", name);                                                               \
74         }                                                                                                                          \
75                                                                                                                                    \
76         return true;                                                                                                               \
77     }
78
79 void LogStatus(uint8_t status)
80 {
81     switch (status)
82     {
83     case EMBER_ZCL_STATUS_SUCCESS:
84         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_SUCCESS (0x%02x)", status);
85         break;
86     case EMBER_ZCL_STATUS_FAILURE:
87         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_FAILURE (0x%02x)", status);
88         break;
89     case EMBER_ZCL_STATUS_NOT_AUTHORIZED:
90         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_NOT_AUTHORIZED (0x%02x)", status);
91         break;
92     case EMBER_ZCL_STATUS_MALFORMED_COMMAND:
93         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_MALFORMED_COMMAND (0x%02x)", status);
94         break;
95     case EMBER_ZCL_STATUS_UNSUP_COMMAND:
96         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_CLUSTER_COMMAND (0x%02x)", status);
97         break;
98     case EMBER_ZCL_STATUS_UNSUP_GENERAL_COMMAND:
99         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_GENERAL_COMMAND (0x%02x)", status);
100         break;
101     case EMBER_ZCL_STATUS_UNSUP_MANUF_CLUSTER_COMMAND:
102         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_MANUF_CLUSTER_COMMAND (0x%02x)", status);
103         break;
104     case EMBER_ZCL_STATUS_UNSUP_MANUF_GENERAL_COMMAND:
105         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUP_MANUF_GENERAL_COMMAND (0x%02x)", status);
106         break;
107     case EMBER_ZCL_STATUS_INVALID_FIELD:
108         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_FIELD (0x%02x)", status);
109         break;
110     case EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE:
111         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE (0x%02x)", status);
112         break;
113     case EMBER_ZCL_STATUS_INVALID_VALUE:
114         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_VALUE (0x%02x)", status);
115         break;
116     case EMBER_ZCL_STATUS_READ_ONLY:
117         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_READ_ONLY (0x%02x)", status);
118         break;
119     case EMBER_ZCL_STATUS_INSUFFICIENT_SPACE:
120         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INSUFFICIENT_SPACE (0x%02x)", status);
121         break;
122     case EMBER_ZCL_STATUS_DUPLICATE_EXISTS:
123         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_DUPLICATE_EXISTS (0x%02x)", status);
124         break;
125     case EMBER_ZCL_STATUS_NOT_FOUND:
126         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_NOT_FOUND (0x%02x)", status);
127         break;
128     case EMBER_ZCL_STATUS_UNREPORTABLE_ATTRIBUTE:
129         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNREPORTABLE_ATTRIBUTE (0x%02x)", status);
130         break;
131     case EMBER_ZCL_STATUS_INVALID_DATA_TYPE:
132         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_DATA_TYPE (0x%02x)", status);
133         break;
134     case EMBER_ZCL_STATUS_INVALID_SELECTOR:
135         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_SELECTOR (0x%02x)", status);
136         break;
137     case EMBER_ZCL_STATUS_WRITE_ONLY:
138         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_WRITE_ONLY (0x%02x)", status);
139         break;
140     case EMBER_ZCL_STATUS_INCONSISTENT_STARTUP_STATE:
141         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INCONSISTENT_STARTUP_STATE (0x%02x)", status);
142         break;
143     case EMBER_ZCL_STATUS_DEFINED_OUT_OF_BAND:
144         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_DEFINED_OUT_Of_BAND (0x%02x)", status);
145         break;
146     case EMBER_ZCL_STATUS_ACTION_DENIED:
147         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_ACTION_DENIED (0x%02x)", status);
148         break;
149     case EMBER_ZCL_STATUS_TIMEOUT:
150         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_TIMEOUT (0x%02x)", status);
151         break;
152     case EMBER_ZCL_STATUS_ABORT:
153         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_ABORT (0x%02x)", status);
154         break;
155     case EMBER_ZCL_STATUS_INVALID_IMAGE:
156         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_INVALID_IMAGE (0x%02x)", status);
157         break;
158     case EMBER_ZCL_STATUS_WAIT_FOR_DATA:
159         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_WAIT_FOR_DATA (0x%02x)", status);
160         break;
161     case EMBER_ZCL_STATUS_NO_IMAGE_AVAILABLE:
162         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_NO_IMAGE_AVAILABLE (0x%02x)", status);
163         break;
164     case EMBER_ZCL_STATUS_REQUIRE_MORE_IMAGE:
165         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_REQUIRE_MORE_IMAGE (0x%02x)", status);
166         break;
167     case EMBER_ZCL_STATUS_HARDWARE_FAILURE:
168         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_HARDWARE_FAILURE (0x%02x)", status);
169         break;
170     case EMBER_ZCL_STATUS_SOFTWARE_FAILURE:
171         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_SOFTWARE_FAILURE (0x%02x)", status);
172         break;
173     case EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER:
174         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER (0x%02x)", status);
175         break;
176     case EMBER_ZCL_STATUS_LIMIT_REACHED:
177         ChipLogProgress(Zcl, "  status: EMBER_ZCL_STATUS_LIMIT_REACHED (0x%02x)", status);
178         break;
179     default:
180         ChipLogError(Zcl, "Unknow status: 0x%02x", status);
181         break;
182     }
183 }
184
185 // Singleton instance of the callbacks manager
186 app::CHIPDeviceCallbacksMgr & gCallbacks = app::CHIPDeviceCallbacksMgr::GetInstance();
187
188 bool emberAfDefaultResponseCallback(ClusterId clusterId, CommandId commandId, EmberAfStatus status)
189 {
190     ChipLogProgress(Zcl, "DefaultResponse:");
191     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
192     ChipLogProgress(Zcl, "  CommandId: 0x%02x", commandId);
193     LogStatus(status);
194
195     GET_RESPONSE_CALLBACKS("emberAfDefaultResponseCallback");
196     if (status == EMBER_ZCL_STATUS_SUCCESS)
197     {
198         Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
199         cb->mCall(cb->mContext);
200     }
201     else
202     {
203         Callback::Callback<DefaultFailureCallback> * cb = Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
204         cb->mCall(cb->mContext, static_cast<uint8_t>(status));
205     }
206
207     return true;
208 }
209
210 bool emberAfReadAttributesResponseCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen)
211 {
212     ChipLogProgress(Zcl, "ReadAttributesResponse:");
213     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
214
215     GET_RESPONSE_CALLBACKS("emberAfReadAttributesResponseCallback");
216
217     // struct readAttributeResponseRecord[]
218     while (messageLen)
219     {
220         CHECK_MESSAGE_LENGTH(2);
221         uint16_t attributeId = chip::Encoding::LittleEndian::Read16(message); // attribId
222         ChipLogProgress(Zcl, "  attributeId: 0x%04x", attributeId);
223
224         CHECK_MESSAGE_LENGTH(1);
225         uint8_t status = chip::Encoding::Read8(message); // zclStatus
226         LogStatus(status);
227
228         if (status == EMBER_ZCL_STATUS_SUCCESS)
229         {
230             CHECK_MESSAGE_LENGTH(1);
231             uint8_t attributeType = chip::Encoding::Read8(message);
232             ChipLogProgress(Zcl, "  attributeType: 0x%02x", attributeType);
233
234             switch (attributeType)
235             {
236                 case 0x00: // nodata / No data
237                 case 0x0A: // data24 / 24-bit data
238                 case 0x0C: // data40 / 40-bit data
239                 case 0x0D: // data48 / 48-bit data
240                 case 0x0E: // data56 / 56-bit data
241                 case 0x1A: // map24 / 24-bit bitmap
242                 case 0x1C: // map40 / 40-bit bitmap
243                 case 0x1D: // map48 / 48-bit bitmap
244                 case 0x1E: // map56 / 56-bit bitmap
245                 case 0x22: // uint24 / Unsigned 24-bit integer
246                 case 0x24: // uint40 / Unsigned 40-bit integer
247                 case 0x25: // uint48 / Unsigned 48-bit integer
248                 case 0x26: // uint56 / Unsigned 56-bit integer
249                 case 0x2A: // int24 / Signed 24-bit integer
250                 case 0x2C: // int40 / Signed 40-bit integer
251                 case 0x2D: // int48 / Signed 48-bit integer
252                 case 0x2E: // int56 / Signed 56-bit integer
253                 case 0x38: // semi / Semi-precision
254                 case 0x39: // single / Single precision
255                 case 0x3A: // double / Double precision
256                 case 0x48: // array / Array
257                 case 0x49: // struct / Structure
258                 case 0x50: // set / Set
259                 case 0x51: // bag / Bag
260                 case 0xE0: // ToD / Time of day
261                 {
262                     ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType);
263                     Callback::Callback<DefaultFailureCallback> * cb = Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
264                     cb->mCall(cb->mContext, EMBER_ZCL_STATUS_INVALID_VALUE);
265                     return true;
266                 }
267
268                 case 0x41: // octstr / Octet string
269                 case 0x42: // string / Character string
270                 {
271                     // Short Strings must contains at least one byte for the length
272                     CHECK_MESSAGE_LENGTH(1);
273                     uint8_t length = chip::Encoding::Read8(message);
274                     ChipLogProgress(Zcl, "  length: 0x%02x", length);
275
276                     // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length.
277                     if (length == 0xFF)
278                     {
279                         length = 0;
280                     }
281
282                     CHECK_MESSAGE_LENGTH(length);
283                     Callback::Callback<StringAttributeCallback> * cb = Callback::Callback<StringAttributeCallback>::FromCancelable(onSuccessCallback);
284                     cb->mCall(cb->mContext, chip::ByteSpan(message, length));
285                     break;
286                 }
287
288                 case 0x43: // octstr16 / Long octet string
289                 case 0x44: // string16 / Long character string
290                 {
291                     // Long Strings must contains at least two bytes for the length
292                     CHECK_MESSAGE_LENGTH(2);
293                     uint16_t length = chip::Encoding::LittleEndian::Read16(message);
294                     ChipLogProgress(Zcl, "  length: 0x%02x", length);
295
296                     // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length.
297                     if (length == 0xFFFF)
298                     {
299                         length = 0;
300                     }
301
302                     CHECK_MESSAGE_LENGTH(length);
303                     Callback::Callback<StringAttributeCallback> * cb = Callback::Callback<StringAttributeCallback>::FromCancelable(onSuccessCallback);
304                     cb->mCall(cb->mContext, chip::ByteSpan(message, length));
305                     break;
306                 }
307
308                 case 0x08: // data8 / 8-bit data
309                 case 0x18: // map8 / 8-bit bitmap
310                 case 0x20: // uint8 / Unsigned  8-bit integer
311                 case 0x30: // enum8 / 8-bit enumeration
312                 {
313                     CHECK_MESSAGE_LENGTH(1);
314                     uint8_t value = chip::Encoding::Read8(message);
315                     ChipLogProgress(Zcl, "  value: 0x%02x", value);
316
317                     Callback::Callback<Int8uAttributeCallback> * cb = Callback::Callback<Int8uAttributeCallback>::FromCancelable(onSuccessCallback);
318                     cb->mCall(cb->mContext, value);
319                     break;
320                 }
321
322                 case 0x09: // data16 / 16-bit data
323                 case 0x19: // map16 / 16-bit bitmap
324                 case 0x21: // uint16 / Unsigned 16-bit integer
325                 case 0x31: // enum16 / 16-bit enumeration
326                 case 0xE8: // clusterId / Cluster ID
327                 case 0xE9: // attribId / Attribute ID
328                 case 0xEA: // bacOID / BACnet OID
329                 case 0xF1: // key128 / 128-bit security key
330                 case 0xFF: // unk / Unknown
331                 {
332                     CHECK_MESSAGE_LENGTH(2);
333                     uint16_t value = chip::Encoding::LittleEndian::Read16(message);
334                     ChipLogProgress(Zcl, "  value: 0x%04x", value);
335
336                     Callback::Callback<Int16uAttributeCallback> * cb = Callback::Callback<Int16uAttributeCallback>::FromCancelable(onSuccessCallback);
337                     cb->mCall(cb->mContext, value);
338                     break;
339                 }
340
341                 case 0x0B: // data32 / 32-bit data
342                 case 0x1B: // map32 / 32-bit bitmap
343                 case 0x23: // uint32 / Unsigned 32-bit integer
344                 case 0xE1: // date / Date
345                 case 0xE2: // UTC / UTCTime
346                 {
347                     CHECK_MESSAGE_LENGTH(4);
348                     uint32_t value = chip::Encoding::LittleEndian::Read32(message);
349                     ChipLogProgress(Zcl, "  value: 0x%08x", value);
350
351                     Callback::Callback<Int32uAttributeCallback> * cb = Callback::Callback<Int32uAttributeCallback>::FromCancelable(onSuccessCallback);
352                     cb->mCall(cb->mContext, value);
353                     break;
354                 }
355
356                 case 0x0F: // data64 / 64-bit data
357                 case 0x1F: // map64 / 64-bit bitmap
358                 case 0x27: // uint64 / Unsigned 64-bit integer
359                 case 0xF0: // EUI64 / IEEE address
360                 {
361                     CHECK_MESSAGE_LENGTH(8);
362                     uint64_t value = chip::Encoding::LittleEndian::Read64(message);
363                     ChipLogProgress(Zcl, "  value: 0x%16x", value);
364
365                     Callback::Callback<Int64uAttributeCallback> * cb = Callback::Callback<Int64uAttributeCallback>::FromCancelable(onSuccessCallback);
366                     cb->mCall(cb->mContext, value);
367                     break;
368                 }
369
370                 case 0x10: // bool / Boolean
371                 {
372                     CHECK_MESSAGE_LENGTH(1);
373                     uint8_t value = chip::Encoding::Read8(message);
374                     ChipLogProgress(Zcl, "  value: %d", value);
375
376                     Callback::Callback<BooleanAttributeCallback> * cb = Callback::Callback<BooleanAttributeCallback>::FromCancelable(onSuccessCallback);
377                     cb->mCall(cb->mContext, value);
378                     break;
379                 }
380
381                 case 0x28: // int8 / Signed 8-bit integer
382                 {
383                     CHECK_MESSAGE_LENGTH(1);
384                     int8_t value = chip::CastToSigned(chip::Encoding::Read8(message));
385                     ChipLogProgress(Zcl, "  value: %" PRId8, value);
386
387                     Callback::Callback<Int8sAttributeCallback> * cb = Callback::Callback<Int8sAttributeCallback>::FromCancelable(onSuccessCallback);
388                     cb->mCall(cb->mContext, value);
389                     break;
390                 }
391
392                 case 0x29: // int16 / Signed 16-bit integer
393                 {
394                     CHECK_MESSAGE_LENGTH(2);
395                     int16_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read16(message));
396                     ChipLogProgress(Zcl, "  value: %" PRId16, value);
397
398                     Callback::Callback<Int16sAttributeCallback> * cb = Callback::Callback<Int16sAttributeCallback>::FromCancelable(onSuccessCallback);
399                     cb->mCall(cb->mContext, value);
400                     break;
401                 }
402
403                 case 0x2B: // int32 / Signed 32-bit integer
404                 {
405                     CHECK_MESSAGE_LENGTH(4);
406                     int32_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read32(message));
407                     ChipLogProgress(Zcl, "  value: %" PRId32, value);
408
409                     Callback::Callback<Int32sAttributeCallback> * cb = Callback::Callback<Int32sAttributeCallback>::FromCancelable(onSuccessCallback);
410                     cb->mCall(cb->mContext, value);
411                     break;
412                 }
413
414                 case 0x2F: // int64 / Signed 64-bit integer
415                 {
416                     CHECK_MESSAGE_LENGTH(8);
417                     int64_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read64(message));
418                     ChipLogProgress(Zcl, "  value: %" PRId64, value);
419
420                     Callback::Callback<Int64sAttributeCallback> * cb = Callback::Callback<Int64sAttributeCallback>::FromCancelable(onSuccessCallback);
421                     cb->mCall(cb->mContext, value);
422                     break;
423                 }
424             }
425         }
426         else
427         {
428             Callback::Callback<DefaultFailureCallback> * cb = Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
429             cb->mCall(cb->mContext, status);
430         }
431
432         // The current code is written matching the current API where there is a single attribute read 
433         // per read command. So if multiple attributes are read at the same time, something is wrong
434         // somewhere.
435         if (messageLen)
436         {
437             ChipLogError(Zcl, "Multiple attributes read at the same time. Something went wrong.");
438             break;
439         }
440     }
441
442     return true;
443 }
444
445 bool emberAfWriteAttributesResponseCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen)
446 {
447     ChipLogProgress(Zcl, "WriteAttributesResponse:");
448     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
449
450     GET_RESPONSE_CALLBACKS("emberAfWriteAttributesResponseCallback");
451
452     // struct writeAttributeResponseRecord[]
453     while (messageLen)
454     {
455         CHECK_MESSAGE_LENGTH(1);
456         uint8_t status = chip::Encoding::Read8(message); // zclStatus
457         LogStatus(status);
458
459         if (status == EMBER_ZCL_STATUS_SUCCESS)
460         {
461             Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
462             cb->mCall(cb->mContext);
463         }
464         else
465         {
466             CHECK_MESSAGE_LENGTH(2);
467             uint16_t attributeId = chip::Encoding::LittleEndian::Read16(message); // attribId
468             ChipLogProgress(Zcl, "  attributeId: 0x%04x", attributeId);
469
470             Callback::Callback<DefaultFailureCallback> * cb = Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
471             cb->mCall(cb->mContext, status);
472         }
473
474         // The current code is written matching the current API where there is a single attribute written
475         // per write command. So if multiple attributes are written at the same time, something is wrong
476         // somewhere.
477         if (messageLen)
478         {
479             ChipLogError(Zcl, "Multiple attributes written at the same time. Something went wrong.");
480             break;
481         }
482     }
483
484     return true;
485 }
486
487 bool emberAfConfigureReportingResponseCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen)
488 {
489     ChipLogProgress(Zcl, "ConfigureReportingResponseCallback:");
490     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
491
492     GET_RESPONSE_CALLBACKS("emberAfConfigureReportingResponseCallback");
493
494     // struct configureReportingResponseRecord[]
495     while (messageLen)
496     {
497         CHECK_MESSAGE_LENGTH(1);
498         uint8_t status = chip::Encoding::Read8(message); // zclStatus
499         LogStatus(status);
500
501         if (status == EMBER_ZCL_STATUS_SUCCESS)
502         {
503             Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
504             cb->mCall(cb->mContext);
505         }
506         else
507         {
508             CHECK_MESSAGE_LENGTH(1);
509             uint8_t direction = chip::Encoding::Read8(message); // reportingRole
510             ChipLogProgress(Zcl, "  direction: 0x%02x", direction);
511
512             CHECK_MESSAGE_LENGTH(2);
513             uint16_t attributeId = chip::Encoding::LittleEndian::Read16(message); // attribId
514             ChipLogProgress(Zcl, "  attributeId: 0x%04x", attributeId);
515
516             Callback::Callback<DefaultFailureCallback> * cb = Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
517             cb->mCall(cb->mContext, status);
518         }
519
520         // The current code is written matching the current API where there is a single attribute report 
521         // per configure command. So if multiple attributes are configured at the same time, something is wrong
522         // somewhere.
523         if (messageLen)
524         {
525             ChipLogError(Zcl, "Multiple attributes reports configured at the same time. Something went wrong.");
526             break;
527         }
528     }
529
530     return true;
531 }
532
533 bool emberAfReadReportingConfigurationResponseCallback(chip::ClusterId clusterId, uint8_t * message, uint16_t messageLen)
534 {
535     ChipLogProgress(Zcl, "ReadReportingConfigurationResponse:");
536     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
537
538     GET_RESPONSE_CALLBACKS("emberAfReadReportingConfigurationResponseCallback");
539
540     // struct readReportingConfigurationResponseRecord[]
541     while (messageLen)
542     {
543         CHECK_MESSAGE_LENGTH(1);
544         uint8_t direction = chip::Encoding::Read8(message); // reportingRole
545         ChipLogProgress(Zcl, "  direction: 0x%02x", direction);
546
547         CHECK_MESSAGE_LENGTH(2);
548         uint16_t attributeId = chip::Encoding::LittleEndian::Read16(message); // attribId
549         ChipLogProgress(Zcl, "  attributeId: 0x%04x", attributeId);
550
551         if (direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED)
552         {
553             CHECK_MESSAGE_LENGTH(1);
554             uint8_t attributeType = chip::Encoding::Read8(message); // zclType
555             ChipLogProgress(Zcl, "  attributeType: 0x%02x", attributeType);
556
557             CHECK_MESSAGE_LENGTH(2);
558             uint16_t minimumReportingInterval = chip::Encoding::LittleEndian::Read16(message); // uint16
559             ChipLogProgress(Zcl, "  minimumReportingInterval: %" PRIu16, minimumReportingInterval);
560
561             CHECK_MESSAGE_LENGTH(2);
562             uint16_t maximumReportingInterval = chip::Encoding::LittleEndian::Read16(message); // uint16
563             ChipLogProgress(Zcl, "  maximumReportingInterval: %" PRIu16, maximumReportingInterval);
564
565             // FIXME: unk is not supported yet.
566
567             Callback::Callback<ReadReportingConfigurationReportedCallback> * cb = Callback::Callback<ReadReportingConfigurationReportedCallback>::FromCancelable(onSuccessCallback);
568             cb->mCall(cb->mContext, minimumReportingInterval, maximumReportingInterval);
569         }
570         else
571         {
572             CHECK_MESSAGE_LENGTH(2);
573             uint16_t timeout = chip::Encoding::LittleEndian::Read16(message); // uint16
574             ChipLogProgress(Zcl, "  timeout: %" PRIu16, timeout);
575
576             Callback::Callback<ReadReportingConfigurationReceivedCallback> * cb = Callback::Callback<ReadReportingConfigurationReceivedCallback>::FromCancelable(onSuccessCallback);
577             cb->mCall(cb->mContext, timeout);
578         }
579     }
580
581     return true;
582 }
583
584 bool emberAfDiscoverAttributesResponseCallback(ClusterId clusterId, bool discoveryComplete, uint8_t * message, uint16_t messageLen,
585                                                bool extended)
586 {
587     ChipLogProgress(Zcl, "DiscoverAttributesResponse:");
588     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
589     ChipLogProgress(Zcl, "  discoveryComplete: %d", discoveryComplete);
590     ChipLogProgress(Zcl, "  extended: %d", extended);
591
592     GET_RESPONSE_CALLBACKS("emberAfDiscoverAttributesCallback");
593
594     // struct discoverAttributesResponseRecord[]
595     while (messageLen)
596     {
597         CHECK_MESSAGE_LENGTH(2);
598         uint16_t attributeId = chip::Encoding::LittleEndian::Read16(message); // attribId
599         ChipLogProgress(Zcl, "  attributeId: 0x%04x", attributeId);
600
601         CHECK_MESSAGE_LENGTH(1);
602         uint8_t attributeType = chip::Encoding::Read8(message); // zclType
603         ChipLogProgress(Zcl, "  attributeType: 0x%02x", attributeType);
604     }
605
606     Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
607     cb->mCall(cb->mContext);
608     return true;
609 }
610
611 bool emberAfDiscoverCommandsGeneratedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete,
612                                                       CommandId * commandIds, uint16_t commandIdCount)
613 {
614     ChipLogProgress(Zcl, "DiscoverCommandsGeneratedResponse:");
615     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
616     ChipLogProgress(Zcl, "  manufacturerCode: 0x%04x", manufacturerCode);
617     ChipLogProgress(Zcl, "  discoveryComplete: %d", discoveryComplete);
618     ChipLogProgress(Zcl, "  commandIdCount: %" PRIu16, commandIdCount);
619
620     for (uint16_t i = 0; i < commandIdCount; i++)
621     {
622         ChipLogProgress(Zcl, "  commandId: 0x%02x", commandIds++);
623     }
624
625     GET_RESPONSE_CALLBACKS("emberAfDiscoverCommandsGeneratedResponseCallback");
626     Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
627     cb->mCall(cb->mContext);
628     return true;
629 }
630
631 bool emberAfDiscoverCommandsReceivedResponseCallback(ClusterId clusterId, uint16_t manufacturerCode, bool discoveryComplete,
632                                                      CommandId * commandIds, uint16_t commandIdCount)
633 {
634     ChipLogProgress(Zcl, "DiscoverCommandsReceivedResponse:");
635     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
636     ChipLogProgress(Zcl, "  manufacturerCode: 0x%04x", manufacturerCode);
637     ChipLogProgress(Zcl, "  discoveryComplete: %d", discoveryComplete);
638     ChipLogProgress(Zcl, "  commandIdCount: %" PRIu16, commandIdCount);
639
640     for (uint16_t i = 0; i < commandIdCount; i++)
641     {
642         ChipLogProgress(Zcl, "  commandId: 0x%02x", commandIds++);
643     }
644
645     GET_RESPONSE_CALLBACKS("emberAfDiscoverCommandsGeneratedResponseCallback");
646     Callback::Callback<DefaultSuccessCallback> * cb = Callback::Callback<DefaultSuccessCallback>::FromCancelable(onSuccessCallback);
647     cb->mCall(cb->mContext);
648     return true;
649 }
650
651 {{#all_user_clusters}}
652 {{#if (isClient side) }}
653 {{#if (user_cluster_has_enabled_command name side)}}
654 {{#all_user_cluster_commands}}
655 {{#if (isStrEqual clusterName parent.name)}}
656 {{#if (isCommandAvailable parent.side incoming outgoing commandSource name)}}
657 {{#if (isStrEndsWith name "Response")}}
658 bool emberAf{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback({{#zcl_command_arguments}}{{asUnderlyingZclType type}} {{asSymbol label}}{{#unless (isLastElement index count)}}, {{/unless}}{{/zcl_command_arguments}})
659 {
660     ChipLogProgress(Zcl, "{{asCamelCased name false}}:");
661     {{#zcl_command_arguments}}
662     {{#if (isStrEqual label "status")}}
663     LogStatus(status);
664     {{else}}
665     ChipLogProgress(Zcl, "  {{asSymbol label}}: {{asPrintFormat type}}", {{asSymbol label}});
666     {{/if}}
667     {{/zcl_command_arguments}}
668
669     GET_RESPONSE_CALLBACKS("{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback");
670
671     {{#zcl_command_arguments}}
672     {{#if (isStrEqual label "status")}}
673     if (status != EMBER_ZCL_STATUS_SUCCESS)
674     {
675         Callback::Callback<DefaultFailureCallback> * cb = Callback::Callback<DefaultFailureCallback>::FromCancelable(onFailureCallback);
676         cb->mCall(cb->mContext, status);
677         return true;
678     }
679     {{/if}}
680     {{/zcl_command_arguments}}
681
682     Callback::Callback<{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback> * cb = Callback::Callback<{{asCamelCased parent.name false}}Cluster{{asCamelCased name false}}Callback>::FromCancelable(onSuccessCallback);
683     cb->mCall(cb->mContext{{#zcl_command_arguments}}{{#unless (isStrEqual label "status")}}, {{asSymbol label}}{{/unless}}{{/zcl_command_arguments}});
684     return true;
685 }
686
687 {{/if}}
688 {{/if}}
689 {{/if}}
690 {{/all_user_cluster_commands}}
691 {{/if}}
692 {{/if}}
693 {{/all_user_clusters}}
694
695 bool emberAfReportAttributesCallback(ClusterId clusterId, uint8_t * message, uint16_t messageLen)
696 {
697     ChipLogProgress(Zcl, "emberAfReportAttributeCallback:");
698     ChipLogProgress(Zcl, "  ClusterId: 0x%04x", clusterId);
699
700     NodeId sourceId = emberAfCurrentCommand()->source;
701     ChipLogProgress(Zcl, "  Source NodeId: %" PRIu64, sourceId);
702
703     EndpointId endpointId = emberAfCurrentCommand()->apsFrame->sourceEndpoint;
704     ChipLogProgress(Zcl, "  Source EndpointId: 0x%04x", endpointId);
705
706     // TODO onFailureCallback is just here because of the CHECK_MESSAGE_LENGTH macro. It needs to be removed.
707     Callback::Cancelable * onFailureCallback = nullptr;
708
709     while (messageLen)
710     {
711         CHECK_MESSAGE_LENGTH(2);
712         uint16_t attributeId = chip::Encoding::LittleEndian::Read16(message); // attribId
713         ChipLogProgress(Zcl, "  attributeId: 0x%04x", attributeId);
714
715         GET_REPORT_CALLBACK("emberAfReportAttributesCallback");
716
717         CHECK_MESSAGE_LENGTH(1);
718         uint8_t attributeType = chip::Encoding::Read8(message);
719         ChipLogProgress(Zcl, "  attributeType: 0x%02x", attributeType);
720
721         switch (attributeType)
722         {
723             case 0x00: // nodata / No data
724             case 0x0A: // data24 / 24-bit data
725             case 0x0C: // data40 / 40-bit data
726             case 0x0D: // data48 / 48-bit data
727             case 0x0E: // data56 / 56-bit data
728             case 0x1A: // map24 / 24-bit bitmap
729             case 0x1C: // map40 / 40-bit bitmap
730             case 0x1D: // map48 / 48-bit bitmap
731             case 0x1E: // map56 / 56-bit bitmap
732             case 0x22: // uint24 / Unsigned 24-bit integer
733             case 0x24: // uint40 / Unsigned 40-bit integer
734             case 0x25: // uint48 / Unsigned 48-bit integer
735             case 0x26: // uint56 / Unsigned 56-bit integer
736             case 0x2A: // int24 / Signed 24-bit integer
737             case 0x2C: // int40 / Signed 40-bit integer
738             case 0x2D: // int48 / Signed 48-bit integer
739             case 0x2E: // int56 / Signed 56-bit integer
740             case 0x38: // semi / Semi-precision
741             case 0x39: // single / Single precision
742             case 0x3A: // double / Double precision
743             case 0x48: // array / Array
744             case 0x49: // struct / Structure
745             case 0x50: // set / Set
746             case 0x51: // bag / Bag
747             case 0xE0: // ToD / Time of day
748             {
749                 ChipLogError(Zcl, "attributeType 0x%02x is not supported", attributeType);
750                 return true;
751             }
752
753             case 0x41: // octstr / Octet string
754             case 0x42: // string / Character string
755             {
756                 // Short Strings must contains at least one byte for the length
757                 CHECK_MESSAGE_LENGTH(1);
758                 uint8_t length = chip::Encoding::Read8(message);
759                 ChipLogProgress(Zcl, "  length: 0x%02x", length);
760
761                 // When the length is set to 0xFF, it represents a non-value. In this case the data field is zero length.
762                 if (length == 0xFF)
763                 {
764                     length = 0;
765                 }
766
767                 CHECK_MESSAGE_LENGTH(length);
768                 Callback::Callback<StringAttributeCallback> * cb = Callback::Callback<StringAttributeCallback>::FromCancelable(onReportCallback);
769                 cb->mCall(cb->mContext, chip::ByteSpan(message, length));
770                 break;
771             }
772
773             case 0x43: // octstr16 / Long octet string
774             case 0x44: // string16 / Long character string
775             {
776                 // Long Strings must contains at least two bytes for the length
777                 CHECK_MESSAGE_LENGTH(2);
778                 uint16_t length = chip::Encoding::LittleEndian::Read16(message);
779                 ChipLogProgress(Zcl, "  length: 0x%02x", length);
780
781                 // When the length is set to 0xFFFF, it represents a non-value. In this case the data field is zero length.
782                 if (length == 0xFFFF)
783                 {
784                     length = 0;
785                 }
786
787                 CHECK_MESSAGE_LENGTH(length);
788                 Callback::Callback<StringAttributeCallback> * cb = Callback::Callback<StringAttributeCallback>::FromCancelable(onReportCallback);
789                 cb->mCall(cb->mContext, chip::ByteSpan(message, length));
790                 break;
791             }
792
793             case 0x08: // data8 / 8-bit data
794             case 0x18: // map8 / 8-bit bitmap
795             case 0x20: // uint8 / Unsigned  8-bit integer
796             case 0x30: // enum8 / 8-bit enumeration
797             {
798                 CHECK_MESSAGE_LENGTH(1);
799                 uint8_t value = chip::Encoding::Read8(message);
800                 ChipLogProgress(Zcl, "  value: 0x%02x", value);
801
802                 Callback::Callback<Int8uAttributeCallback> * cb = Callback::Callback<Int8uAttributeCallback>::FromCancelable(onReportCallback);
803                 cb->mCall(cb->mContext, value);
804                 break;
805             }
806
807             case 0x09: // data16 / 16-bit data
808             case 0x19: // map16 / 16-bit bitmap
809             case 0x21: // uint16 / Unsigned 16-bit integer
810             case 0x31: // enum16 / 16-bit enumeration
811             case 0xE8: // clusterId / Cluster ID
812             case 0xE9: // attribId / Attribute ID
813             case 0xEA: // bacOID / BACnet OID
814             case 0xF1: // key128 / 128-bit security key
815             case 0xFF: // unk / Unknown
816             {
817                 CHECK_MESSAGE_LENGTH(2);
818                 uint16_t value = chip::Encoding::LittleEndian::Read16(message);
819                 ChipLogProgress(Zcl, "  value: 0x%04x", value);
820
821                 Callback::Callback<Int16uAttributeCallback> * cb = Callback::Callback<Int16uAttributeCallback>::FromCancelable(onReportCallback);
822                 cb->mCall(cb->mContext, value);
823                 break;
824             }
825
826             case 0x0B: // data32 / 32-bit data
827             case 0x1B: // map32 / 32-bit bitmap
828             case 0x23: // uint32 / Unsigned 32-bit integer
829             case 0xE1: // date / Date
830             case 0xE2: // UTC / UTCTime
831             {
832                 CHECK_MESSAGE_LENGTH(4);
833                 uint32_t value = chip::Encoding::LittleEndian::Read32(message);
834                 ChipLogProgress(Zcl, "  value: 0x%08x", value);
835
836                 Callback::Callback<Int32uAttributeCallback> * cb = Callback::Callback<Int32uAttributeCallback>::FromCancelable(onReportCallback);
837                 cb->mCall(cb->mContext, value);
838                 break;
839             }
840
841             case 0x0F: // data64 / 64-bit data
842             case 0x1F: // map64 / 64-bit bitmap
843             case 0x27: // uint64 / Unsigned 64-bit integer
844             case 0xF0: // EUI64 / IEEE address
845             {
846                 CHECK_MESSAGE_LENGTH(8);
847                 uint64_t value = chip::Encoding::LittleEndian::Read64(message);
848                 ChipLogProgress(Zcl, "  value: 0x%16x", value);
849
850                 Callback::Callback<Int64uAttributeCallback> * cb = Callback::Callback<Int64uAttributeCallback>::FromCancelable(onReportCallback);
851                 cb->mCall(cb->mContext, value);
852                 break;
853             }
854
855             case 0x10: // bool / Boolean
856             {
857                 CHECK_MESSAGE_LENGTH(1);
858                 uint8_t value = chip::Encoding::Read8(message);
859                 ChipLogProgress(Zcl, "  value: %d", value);
860
861                 Callback::Callback<BooleanAttributeCallback> * cb = Callback::Callback<BooleanAttributeCallback>::FromCancelable(onReportCallback);
862                 cb->mCall(cb->mContext, value);
863                 break;
864             }
865
866             case 0x28: // int8 / Signed 8-bit integer
867             {
868                 CHECK_MESSAGE_LENGTH(1);
869                 int8_t value = chip::CastToSigned(chip::Encoding::Read8(message));
870                 ChipLogProgress(Zcl, "  value: %" PRId8, value);
871
872                 Callback::Callback<Int8sAttributeCallback> * cb = Callback::Callback<Int8sAttributeCallback>::FromCancelable(onReportCallback);
873                 cb->mCall(cb->mContext, value);
874                 break;
875             }
876
877             case 0x29: // int16 / Signed 16-bit integer
878             {
879                 CHECK_MESSAGE_LENGTH(2);
880                 int16_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read16(message));
881                 ChipLogProgress(Zcl, "  value: %" PRId16, value);
882
883                 Callback::Callback<Int16sAttributeCallback> * cb = Callback::Callback<Int16sAttributeCallback>::FromCancelable(onReportCallback);
884                 cb->mCall(cb->mContext, value);
885                 break;
886             }
887
888             case 0x2B: // int32 / Signed 32-bit integer
889             {
890                 CHECK_MESSAGE_LENGTH(4);
891                 int32_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read32(message));
892                 ChipLogProgress(Zcl, "  value: %" PRId32, value);
893
894                 Callback::Callback<Int32sAttributeCallback> * cb = Callback::Callback<Int32sAttributeCallback>::FromCancelable(onReportCallback);
895                 cb->mCall(cb->mContext, value);
896                 break;
897             }
898
899             case 0x2F: // int64 / Signed 64-bit integer
900             {
901                 CHECK_MESSAGE_LENGTH(8);
902                 int64_t value = chip::CastToSigned(chip::Encoding::LittleEndian::Read64(message));
903                 ChipLogProgress(Zcl, "  value: %" PRId64, value);
904
905                 Callback::Callback<Int64sAttributeCallback> * cb = Callback::Callback<Int64sAttributeCallback>::FromCancelable(onReportCallback);
906                 cb->mCall(cb->mContext, value);
907                 break;
908             }
909         }
910     }
911
912     return true;
913 }