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