3 * Copyright (c) 2020-2021 Project CHIP Authors
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 * Copyright (c) 2020 Silicon Labs
22 * Licensed under the Apache License, Version 2.0 (the "License");
23 * you may not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
26 * http://www.apache.org/licenses/LICENSE-2.0
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
34 /***************************************************************************/
37 * @brief The master include file for the Ember
38 *ApplicationFramework API.
39 *******************************************************************************
40 ******************************************************************************/
43 * @addtogroup af Zigbee Application Framework API Reference
44 * This documentation describes the application programming interface (API)
45 * for the Zigbee Application Framework.
46 * The file af.h is the master include file for the Zigbee Application
53 #ifndef CONFIGURATION_HEADER
54 #define CONFIGURATION_HEADER "config.h"
56 #include CONFIGURATION_HEADER
59 // Includes needed for ember related functions for the EZSP host
60 #include "app/util/ezsp/ezsp-protocol.h"
61 #include "app/util/ezsp/ezsp-utils.h"
62 #include "app/util/ezsp/ezsp.h"
63 #include "app/util/ezsp/serial-interface.h"
64 #include "stack/include/ember-random-api.h"
65 #include "stack/include/ember-types.h"
66 #include "stack/include/error.h"
71 #include "client-api.h"
72 #include "debug-printing.h"
73 #include "ember-print.h"
75 /** @name Attribute Storage */
79 * @brief locate attribute metadata
81 * Function returns pointer to the attribute metadata structure,
82 * or NULL if attribute was not found.
84 * @param endpoint Zigbee endpoint number.
85 * @param cluster Cluster ID of the sought cluster.
86 * @param attribute Attribute ID of the sought attribute.
87 * @param mask CLUSTER_MASK_SERVER or CLUSTER_MASK_CLIENT
89 * @return Returns pointer to the attribute metadata location.
91 EmberAfAttributeMetadata * emberAfLocateAttributeMetadata(chip::EndpointId endpoint, chip::ClusterId clusterId,
92 chip::AttributeId attributeId, uint8_t mask, uint16_t manufacturerCode);
94 #ifdef DOXYGEN_SHOULD_SKIP_THIS
95 /** @brief Returns true if the attribute exists. */
96 bool emberAfContainsAttribute(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId, uint8_t mask,
97 uint16_t manufacturerCode);
99 #define emberAfContainsAttribute(endpoint, clusterId, attributeId, mask, manufacturerCode) \
100 (emberAfLocateAttributeMetadata(endpoint, clusterId, attributeId, mask, manufacturerCode) != NULL)
104 * @brief Returns true if endpoint contains a cluster, checking for mfg code.
106 * This function returns true regardless of whether
107 * the endpoint contains server, client or both.
108 * For standard libraries (when ClusterId < FC00),
109 * the manufacturerCode is ignored.
111 bool emberAfContainsClusterWithMfgCode(chip::EndpointId endpoint, chip::ClusterId clusterId, uint16_t manufacturerCode);
114 * @brief Returns true if endpoint contains the ZCL cluster with specified id.
116 * This function returns true regardless of whether
117 * the endpoint contains server, client or both in the Zigbee cluster Library.
118 * This wraps emberAfContainsClusterWithMfgCode with
119 * manufacturerCode = EMBER_AF_NULL_MANUFACTURER_CODE
120 * If this function is used with a manufacturer specific clusterId
121 * then this will return the first cluster that it finds in the Cluster table.
122 * and will not return any other clusters that share that id.
124 bool emberAfContainsCluster(chip::EndpointId endpoint, chip::ClusterId clusterId);
127 * @brief Returns true if endpoint has cluster server, checking for mfg code.
129 * This function returns true if
130 * the endpoint contains server of a given cluster.
131 * For standard librarys (when ClusterId < FC00), the manufacturerCode is ignored.
133 bool emberAfContainsServerWithMfgCode(chip::EndpointId endpoint, chip::ClusterId clusterId, uint16_t manufacturerCode);
136 * @brief Returns true if endpoint contains the ZCL server with specified id.
138 * This function returns true if
139 * the endpoint contains server of a given cluster.
140 * This wraps emberAfContainsServer with
141 * manufacturerCode = EMBER_AF_NULL_MANUFACTURER_CODE
142 * If this function is used with a manufacturer specific clusterId
143 * then this will return the first cluster that it finds in the Cluster table.
144 * and will not return any other clusters that share that id.
146 bool emberAfContainsServer(chip::EndpointId endpoint, chip::ClusterId clusterId);
149 * @brief Returns true if endpoint contains cluster client.
151 * This function returns true if
152 * the endpoint contains client of a given cluster.
153 * For standard library clusters (when ClusterId < FC00),
154 * the manufacturerCode is ignored.
156 bool emberAfContainsClientWithMfgCode(chip::EndpointId endpoint, chip::ClusterId clusterId, uint16_t manufacturerCode);
159 * @brief Returns true if endpoint contains the ZCL client with specified id.
161 * This function returns true if
162 * the endpoint contains client of a given cluster.
163 * This wraps emberAfContainsClient with
164 * manufacturerCode = EMBER_AF_NULL_MANUFACTURER_CODE
165 * If this function is used with a manufacturer specific clusterId
166 * then this will return the first cluster that it finds in the Cluster table.
167 * and will not return any other clusters that share that id.
169 bool emberAfContainsClient(chip::EndpointId endpoint, chip::ClusterId clusterId);
172 * @brief write an attribute, performing all the checks.
174 * This function will attempt to write the attribute value from
175 * the provided pointer. This function will only check that the
176 * attribute exists. If it does it will write the value into
177 * the attribute table for the given attribute.
179 * This function will not check to see if the attribute is
180 * writable since the read only / writable characteristic
181 * of an attribute only pertains to external devices writing
182 * over the air. Because this function is being called locally
183 * it assumes that the device knows what it is doing and has permission
184 * to perform the given operation.
186 * @see emberAfWriteClientAttribute, emberAfWriteServerAttribute,
187 * emberAfWriteManufacturerSpecificClientAttribute,
188 * emberAfWriteManufacturerSpecificServerAttribute
190 EmberAfStatus emberAfWriteAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t mask,
191 uint8_t * dataPtr, EmberAfAttributeType dataType);
194 * @brief write a cluster server attribute.
196 * This function is the same as emberAfWriteAttribute
197 * except that it saves having to pass the cluster mask.
198 * This is useful for code savings since write attribute
199 * is used frequently throughout the framework
201 * @see emberAfWriteClientAttribute,
202 * emberAfWriteManufacturerSpecificClientAttribute,
203 * emberAfWriteManufacturerSpecificServerAttribute
205 EmberAfStatus emberAfWriteServerAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID,
206 uint8_t * dataPtr, EmberAfAttributeType dataType);
209 * @brief write a cluster client attribute.
211 * This function is the same as emberAfWriteAttribute
212 * except that it saves having to pass the cluster mask.
213 * This is useful for code savings since write attribute
214 * is used frequently throughout the framework
216 * @see emberAfWriteServerAttribute,
217 * emberAfWriteManufacturerSpecificClientAttribute,
218 * emberAfWriteManufacturerSpecificServerAttribute
220 EmberAfStatus emberAfWriteClientAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID,
221 uint8_t * dataPtr, EmberAfAttributeType dataType);
224 * @brief write a manufacturer specific server attribute.
226 * This function is the same as emberAfWriteAttribute
227 * except that it saves having to pass the cluster mask
228 * and allows passing of a manufacturer code.
229 * This is useful for code savings since write attribute
230 * is used frequently throughout the framework
232 * @see emberAfWriteClientAttribute, emberAfWriteServerAttribute,
233 * emberAfWriteManufacturerSpecificClientAttribute
235 EmberAfStatus emberAfWriteManufacturerSpecificServerAttribute(chip::EndpointId endpoint, chip::ClusterId cluster,
236 chip::AttributeId attributeID, uint16_t manufacturerCode,
237 uint8_t * dataPtr, EmberAfAttributeType dataType);
240 * @brief write a manufacturer specific client attribute.
242 * This function is the same as emberAfWriteAttribute
243 * except that it saves having to pass the cluster mask.
244 * and allows passing of a manufacturer code.
245 * This is useful for code savings since write attribute
246 * is used frequently throughout the framework
248 * @see emberAfWriteClientAttribute, emberAfWriteServerAttribute,
249 * emberAfWriteManufacturerSpecificServerAttribute
251 EmberAfStatus emberAfWriteManufacturerSpecificClientAttribute(chip::EndpointId endpoint, chip::ClusterId cluster,
252 chip::AttributeId attributeID, uint16_t manufacturerCode,
253 uint8_t * dataPtr, EmberAfAttributeType dataType);
256 * @brief Function that test the success of attribute write.
258 * This function returns success if attribute write would be successful.
259 * It does not actually write anything, just validates for read-only and
262 * @param endpoint Zigbee endpoint number
263 * @param cluster Cluster ID of the sought cluster.
264 * @param attribute Attribute ID of the sought attribute.
265 * @param mask CLUSTER_MASK_SERVER or CLUSTER_MASK_CLIENT
266 * @param buffer Location where attribute will be written from.
267 * @param dataType ZCL attribute type.
269 EmberAfStatus emberAfVerifyAttributeWrite(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID,
270 uint8_t mask, uint16_t manufacturerCode, uint8_t * dataPtr,
271 EmberAfAttributeType dataType);
274 * @brief Read the attribute value, performing all the checks.
276 * This function will attempt to read the attribute and store
277 * it into the pointer. It will also read the data type.
278 * Both dataPtr and dataType may be NULL, signifying that either
279 * value or type is not desired.
281 * @see emberAfReadClientAttribute, emberAfReadServerAttribute,
282 * emberAfReadManufacturerSpecificClientAttribute,
283 * emberAfReadManufacturerSpecificServerAttribute
285 EmberAfStatus emberAfReadAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID, uint8_t mask,
286 uint8_t * dataPtr, uint8_t readLength, EmberAfAttributeType * dataType);
289 * @brief Read the server attribute value, performing all the checks.
291 * This function will attempt to read the attribute and store
292 * it into the pointer. It will also read the data type.
293 * Both dataPtr and dataType may be NULL, signifying that either
294 * value or type is not desired.
296 * @see emberAfReadClientAttribute,
297 * emberAfReadManufacturerSpecificClientAttribute,
298 * emberAfReadManufacturerSpecificServerAttribute
300 EmberAfStatus emberAfReadServerAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID,
301 uint8_t * dataPtr, uint8_t readLength);
304 * @brief Read the client attribute value, performing all the checks.
306 * This function will attempt to read the attribute and store
307 * it into the pointer. It will also read the data type.
308 * Both dataPtr and dataType may be NULL, signifying that either
309 * value or type is not desired.
311 * @see emberAfReadServerAttribute,
312 * emberAfReadManufacturerSpecificClientAttribute,
313 * emberAfReadManufacturerSpecificServerAttribute
315 EmberAfStatus emberAfReadClientAttribute(chip::EndpointId endpoint, chip::ClusterId cluster, chip::AttributeId attributeID,
316 uint8_t * dataPtr, uint8_t readLength);
319 * @brief Read the manufacturer-specific server attribute value, performing all checks.
321 * This function will attempt to read the attribute and store
322 * it into the pointer. It will also read the data type.
323 * Both dataPtr and dataType may be NULL, signifying that either
324 * value or type is not desired.
326 * @see emberAfReadClientAttribute, emberAfReadServerAttribute,
327 * emberAfReadManufacturerSpecificClientAttribute
329 EmberAfStatus emberAfReadManufacturerSpecificServerAttribute(chip::EndpointId endpoint, chip::ClusterId cluster,
330 chip::AttributeId attributeID, uint16_t manufacturerCode,
331 uint8_t * dataPtr, uint8_t readLength);
334 * @brief Read the manufacturer-specific client attribute value, performing all checks.
336 * This function will attempt to read the attribute and store
337 * it into the pointer. It will also read the data type.
338 * Both dataPtr and dataType may be NULL, signifying that either
339 * value or type is not desired.
341 * @see emberAfReadClientAttribute, emberAfReadServerAttribute,
342 * emberAfReadManufacturerSpecificServerAttribute
344 EmberAfStatus emberAfReadManufacturerSpecificClientAttribute(chip::EndpointId endpoint, chip::ClusterId cluster,
345 chip::AttributeId attributeID, uint16_t manufacturerCode,
346 uint8_t * dataPtr, uint8_t readLength);
349 * @brief this function returns the size of the ZCL data in bytes.
351 * @param dataType Zcl data type
352 * @return size in bytes or 0 if invalid data type
354 uint8_t emberAfGetDataSize(uint8_t dataType);
357 * @brief macro that returns true if the cluster is in the manufacturer specific range
359 * @param cluster EmberAfCluster* to consider
361 #define emberAfClusterIsManufacturerSpecific(cluster) ((cluster)->clusterId >= 0xFC00)
364 * @brief macro that returns true if attribute is read only.
366 * @param metadata EmberAfAttributeMetadata* to consider.
368 #define emberAfAttributeIsReadOnly(metadata) (((metadata)->mask & ATTRIBUTE_MASK_WRITABLE) == 0)
371 * @brief macro that returns true if client attribute, and false if server.
373 * @param metadata EmberAfAttributeMetadata* to consider.
375 #define emberAfAttributeIsClient(metadata) (((metadata)->mask & ATTRIBUTE_MASK_CLIENT) != 0)
378 * @brief macro that returns true if attribute is saved to token.
380 * @param metadata EmberAfAttributeMetadata* to consider.
382 #define emberAfAttributeIsTokenized(metadata) (((metadata)->mask & ATTRIBUTE_MASK_TOKENIZE) != 0)
385 * @brief macro that returns true if attribute is saved in external storage.
387 * @param metadata EmberAfAttributeMetadata* to consider.
389 #define emberAfAttributeIsExternal(metadata) (((metadata)->mask & ATTRIBUTE_MASK_EXTERNAL_STORAGE) != 0)
392 * @brief macro that returns true if attribute is a singleton
394 * @param metadata EmberAfAttributeMetadata* to consider.
396 #define emberAfAttributeIsSingleton(metadata) (((metadata)->mask & ATTRIBUTE_MASK_SINGLETON) != 0)
399 * @brief macro that returns true if attribute is manufacturer specific
401 * @param metadata EmberAfAttributeMetadata* to consider.
403 #define emberAfAttributeIsManufacturerSpecific(metadata) (((metadata)->mask & ATTRIBUTE_MASK_MANUFACTURER_SPECIFIC) != 0)
406 * @brief macro that returns size of attribute in bytes.
408 * @param metadata EmberAfAttributeMetadata* to consider.
410 #define emberAfAttributeSize(metadata) ((metadata)->size)
412 #if !defined(DOXYGEN_SHOULD_SKIP_THIS)
413 // master array of all defined endpoints
414 extern EmberAfDefinedEndpoint emAfEndpoints[];
418 * @brief Macro that takes index of endpoint, and returns Zigbee endpoint
420 chip::EndpointId emberAfEndpointFromIndex(uint8_t index);
423 * Returns the index of a given endpoint
425 uint8_t emberAfIndexFromEndpoint(chip::EndpointId endpoint);
428 * Returns the index of a given endpoint; Does not ignore disabled endpoints
430 uint8_t emberAfIndexFromEndpointIncludingDisabledEndpoints(chip::EndpointId endpoint);
433 * Returns the endpoint index within a given cluster (Client-side),
434 * looking only for standard clusters.
436 uint8_t emberAfFindClusterClientEndpointIndex(chip::EndpointId endpoint, chip::ClusterId clusterId);
439 * Returns the endpoint index within a given cluster (Server-side),
440 * looking only for standard clusters.
442 uint8_t emberAfFindClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId clusterId);
445 * @brief Macro that takes index of endpoint, and returns device Id for it
447 #define emberAfDeviceIdFromIndex(index) (emAfEndpoints[(index)].deviceId)
450 * @brief Macro that takes index of endpoint, and returns device version for it
452 #define emberAfDeviceVersionFromIndex(index) (emAfEndpoints[(index)].deviceVersion)
455 * @brief Macro that takes index of endpoint, and returns network index for it
457 #define emberAfNetworkIndexFromEndpointIndex(index) (emAfEndpoints[(index)].networkIndex)
460 * @brief Macro that returns the primary endpoint.
462 #define emberAfPrimaryEndpoint() (emAfEndpoints[0].endpoint)
465 * @brief Returns the total number of endpoints (dynamic and pre-compiled).
467 uint8_t emberAfEndpointCount(void);
470 * @brief Returns the number of pre-compiled endpoints.
472 uint8_t emberAfFixedEndpointCount(void);
475 * Data types are either analog or discrete. This makes a difference for
476 * some of the ZCL global commands
480 EMBER_AF_DATA_TYPE_ANALOG = 0,
481 EMBER_AF_DATA_TYPE_DISCRETE = 1,
482 EMBER_AF_DATA_TYPE_NONE = 2
486 * @brief Returns the type of the attribute, either ANALOG, DISCRETE or NONE
488 uint8_t emberAfGetAttributeAnalogOrDiscreteType(uint8_t dataType);
491 *@brief Returns true if type is signed, false otherwise.
493 bool emberAfIsTypeSigned(EmberAfAttributeType dataType);
496 * @brief Function that extracts a 64-bit integer from the message buffer
498 uint64_t emberAfGetInt64u(const uint8_t * message, uint16_t currentIndex, uint16_t msgLen);
501 * @brief Function that extracts a 32-bit integer from the message buffer
503 uint32_t emberAfGetInt32u(const uint8_t * message, uint16_t currentIndex, uint16_t msgLen);
506 * @brief Function that extracts a 24-bit integer from the message buffer
508 uint32_t emberAfGetInt24u(const uint8_t * message, uint16_t currentIndex, uint16_t msgLen);
511 * @brief Function that extracts a 16-bit integer from the message buffer
513 uint16_t emberAfGetInt16u(const uint8_t * message, uint16_t currentIndex, uint16_t msgLen);
515 * @brief Function that extracts a ZCL string from the message buffer
517 uint8_t * emberAfGetString(uint8_t * message, uint16_t currentIndex, uint16_t msgLen);
519 * @brief Function that extracts a ZCL long string from the message buffer
521 uint8_t * emberAfGetLongString(uint8_t * message, uint16_t currentIndex, uint16_t msgLen);
523 * @brief Function that extracts a ZCL Date from the message buffer and returns it
524 * in the given destination. Returns the number of bytes copied.
526 uint8_t emberAfGetDate(uint8_t * message, uint16_t currentIndex, uint16_t msgLen, EmberAfDate * destination);
529 * @brief Macro for consistency, that extracts single byte out of the message
531 #define emberAfGetInt8u(message, currentIndex, msgLen) message[currentIndex]
534 * @brief Macro for consistency that copies a uint8_t from variable into buffer.
536 #define emberAfCopyInt8u(data, index, x) (data[index] = (x))
538 * @brief function that copies a uint16_t value into a buffer
540 void emberAfCopyInt16u(uint8_t * data, uint16_t index, uint16_t x);
542 * @brief function that copies a uint24_t value into a buffer
544 void emberAfCopyInt24u(uint8_t * data, uint16_t index, uint32_t x);
546 * @brief function that copies a uint32_t value into a buffer
548 void emberAfCopyInt32u(uint8_t * data, uint16_t index, uint32_t x);
550 * @brief Function that copies a ZCL string type into a buffer. The size
551 * parameter should indicate the maximum number of characters to copy to the
552 * destination buffer not including the length byte.
554 void emberAfCopyString(uint8_t * dest, const uint8_t * src, uint8_t size);
556 * @brief Function that copies a ZCL long string into a buffer. The size
557 * parameter should indicate the maximum number of characters to copy to the
558 * destination buffer not including the length bytes.
560 void emberAfCopyLongString(uint8_t * dest, const uint8_t * src, uint16_t size);
562 * @brief Function that determines the length of a zigbee Cluster Library string
563 * (where the first byte is assumed to be the length).
565 uint8_t emberAfStringLength(const uint8_t * buffer);
567 * @brief Function that determines the length of a zigbee Cluster Library long string.
568 * (where the first two bytes are assumed to be the length).
570 uint16_t emberAfLongStringLength(const uint8_t * buffer);
573 * @brief Function that determines the size of a zigbee Cluster Library
574 * attribute value (where the attribute could be non-string, string, or long
575 * string). For strings, the size includes the length of the string plus the
576 * number of the string's length prefix byte(s).
578 uint16_t emberAfAttributeValueSize(EmberAfAttributeType dataType, const uint8_t * buffer);
580 /** @} END Attribute Storage */
582 /** @name Device Control */
586 * @brief Function that checks if endpoint is enabled.
588 * This function returns true if device at a given endpoint is
589 * enabled. At startup all endpoints are enabled.
591 * @param endpoint Zigbee endpoint number
593 bool emberAfIsDeviceEnabled(chip::EndpointId endpoint);
596 * @brief Function that checks if endpoint is identifying
598 * This function returns true if device at a given endpoint is
601 * @param endpoint Zigbee endpoint number
603 bool emberAfIsDeviceIdentifying(chip::EndpointId endpoint);
606 * @brief Function that enables or disables an endpoint.
608 * By calling this function, you turn off all processing of incoming traffic
609 * for a given endpoint.
611 * @param endpoint Zigbee endpoint number
613 void emberAfSetDeviceEnabled(chip::EndpointId endpoint, bool enabled);
615 /** @} END Device Control */
617 /** @name Miscellaneous */
621 * @brief Enable/disable endpoints
623 bool emberAfEndpointEnableDisable(chip::EndpointId endpoint, bool enable);
626 * @brief Determine if an endpoint at the specified index is enabled or disabled
628 bool emberAfEndpointIndexIsEnabled(uint8_t index);
631 * @brief Returns true if a given ZCL data type is a string type.
633 * You should use this function if you need to perform a different
634 * memory operation on a certain attribute because it is a string type.
635 * Since ZCL strings carry length as the first byte(s), it is often required
636 * to treat them differently than regular data types.
638 * @return true if data type is a string.
640 bool emberAfIsThisDataTypeAStringType(EmberAfAttributeType dataType);
642 /** @brief Returns true if the given attribute type is a string. */
643 bool emberAfIsStringAttributeType(EmberAfAttributeType attributeType);
645 /** @brief Returns true if the given attribute type is a long string. */
646 bool emberAfIsLongStringAttributeType(EmberAfAttributeType attributeType);
649 * @brief The mask applied by ::emberAfNextSequence when generating ZCL
652 #define EMBER_AF_ZCL_SEQUENCE_MASK 0x7F
655 * @brief The mask applied to generated message tags used by the framework when sending messages via EZSP.
656 * Customers who call ezspSend functions directly must use message tags outside this mask
658 #define EMBER_AF_MESSAGE_TAG_MASK 0x7F
661 * @brief Increments the ZCL sequence number and returns the value.
663 * ZCL messages have sequence numbers so that they can be matched up with other
664 * messages in the transaction. To avoid conflicts with sequence numbers
665 * generated independently by the application, this API returns sequence
666 * numbers with the high bit clear. If the application generates its own
667 * sequence numbers, it should use numbers with the high bit set.
669 * @return The next ZCL sequence number.
671 uint8_t emberAfNextSequence(void);
674 * @brief Retrieves the last sequence number that was used.
677 uint8_t emberAfGetLastSequenceNumber(void);
680 * @brief Simple integer comparison function.
681 * Compares two values of a known length as integers.
682 * Signed integer comparison are supported for numbers with length of
684 * The integers are in native endianness.
686 * @return -1, if val1 is smaller
687 * 0, if they are the same or if two negative numbers with length
688 * greater than 4 is being compared
689 * 1, if val2 is smaller.
691 int8_t emberAfCompareValues(uint8_t * val1, uint8_t * val2, uint8_t len, bool signedNumber);
694 * @brief populates the passed EUI64 with the local EUI64 MAC address.
696 void emberAfGetEui64(EmberEUI64 returnEui64);
699 // Normally this is provided by the stack code, but on the host
700 // it is provided by the application code.
701 void emberReverseMemCopy(uint8_t * dest, const uint8_t * src, uint16_t length);
705 * @brief Returns the node ID of the local node.
707 EmberNodeId emberAfGetNodeId(void);
709 #if defined(DOXYGEN_SHOULD_SKIP_THIS) || defined(EZSP_HOST)
711 * @brief Generates a random key (link, network, or master).
713 EmberStatus emberAfGenerateRandomKey(EmberKeyData * result);
715 #define emberAfGenerateRandomKey(result) emberGenerateRandomKey(result)
719 * @brief Returns the PAN ID of the local node.
721 EmberPanId emberAfGetPanId(void);
724 * @brief Returns the radioChannel of the current network
726 uint8_t emberAfGetRadioChannel(void);
729 * @brief Returns a binding index that matches the current incoming message, if
732 uint8_t emberAfGetBindingIndex(void);
735 * @brief Returns an address index that matches the current incoming message,
738 uint8_t emberAfGetAddressIndex(void);
741 * @brief Returns the current network state. This call caches the results
742 * on the host to prevent frequent EZSP transactions.
744 EmberNetworkStatus emberAfNetworkState(void);
747 * @brief Get this node's radio channel for the current network.
749 uint8_t emberAfGetRadioChannel(void);
752 * @brief Returns the current network parameters.
754 EmberStatus emberAfGetNetworkParameters(EmberNodeType * nodeType, EmberNetworkParameters * parameters);
757 * @brief Returns the current node type.
759 EmberStatus emberAfGetNodeType(EmberNodeType * nodeType);
763 #define EMBER_AF_REJOIN_DUE_TO_END_DEVICE_MOVE 0xA0
764 #define EMBER_AF_REJOIN_DUE_TO_TC_KEEPALIVE_FAILURE 0xA1
765 #define EMBER_AF_REJOIN_DUE_TO_CLI_COMMAND 0xA2
766 #define EMBER_AF_REJOIN_DUE_TO_WWAH_CONNECTIVITY_MANAGER 0xA3
768 #define EMBER_AF_REJOIN_FIRST_REASON EMBER_AF_REJOIN_DUE_TO_END_DEVICE_MOVE
769 #define EMBER_AF_REJOIN_LAST_REASON EMBER_AF_REJOIN_DUE_TO_END_DEVICE_MOVE
772 * @brief Enables local permit join and optionally broadcasts the ZDO
773 * Mgmt_Permit_Join_req message. This API can be called from any device
774 * type and still return EMBER_SUCCESS. If the API is called from an
775 * end device, the permit association bit will just be left off.
777 * @param duration the duration that the permit join bit will remain on
778 * and other devices will be able to join the current network.
779 * @param broadcastMgmtPermitJoin whether or not to broadcast the ZDO
780 * Mgmt_Permit_Join_req message.
782 * @returns status of whether or not permit join was enabled.
784 EmberStatus emberAfPermitJoin(uint8_t duration, bool broadcastMgmtPermitJoin);
786 #ifdef DOXYGEN_SHOULD_SKIP_THIS
788 * @brief Enables local permit join and broadcasts the ZDO
789 * Mgmt_Permit_Join_req message. This API can be called from any device
790 * type and still return EMBER_SUCCESS. If the API is called from an
791 * end device, the permit association bit will just be left off.
793 * @param duration the duration that the permit join bit will remain on
794 * and other devices will be able to join the current network.
796 * @returns status of whether or not permit join was enabled.
798 EmberStatus emberAfBroadcastPermitJoin(uint8_t duration);
800 #define emberAfBroadcastPermitJoin(duration) emberAfPermitJoin((duration), true)
803 /** @} END Miscellaneous */
805 /** @name Sleep Control */
809 * @brief A function used to add a task to the task register.
811 #define emberAfAddToCurrentAppTasks(x) emberAfAddToCurrentAppTasksCallback(x)
814 * @brief A function used to remove a task from the task register.
816 #define emberAfRemoveFromCurrentAppTasks(x) emberAfRemoveFromCurrentAppTasksCallback(x)
819 * @brief A macro used to retrieve the bitmask of all application
820 * frameowrk tasks currently in progress. This can be useful for debugging if
821 * some task is holding the device out of hibernation.
823 #define emberAfCurrentAppTasks() emberAfGetCurrentAppTasksCallback()
826 * @brief a function used to run the application framework's
827 * event mechanism. This function passes the application
828 * framework's event tables to the ember stack's event
831 void emberAfRunEvents(void);
834 * @brief Friendly define for use in the scheduling or canceling client events
835 * with emberAfScheduleClusterTick() and emberAfDeactivateClusterTick().
837 #define EMBER_AF_CLIENT_CLUSTER_TICK true
840 * @brief Friendly define for use in the scheduling or canceling server events
841 * with emberAfScheduleClusterTick() and emberAfDeactivateClusterTick().
843 #define EMBER_AF_SERVER_CLUSTER_TICK false
846 * @brief This function is used to schedule a cluster-related event inside the
847 * application framework's event mechanism. This function provides a wrapper
848 * for the Ember stack event mechanism which allows the cluster code to access
849 * its events by their endpoint, cluster id, and client/server identity. The
850 * passed poll and sleep controls allow the cluster to indicate whether it
851 * needs to long or short poll and whether it needs to stay awake or if it can
854 * @param endpoint the endpoint of the event to be scheduled.
855 * @param clusterId the cluster id of the event to be scheduled.
856 * @param isClient ::EMBER_AF_CLIENT_CLUSTER_TICK if the event to be scheduled
857 * is associated with a client cluster or ::EMBER_AF_SERVER_CLUSTER_TICK
859 * @param delayMs the number of milliseconds until the event should be called.
860 * @param pollControl ::EMBER_AF_SHORT_POLL if the cluster needs to short poll
861 * or ::EMBER_AF_LONG_POLL otherwise.
862 * @param sleepControl ::EMBER_AF_STAY_AWAKE if the cluster needs to stay awake
863 * or EMBER_AF_OK_TO_SLEEP otherwise.
865 * @return EMBER_SUCCESS if the event was scheduled or an error otherwise.
867 EmberStatus emberAfScheduleTickExtended(chip::EndpointId endpoint, chip::ClusterId clusterId, bool isClient, uint32_t delayMs,
868 EmberAfEventPollControl pollControl, EmberAfEventSleepControl sleepControl);
871 * @brief This function is used to schedule a cluster-related event inside the
872 * This function is a wrapper for ::emberAfScheduleTickExtended. The cluster
873 * on the given endpoint will be set to long poll if sleepControl is set to
874 * ::EMBER_AF_OK_TO_HIBERNATE or will be set to short poll otherwise. It will
875 * stay awake if sleepControl is ::EMBER_AF_STAY_AWAKE and will sleep
878 * @param endpoint the endpoint of the event to be scheduled.
879 * @param clusterId the cluster id of the event to be scheduled.
880 * @param isClient ::EMBER_AF_CLIENT_CLUSTER_TICK if the event to be scheduled
881 * is associated with a client cluster or ::EMBER_AF_SERVER_CLUSTER_TICK
883 * @param delayMs the number of milliseconds until the event should be called.
884 * @param sleepControl the priority of the event, what the processor should
885 * be allowed to do in terms of sleeping while the event is active.
887 * @return EMBER_SUCCESS if the event was scheduled or an error otherwise.
889 EmberStatus emberAfScheduleClusterTick(chip::EndpointId endpoint, chip::ClusterId clusterId, bool isClient, uint32_t delayMs,
890 EmberAfEventSleepControl sleepControl);
893 * @brief A function used to schedule a cluster client event. This function
894 * is a wrapper for ::emberAfScheduleTickExtended.
896 * @param endpoint the endpoint of the event to be scheduled
897 * @param clusterId the cluster id of the event to be scheduled
898 * @param delayMs the number of milliseconds until the event should be called.
899 * @param pollControl ::EMBER_AF_SHORT_POLL if the cluster needs to short poll
900 * or ::EMBER_AF_LONG_POLL otherwise.
901 * @param sleepControl ::EMBER_AF_STAY_AWAKE if the cluster needs to stay awake
902 * or EMBER_AF_OK_TO_SLEEP otherwise.
904 * @return EMBER_SUCCESS if the event was scheduled or an error otherwise.
906 EmberStatus emberAfScheduleClientTickExtended(chip::EndpointId endpoint, chip::ClusterId clusterId, uint32_t delayMs,
907 EmberAfEventPollControl pollControl, EmberAfEventSleepControl sleepControl);
910 * @brief A function used to schedule a cluster client event. This function
911 * is a wrapper for ::emberAfScheduleClientTickExtended. It indicates that
912 * the cluster client on the given endpoint can long poll and can sleep.
914 * @param endpoint the endpoint of the event to be scheduled.
915 * @param clusterId the cluster id of the event to be scheduled.
916 * @param delayMs the number of milliseconds until the event should be called.
918 * @return EMBER_SUCCESS if the event was scheduled or an error otherwise.
920 EmberStatus emberAfScheduleClientTick(chip::EndpointId endpoint, chip::ClusterId clusterId, uint32_t delayMs);
923 * @brief A function used to schedule a cluster server event. This function
924 * is a wrapper for ::emberAfScheduleTickExtended.
926 * @param endpoint the endpoint of the event to be scheduled.
927 * @param clusterId the cluster id of the event to be scheduled.
928 * @param delayMs the number of milliseconds until the event should be called.
929 * @param pollControl ::EMBER_AF_SHORT_POLL if the cluster needs to short poll
930 * or ::EMBER_AF_LONG_POLL otherwise.
931 * @param sleepControl ::EMBER_AF_STAY_AWAKE if the cluster needs to stay awake
932 * or EMBER_AF_OK_TO_SLEEP otherwise.
934 * @return EMBER_SUCCESS if the event was scheduled or an error otherwise.
936 EmberStatus emberAfScheduleServerTickExtended(chip::EndpointId endpoint, chip::ClusterId clusterId, uint32_t delayMs,
937 EmberAfEventPollControl pollControl, EmberAfEventSleepControl sleepControl);
940 * @brief A function used to schedule a cluster server event. This function
941 * is a wrapper for ::emberAfScheduleServerTickExtended. It indicates that
942 * the cluster server on the given endpoint can long poll and can sleep.
944 * @param endpoint the endpoint of the event to be scheduled
945 * @param clusterId the cluster id of the event to be scheduled.
946 * @param delayMs the number of milliseconds until the event should be called.
948 * @return EMBER_SUCCESS if the event was scheduled or an error otherwise.
950 EmberStatus emberAfScheduleServerTick(chip::EndpointId endpoint, chip::ClusterId clusterId, uint32_t delayMs);
953 * @brief A function used to deactivate a cluster-related event. This function
954 * provides a wrapper for the Ember stack's event mechanism which allows an
955 * event to be accessed by its endpoint, cluster id, and client/server
958 * @param endpoint the endpoint of the event to be deactivated.
959 * @param clusterId the cluster id of the event to be deactivated.
960 * @param isClient ::EMBER_AF_CLIENT_CLUSTER_TICK if the event to be
961 * deactivated is a client cluster ::EMBER_AF_SERVER_CLUSTER_TICK
964 * @return EMBER_SUCCESS if the event was deactivated or an error otherwise.
966 EmberStatus emberAfDeactivateClusterTick(chip::EndpointId endpoint, chip::ClusterId clusterId, bool isClient);
969 * @brief A function used to deactivate a cluster client event. This function
970 * is a wrapper for ::emberAfDeactivateClusterTick.
972 * @param endpoint the endpoint of the event to be deactivated.
973 * @param clusterId the cluster id of the event to be deactivated.
975 * @return EMBER_SUCCESS if the event was deactivated or an error otherwise.
977 EmberStatus emberAfDeactivateClientTick(chip::EndpointId endpoint, chip::ClusterId clusterId);
980 * @brief A function used to deactivate a cluster server event. This function
981 * is a wrapper for ::emberAfDeactivateClusterTick.
983 * @param endpoint the endpoint of the event to be deactivated.
984 * @param clusterId the cluster id of the event to be deactivated.
986 * @return EMBER_SUCCESS if the event was deactivated or an error otherwise.
988 EmberStatus emberAfDeactivateServerTick(chip::EndpointId endpoint, chip::ClusterId clusterId);
991 * @brief Sets the ::EmberEventControl to run "delayMs" milliseconds in the
992 * future. This function first verifies that the delay is within the
993 * acceptable range before scheduling the event.
995 * @param control a pointer to the event control.
996 * @param delayMs the number of milliseconds until the next event.
998 * @return If delayMs is less than or equal to
999 ::EMBER_MAX_EVENT_CONTROL_DELAY_MS, this function will schedule the
1000 event and return ::EMBER_SUCCESS. Otherwise it will return
1001 ::EMBER_BAD_ARGUMENT.
1003 EmberStatus emberEventControlSetDelayMS(EmberEventControl * control, uint32_t delayMs);
1006 * @brief Sets the ::EmberEventControl to run "delayQs" quarter seconds in the
1007 * future. The 'quarter seconds' are actually 256 milliseconds long. This
1008 * function first verifies that the delay is within the acceptable range before
1009 * scheduling the event.
1011 * @param control a pointer to the event control.
1012 * @param delayQs the number of quarter seconds until the next event.
1014 * @return If delayQs is less than or equal to
1015 ::EMBER_MAX_EVENT_CONTROL_DELAY_QS, this function will schedule the
1016 event and return ::EMBER_SUCCESS. Otherwise it will return
1017 ::EMBER_BAD_ARGUMENT.
1019 EmberStatus emberAfEventControlSetDelayQS(EmberEventControl * control, uint32_t delayQs);
1022 * @brief Sets the ::EmberEventControl to run "delayM" minutes in the future.
1023 * The 'minutes' are actually 65536 (0x10000) milliseconds long. This function
1024 * first verifies that the delay is within the acceptable range before
1025 * scheduling the event.
1027 * @param control a pointer to the event control.
1028 * @param delayM the number of minutes until the next event.
1030 * @return If delayM is less than or equal to
1031 ::EMBER_MAX_EVENT_CONTROL_DELAY_MINUTES, this function will schedule
1032 the event and return ::EMBER_SUCCESS. Otherwise it will return
1033 ::EMBER_BAD_ARGUMENT.
1035 EmberStatus emberAfEventControlSetDelayMinutes(EmberEventControl * control, uint16_t delayM);
1038 * @brief Sets the ::EmberEventControl for the current network, and only
1039 * the current network, as inactive. See ::emberEventControlSetInactive.
1041 void emberAfNetworkEventControlSetInactive(EmberEventControl * controls);
1043 * @brief Returns true if the event for the current network, and only the
1044 * current network, is active. See ::emberEventControlGetActive.
1046 bool emberAfNetworkEventControlGetActive(EmberEventControl * controls);
1048 * @brief Sets the ::EmberEventControl for the current network, and only
1049 * current network, to run at the next available opportunity. See
1050 * ::emberEventControlSetActive.
1052 void emberAfNetworkEventControlSetActive(EmberEventControl * controls);
1054 * @brief Sets the ::EmberEventControl for the current network, and only the
1055 * current network, to run "delayMs" milliseconds in the future. See
1056 * ::emberEventControlSetDelayMS.
1058 EmberStatus emberAfNetworkEventControlSetDelayMS(EmberEventControl * controls, uint32_t delayMs);
1059 #ifdef DOXYGEN_SHOULD_SKIP_THIS
1061 * @brief Sets the ::EmberEventControl for the current network, and only the
1062 * current network, to run "delayMs" milliseconds in the future. See
1063 * ::emberEventControlSetDelayMS.
1065 EmberStatus emberAfNetworkEventControlSetDelay(EmberEventControl * controls, uint32_t delayMs);
1067 #define emberAfNetworkEventControlSetDelay(controls, delayMs) emberAfNetworkEventControlSetDelayMS(controls, delayMs);
1070 * @brief Sets the ::EmberEventControl for the current network, and only the
1071 * current network, to run "delayQs" quarter seconds in the future. See
1072 * ::emberAfEventControlSetDelayQS.
1074 EmberStatus emberAfNetworkEventControlSetDelayQS(EmberEventControl * controls, uint32_t delayQs);
1076 * @brief Sets the ::EmberEventControl for the current network, and only the
1077 * current network, to run "delayM" minutes in the future. See
1078 * ::emberAfEventControlSetDelayMinutes.
1080 EmberStatus emberAfNetworkEventControlSetDelayMinutes(EmberEventControl * controls, uint16_t delayM);
1083 * @brief Sets the ::EmberEventControl for the specified endpoint as inactive.
1084 * See ::emberEventControlSetInactive.
1086 EmberStatus emberAfEndpointEventControlSetInactive(EmberEventControl * controls, chip::EndpointId endpoint);
1088 * @brief Returns true if the event for the current number is active. See
1089 * ::emberEventControlGetActive.
1091 bool emberAfEndpointEventControlGetActive(EmberEventControl * controls, chip::EndpointId endpoint);
1093 * @brief Sets the ::EmberEventControl for the specified endpoint to run at the
1094 * next available opportunity. See ::emberEventControlSetActive.
1096 EmberStatus emberAfEndpointEventControlSetActive(EmberEventControl * controls, chip::EndpointId endpoint);
1098 * @brief Sets the ::EmberEventControl for the specified endpoint to run
1099 * "delayMs" milliseconds in the future. See ::emberEventControlSetDelayMS.
1101 EmberStatus emberAfEndpointEventControlSetDelayMS(EmberEventControl * controls, chip::EndpointId endpoint, uint32_t delayMs);
1102 #ifdef DOXYGEN_SHOULD_SKIP_THIS
1104 * @brief Sets the ::EmberEventControl for the specified endpoint to run
1105 * "delayMs" milliseconds in the future. See ::emberEventControlSetDelayMS.
1107 EmberStatus emberAfEndpointEventControlSetDelay(EmberEventControl * controls, chip::EndpointId endpoint, uint32_t delayMs);
1109 #define emberAfEndpointEventControlSetDelay(controls, endpoint, delayMs) \
1110 emberAfEndpointEventControlSetDelayMS(controls, endpoint, delayMs);
1113 * @brief Sets the ::EmberEventControl for the specified endpoint to run
1114 * "delayQs" quarter seconds in the future. See
1115 * ::emberAfEventControlSetDelayQS.
1117 EmberStatus emberAfEndpointEventControlSetDelayQS(EmberEventControl * controls, chip::EndpointId endpoint, uint32_t delayQs);
1119 * @brief Sets the ::EmberEventControl for the specified endpoint to run
1120 * "delayM" minutes in the future. See ::emberAfEventControlSetDelayMinutes.
1122 EmberStatus emberAfEndpointEventControlSetDelayMinutes(EmberEventControl * controls, chip::EndpointId endpoint, uint16_t delayM);
1125 * @brief A function used to retrieve the number of milliseconds until
1126 * the next event scheduled in the application framework's event
1128 * @param maxMs, the maximum number of milliseconds until the next
1130 * @return The number of milliseconds until the next event or
1131 * maxMs if no event is scheduled before then.
1133 uint32_t emberAfMsToNextEvent(uint32_t maxMs);
1135 /** @brief This is the same as the function emberAfMsToNextEvent() with the
1136 * following addition. If returnIndex is non-NULL it returns the index
1137 * of the event that is ready to fire next.
1139 uint32_t emberAfMsToNextEventExtended(uint32_t maxMs, uint8_t * returnIndex);
1142 * @brief A function used to retrieve the number of quarter seconds until
1143 * the next event scheduled in the application framework's event
1144 * mechanism. This function will round down and will return 0 if the
1145 * next event must fire within a quarter second.
1146 * @param maxQS, the maximum number of quarter seconds until the next
1148 * @return The number of quarter seconds until the next event or
1149 * maxQS if no event is scheduled before then.
1151 #define emberAfQSToNextEvent(maxQS) \
1152 (emberAfMsToNextEvent(maxQS * MILLISECOND_TICKS_PER_QUARTERSECOND) / MILLISECOND_TICKS_PER_QUARTERSECOND)
1155 * @brief A function for retrieving the most restrictive sleep
1156 * control value for all scheduled events. This function is
1157 * used by emberAfOkToNap and emberAfOkToHibernate to makes sure
1158 * that there are no events scheduled which will keep the device
1159 * from hibernating or napping.
1160 * @return The most restrictive sleep control value for all
1161 * scheduled events or the value returned by
1162 * emberAfGetDefaultSleepControl()
1163 * if no events are currently scheduled. The default
1164 * sleep control value is initialized to
1165 * EMBER_AF_OK_TO_HIBERNATE but can be changed at any
1166 * time using the emberAfSetDefaultSleepControl() function.
1168 #define emberAfGetCurrentSleepControl() emberAfGetCurrentSleepControlCallback()
1171 * @brief A function for setting the default sleep control
1172 * value against which all scheduled event sleep control
1173 * values will be evaluated. This can be used to keep
1174 * a device awake for an extended period of time by setting
1175 * the default to EMBER_AF_STAY_AWAKE and then resetting
1176 * the value to EMBER_AF_OK_TO_HIBERNATE once the wake
1177 * period is complete.
1179 #define emberAfSetDefaultSleepControl(x) emberAfSetDefaultSleepControlCallback(x)
1182 * @brief A function used to retrieve the default sleep control against
1183 * which all event sleep control values are evaluated. The
1184 * default sleep control value is initialized to
1185 * EMBER_AF_OK_TO_HIBERNATE but can be changed by the application
1186 * at any time using the emberAfSetDefaultSleepControl() function.
1187 * @return The current default sleep control value.
1189 #define emberAfGetDefaultSleepControl() emberAfGetDefaultSleepControlCallback()
1191 /** @} END Sleep Control */
1193 /** @name Messaging */
1197 * @brief This function sends a ZCL response, based on the information
1198 * that is currently in the outgoing buffer. It is expected that a complete
1199 * ZCL message is present, including header. The application may use
1200 * this method directly from within the message handling function
1201 * and associated callbacks. However this will result in the
1202 * response being sent before the APS Ack is sent which is not
1205 * NOTE: This will overwrite the ZCL sequence number of the message
1206 * to use the LAST received sequence number.
1208 EmberStatus emberAfSendResponse(void);
1211 * @brief Send ZCL response with attached message sent callback
1213 EmberStatus emberAfSendResponseWithCallback(EmberAfMessageSentFunction callback);
1216 * @brief Sends multicast.
1218 EmberStatus emberAfSendMulticast(chip::GroupId multicastId, EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message);
1221 * @brief Multicasts the message to the group in the binding table that
1222 * matches the cluster and source endpoint in the APS frame. Note: if the
1223 * binding table contains many matching entries, calling this API cause a
1224 * significant amount of network traffic. Care should be taken when considering
1225 * the effects of broadcasts in a network.
1227 EmberStatus emberAfSendMulticastToBindings(EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message);
1230 * @brief Sends Multicast with alias with attached message sent callback
1232 EmberStatus emberAfSendMulticastWithAliasWithCallback(chip::GroupId multicastId, EmberApsFrame * apsFrame, uint16_t messageLength,
1233 uint8_t * message, EmberNodeId alias, uint8_t sequence,
1234 EmberAfMessageSentFunction callback);
1237 * @brief Sends multicast with attached message sent callback.
1239 EmberStatus emberAfSendMulticastWithCallback(chip::GroupId multicastId, EmberApsFrame * apsFrame, uint16_t messageLength,
1240 uint8_t * message, EmberAfMessageSentFunction callback);
1243 * @brief Sends broadcast.
1245 EmberStatus emberAfSendBroadcast(EmberNodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message);
1248 * @brief Sends broadcast with attached message sent callback.
1250 EmberStatus emberAfSendBroadcastWithCallback(EmberNodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength,
1251 uint8_t * message, EmberAfMessageSentFunction callback);
1254 * @brief Sends broadcast with alias with attached message sent callback.
1256 EmberStatus emberAfSendBroadcastWithAliasWithCallback(EmberNodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength,
1257 uint8_t * message, EmberNodeId alias, uint8_t sequence,
1258 EmberAfMessageSentFunction callback);
1261 * @brief Sends unicast.
1263 EmberStatus emberAfSendUnicast(EmberOutgoingMessageType type, uint64_t indexOrDestination, EmberApsFrame * apsFrame,
1264 uint16_t messageLength, uint8_t * message);
1267 * @brief Sends unicast with attached message sent callback.
1269 EmberStatus emberAfSendUnicastWithCallback(EmberOutgoingMessageType type, uint64_t indexOrDestination, EmberApsFrame * apsFrame,
1270 uint16_t messageLength, uint8_t * message, EmberAfMessageSentFunction callback);
1273 * @brief Unicasts the message to each remote node in the binding table that
1274 * matches the cluster and source endpoint in the APS frame. Note: if the
1275 * binding table contains many matching entries, calling this API cause a
1276 * significant amount of network traffic.
1278 EmberStatus emberAfSendUnicastToBindings(EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message);
1281 * @brief emberAfSendUnicastToBindings with attached message sent callback.
1283 EmberStatus emberAfSendUnicastToBindingsWithCallback(EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message,
1284 EmberAfMessageSentFunction callback);
1287 * @brief Sends interpan message.
1289 EmberStatus emberAfSendInterPan(EmberPanId panId, const EmberEUI64 destinationLongId, EmberNodeId destinationShortId,
1290 chip::GroupId multicastId, chip::ClusterId clusterId, uint16_t messageLength,
1291 uint8_t * messageBytes);
1294 * @brief Sends end device binding request.
1296 EmberStatus emberAfSendEndDeviceBind(chip::EndpointId endpoint);
1299 * @brief Sends the command prepared with emberAfFill.... macro.
1301 * This function is used to send a command that was previously prepared
1302 * using the emberAfFill... macros from the client command API. It
1303 * will be sent as unicast to each remote node in the binding table that
1304 * matches the cluster and source endpoint in the APS frame. Note: if the
1305 * binding table contains many matching entries, calling this API cause a
1306 * significant amount of network traffic.
1308 EmberStatus emberAfSendCommandUnicastToBindings(void);
1311 * @brief emberAfSendCommandUnicastToBindings with attached message sent callback.
1313 EmberStatus emberAfSendCommandUnicastToBindingsWithCallback(EmberAfMessageSentFunction callback);
1316 * @brief Sends the command prepared with emberAfFill.... macro.
1318 * This function is used to send a command that was previously prepared
1319 * using the emberAfFill... macros from the client command API. It
1320 * will be sent as multicast.
1322 EmberStatus emberAfSendCommandMulticast(chip::GroupId multicastId);
1325 * @brief Sends the command prepared with emberAfFill.... macro.
1327 * This function is used to send a command that was previously prepared
1328 * using the emberAfFill... macros from the client command API. It
1329 * will be sent as multicast.
1331 EmberStatus emberAfSendCommandMulticastWithAlias(chip::GroupId multicastId, EmberNodeId alias, uint8_t sequence);
1334 * @brief emberAfSendCommandMulticast with attached message sent callback.
1336 EmberStatus emberAfSendCommandMulticastWithCallback(chip::GroupId multicastId, EmberAfMessageSentFunction callback);
1339 * @brief Sends the command prepared with emberAfFill.... macro.
1341 * This function is used to send a command that was previously prepared
1342 * using the emberAfFill... macros from the client command API. It
1343 * will be sent as multicast to the group specified in the binding table that
1344 * matches the cluster and source endpoint in the APS frame. Note: if the
1345 * binding table contains many matching entries, calling this API cause a
1346 * significant amount of network traffic.
1348 EmberStatus emberAfSendCommandMulticastToBindings(void);
1350 * @brief Sends the command prepared with emberAfFill.... macro.
1352 * This function is used to send a command that was previously prepared
1353 * using the emberAfFill... macros from the client command API.
1354 * It will be sent as unicast.
1356 EmberStatus emberAfSendCommandUnicast(EmberOutgoingMessageType type, uint16_t indexOrDestination);
1359 * @brief emberAfSendCommandUnicast with attached message sent callback.
1361 EmberStatus emberAfSendCommandUnicastWithCallback(EmberOutgoingMessageType type, uint64_t indexOrDestination,
1362 EmberAfMessageSentFunction callback);
1365 * @brief Sends the command prepared with emberAfFill.... macro.
1367 * This function is used to send a command that was previously prepared
1368 * using the emberAfFill... macros from the client command API.
1370 EmberStatus emberAfSendCommandBroadcast(EmberNodeId destination);
1373 * @brief emberAfSendCommandBroadcast with attached message sent callback.
1375 EmberStatus emberAfSendCommandBroadcastWithCallback(EmberNodeId destination, EmberAfMessageSentFunction callback);
1378 * @brief emberAfSendCommandBroadcast from alias with attached message sent callback.
1380 EmberStatus emberAfSendCommandBroadcastWithAliasWithCallback(EmberNodeId destination, EmberNodeId alias, uint8_t sequence,
1381 EmberAfMessageSentFunction callback);
1384 * @brief Sends the command prepared with emberAfFill.... macro.
1386 * This function is used to send a command that was previously prepared
1387 * using the emberAfFill... macros from the client command API.
1389 EmberStatus emberAfSendCommandBroadcastWithAlias(EmberNodeId destination, EmberNodeId alias, uint8_t sequence);
1391 * @brief Sends the command prepared with emberAfFill.... macro.
1393 * This function is used to send a command that was previously prepared
1394 * using the emberAfFill... macros from the client command API.
1395 * It will be sent via inter-PAN. If destinationLongId is not NULL, the message
1396 * will be sent to that long address using long addressing mode; otherwise, the
1397 * message will be sent to destinationShortId using short address mode. IF
1398 * multicastId is not zero, the message will be sent using multicast mode.
1400 EmberStatus emberAfSendCommandInterPan(EmberPanId panId, const EmberEUI64 destinationLongId, EmberNodeId destinationShortId,
1401 chip::GroupId multicastId);
1404 * @brief Sends a default response to a cluster command.
1406 * This function is used to prepare and send a default response to a cluster
1409 * @param cmd The cluster command to which to respond.
1410 * @param status Status code for the default response command.
1411 * @return An ::EmberStatus value that indicates the success or failure of
1412 * sending the response.
1414 EmberStatus emberAfSendDefaultResponse(const EmberAfClusterCommand * cmd, EmberAfStatus status);
1417 * @brief emberAfSendDefaultResponse with attached message sent callback.
1419 EmberStatus emberAfSendDefaultResponseWithCallback(const EmberAfClusterCommand * cmd, EmberAfStatus status,
1420 EmberAfMessageSentFunction callback);
1423 * @brief Sends a default response to a cluster command using the
1426 * This function is used to prepare and send a default response to a cluster
1429 * @param status Status code for the default response command.
1430 * @return An ::EmberStatus value that indicates the success or failure of
1431 * sending the response.
1433 EmberStatus emberAfSendImmediateDefaultResponse(EmberAfStatus status);
1436 * @brief emberAfSendImmediateDefaultResponse with attached message sent callback.
1438 EmberStatus emberAfSendImmediateDefaultResponseWithCallback(EmberAfStatus status, EmberAfMessageSentFunction callback);
1441 * @brief Returns the maximum size of the payload that the Application
1442 * Support sub-layer will accept for the given message type, destination, and
1445 * The size depends on multiple factors, including the security level in use
1446 * and additional information added to the message to support the various
1449 * @param type The outgoing message type.
1450 * @param indexOrDestination Depending on the message type, this is either the
1451 * EmberNodeId of the destination, an index into the address table, an index
1452 * into the binding table, the multicast identifier, or a broadcast address.
1453 * @param apsFrame The APS frame for the message.
1454 * @return The maximum APS payload length for the given message.
1456 uint8_t emberAfMaximumApsPayloadLength(EmberOutgoingMessageType type, uint64_t indexOrDestination, EmberApsFrame * apsFrame);
1459 * @brief Access to client API APS frame.
1461 EmberApsFrame * emberAfGetCommandApsFrame(void);
1464 * @brief Set the source and destination endpoints in the client API APS frame.
1466 void emberAfSetCommandEndpoints(chip::EndpointId sourceEndpoint, chip::EndpointId destinationEndpoint);
1469 * @brief Friendly define for use in discovering client clusters with
1470 * ::emberAfFindDevicesByCluster().
1472 #define EMBER_AF_CLIENT_CLUSTER_DISCOVERY false
1475 * @brief Friendly define for use in discovering server clusters with
1476 * ::emberAfFindDevicesByCluster().
1478 #define EMBER_AF_SERVER_CLUSTER_DISCOVERY true
1481 * @brief Use this function to find devices in the network with endpoints
1482 * matching a given cluster ID in their descriptors.
1483 * Target may either be a specific device, or the broadcast
1484 * address EMBER_RX_ON_WHEN_IDLE_BROADCAST_ADDRESS.
1486 * With this function a service discovery is initiated and received
1487 * responses are returned by executing the callback function passed in.
1488 * For unicast discoveries, the callback will be executed only once.
1489 * Either the target will return a result or a timeout will occur.
1490 * For broadcast discoveries, the callback may be called multiple times
1491 * and after a period of time the discovery will be finished with a final
1492 * call to the callback.
1494 * @param target The destination node ID for the discovery; either a specific
1495 * node's ID or EMBER_RX_ON_WHEN_IDLE_BROADCAST_ADDRESS.
1496 * @param clusterId The cluster being discovered.
1497 * @param serverCluster EMBER_AF_SERVER_CLUSTER_DISCOVERY (true) if discovering
1498 * servers for the target cluster; EMBER_AF_CLIENT_CLUSTER_DISCOVERY (false)
1499 * if discovering clients for that cluster.
1500 * @param callback Function pointer for the callback function triggered when
1501 * a match is discovered. (For broadcast discoveries, this is called once per
1502 * matching node, even if a node has multiple matching endpoints.)
1504 EmberStatus emberAfFindDevicesByCluster(EmberNodeId target, chip::ClusterId clusterId, bool serverCluster,
1505 EmberAfServiceDiscoveryCallback * callback);
1508 * @brief Use this function to find all of the given in and out clusters
1509 * implemented on a devices given endpoint. Target should only be the
1510 * short address of a specific device.
1512 * With this function a single service discovery is initiated and the response
1513 * is passed back to the passed callback.
1515 * @param target The destination node ID for the discovery. This should be a
1516 * specific node's ID and should not be a broadcast address.
1517 * @param targetEndpoint The endpoint to target with the discovery process.
1518 * @param callback Function pointer for the callback function triggered when
1519 * the discovery is returned.
1521 EmberStatus emberAfFindClustersByDeviceAndEndpoint(EmberNodeId target, uint8_t targetEndpoint,
1522 EmberAfServiceDiscoveryCallback * callback);
1525 * @brief Use this function to initiate a discovery for the IEEE address
1526 * of the specified node id. This will send a unicast sent to the target
1529 EmberStatus emberAfFindIeeeAddress(EmberNodeId shortAddress, EmberAfServiceDiscoveryCallback * callback);
1532 * @brief Use this function to initiate a discovery for the short ID of the
1533 * specified long address. This will send a broadcast to all
1534 * rx-on-when-idle devices (non-sleepies).
1536 EmberStatus emberAfFindNodeId(EmberEUI64 longAddress, EmberAfServiceDiscoveryCallback * callback);
1539 * @brief Initiate an Active Endpoint request ZDO message to the target node ID.
1541 EmberStatus emberAfFindActiveEndpoints(EmberNodeId target, EmberAfServiceDiscoveryCallback * callback);
1544 * @brief Use this function to add an entry for a remote device to the address
1547 * If the EUI64 already exists in the address table, the index of the existing
1548 * entry will be returned. Otherwise, a new entry will be created and the new
1549 * new index will be returned. The framework will remember how many times the
1550 * returned index has been referenced. When the address table entry is no
1551 * longer needed, the application should remove its reference by calling
1552 * ::emberAfRemoveAddressTableEntry.
1554 * @param longId The EUI64 of the remote device.
1555 * @param shortId The node id of the remote device or ::EMBER_UNKNOWN_NODE_ID
1556 * if the node id is currently unknown.
1557 * @return The index of the address table entry for this remove device or
1558 * ::EMBER_NULL_ADDRESS_TABLE_INDEX if an error occurred (e.g., the address
1561 uint8_t emberAfAddAddressTableEntry(EmberEUI64 longId, EmberNodeId shortId);
1564 * @brief Use this function to add an entry for a remote device to the address
1565 * table at a specific location.
1567 * The framework will remember how many times an address table index has been
1568 * referenced through ::emberAfAddAddressTableEntry. If the reference count
1569 * for the index passed to this function is not zero, the entry will be not
1570 * changed. When the address table entry is no longer needed, the application
1571 * should remove its reference by calling ::emberAfRemoveAddressTableEntry.
1573 * @param index The index of the address table entry.
1574 * @param longId The EUI64 of the remote device.
1575 * @param shortId The node id of the remote device or ::EMBER_UNKNOWN_NODE_ID
1576 * if the node id is currently unknown.
1577 * @return ::EMBER_SUCCESS if the address table entry was successfully set,
1578 * ::EMBER_ADDRESS_TABLE_ENTRY_IS_ACTIVE if any messages are being sent using
1579 * the existing entry at that index or the entry is still referenced in the
1580 * framework, or ::EMBER_ADDRESS_TABLE_INDEX_OUT_OF_RANGE if the index is out
1583 EmberStatus emberAfSetAddressTableEntry(uint8_t index, EmberEUI64 longId, EmberNodeId shortId);
1586 * @brief Use this function to remove a specific entry from the address table.
1588 * The framework will remember how many times an address table index has been
1589 * referenced through ::emberAfAddAddressTableEntry and
1590 * ::emberAfSetAddressTableEntry. The address table entry at this index will
1591 * not actually be removed until its reference count reaches zero.
1593 * @param index The index of the address table entry.
1594 * @return ::EMBER_SUCCESS if the address table entry was successfully removed
1595 * or ::EMBER_ADDRESS_TABLE_INDEX_OUT_OF_RANGE if the index is out of range.
1597 EmberStatus emberAfRemoveAddressTableEntry(uint8_t index);
1599 #if !defined(DOXYGEN_SHOULD_SKIP_THIS)
1601 * @brief Use this macro to retrieve the current command. This
1602 * macro may only be used within the command parsing context. For instance
1603 * Any of the command handling callbacks may use this macro. If this macro
1604 * is used outside the command context, the returned EmberAfClusterCommand pointer
1607 #define emberAfCurrentCommand() (emAfCurrentCommand)
1608 extern EmberAfClusterCommand * emAfCurrentCommand;
1612 * @brief returns the current endpoint that is being served.
1614 * The purpose of this macro is mostly to access endpoint that
1615 * is being served in the command callbacks.
1617 #define emberAfCurrentEndpoint() (emberAfCurrentCommand()->apsFrame->destinationEndpoint)
1619 #ifdef DOXYGEN_SHOULD_SKIP_THIS
1620 /** @brief Use this function to initiate key establishment with a remote node.
1621 * ::emberAfKeyEstablishmentCallback will be called as events occur and when
1622 * key establishment completes.
1624 * @param nodeId The node id of the remote device.
1625 * @param endpoint The endpoint on the remote device.
1626 * @return ::EMBER_SUCCESS if key establishment was initiated successfully
1628 EmberStatus emberAfInitiateKeyEstablishment(EmberNodeId nodeId, chip::EndpointId endpoint);
1630 /** @brief Use this function to initiate key establishment with a remote node on
1631 * a different PAN. ::emberAfInterPanKeyEstablishmentCallback will be called
1632 * as events occur and when key establishment completes.
1634 * @param panId The PAN id of the remote device.
1635 * @param eui64 The EUI64 of the remote device.
1636 * @return ::EMBER_SUCCESS if key establishment was initiated successfully
1638 EmberStatus emberAfInitiateInterPanKeyEstablishment(EmberPanId panId, const EmberEUI64 eui64);
1640 /** @brief Use this function to tell if the device is in the process of
1641 * performing key establishment.
1643 * @return ::true if key establishment is in progress.
1645 bool emberAfPerformingKeyEstablishment(void);
1647 /** @brief Use this function to initiate partner link key exchange with a
1650 * @param target The node id of the remote device.
1651 * @param endpoint The key establishment endpoint of the remote device.
1652 * @param callback The callback that should be called when the partner link
1653 * key exchange completes.
1654 * @return ::EMBER_SUCCESS if the partner link key exchange was initiated
1657 EmberStatus emberAfInitiatePartnerLinkKeyExchange(EmberNodeId target, chip::EndpointId endpoint,
1658 EmberAfPartnerLinkKeyExchangeCallback * callback);
1660 #define emberAfInitiateKeyEstablishment(nodeId, endpoint) emberAfInitiateKeyEstablishmentCallback(nodeId, endpoint)
1661 #define emberAfInitiateInterPanKeyEstablishment(panId, eui64) emberAfInitiateInterPanKeyEstablishmentCallback(panId, eui64)
1662 #define emberAfPerformingKeyEstablishment() emberAfPerformingKeyEstablishmentCallback()
1663 #define emberAfInitiatePartnerLinkKeyExchange(target, endpoint, callback) \
1664 emberAfInitiatePartnerLinkKeyExchangeCallback(target, endpoint, callback)
1667 /** @} END Messaging */
1669 /** @name ZCL macros */
1671 // Frame control fields (8 bits total)
1672 // Bits 0 and 1 are Frame Type Sub-field
1673 #define ZCL_FRAME_CONTROL_FRAME_TYPE_MASK (EMBER_BIT(0) | EMBER_BIT(1))
1674 #define ZCL_CLUSTER_SPECIFIC_COMMAND EMBER_BIT(0)
1675 #define ZCL_PROFILE_WIDE_COMMAND 0
1676 #define ZCL_GLOBAL_COMMAND (ZCL_PROFILE_WIDE_COMMAND)
1677 // Bit 2 is Manufacturer Specific Sub-field
1678 #define ZCL_MANUFACTURER_SPECIFIC_MASK EMBER_BIT(2)
1679 // Bit 3 is Direction Sub-field
1680 #define ZCL_FRAME_CONTROL_DIRECTION_MASK EMBER_BIT(3)
1681 #define ZCL_FRAME_CONTROL_SERVER_TO_CLIENT EMBER_BIT(3)
1682 #define ZCL_FRAME_CONTROL_CLIENT_TO_SERVER 0
1683 // Bit 4 is Disable Default Response Sub-field
1684 #define ZCL_DISABLE_DEFAULT_RESPONSE_MASK EMBER_BIT(4)
1685 // Bits 5 to 7 are reserved
1687 #define ZCL_DIRECTION_CLIENT_TO_SERVER 0
1688 #define ZCL_DIRECTION_SERVER_TO_CLIENT 1
1690 // Packet must be at least 3 bytes for ZCL overhead.
1691 // Frame Control (1-byte)
1692 // Sequence Number (1-byte)
1693 // Command Id (1-byte)
1694 #define EMBER_AF_ZCL_OVERHEAD 3
1695 #define EMBER_AF_ZCL_MANUFACTURER_SPECIFIC_OVERHEAD 5
1697 // Permitted values for emberAfSetFormAndJoinMode
1698 #define FIND_AND_JOIN_MODE_ALLOW_2_4_GHZ EMBER_BIT(0)
1699 #define FIND_AND_JOIN_MODE_ALLOW_SUB_GHZ EMBER_BIT(1)
1700 #define FIND_AND_JOIN_MODE_ALLOW_BOTH (FIND_AND_JOIN_MODE_ALLOW_2_4_GHZ | FIND_AND_JOIN_MODE_ALLOW_SUB_GHZ)
1702 /** @} END ZCL macros */
1704 /** @name Network utility functions */
1707 /** @brief Use this function to form a new network using the specified network
1710 * @param parameters Specification of the new network.
1711 * @return An ::EmberStatus value that indicates either the successful formation
1712 * of the new network or the reason that the network formation failed.
1714 EmberStatus emberAfFormNetwork(EmberNetworkParameters * parameters);
1716 /** @brief Use this function to associate with the network using the specified
1717 * network parameters.
1719 * @param parameters Specification of the network with which the node should
1721 * @return An ::EmberStatus value that indicates either that the association
1722 * process began successfully or the reason for failure.
1724 EmberStatus emberAfJoinNetwork(EmberNetworkParameters * parameters);
1726 #ifdef DOXYGEN_SHOULD_SKIP_THIS
1727 /** @brief Use this function to find an unused PAN id and form a new network.
1729 * @return An ::EmberStatus value that indicates either the process begin
1730 * successfully or the reason for failure.
1732 EmberStatus emberAfFindUnusedPanIdAndForm(void);
1733 /** @brief Use this function to find a joinable network and join it.
1735 * @return An ::EmberStatus value that indicates either the process begin
1736 * successfully or the reason for failure.
1738 EmberStatus emberAfStartSearchForJoinableNetwork(void);
1740 #define emberAfFindUnusedPanIdAndForm() emberAfFindUnusedPanIdAndFormCallback()
1741 #define emberAfStartSearchForJoinableNetwork() emberAfStartSearchForJoinableNetworkCallback()
1744 /** @brief Sets the current network to that of the given index and adds it to
1745 * the stack of networks maintained by the framework. Every call to this API
1746 * must be paired with a subsequent call to ::emberAfPopNetworkIndex.
1749 EmberStatus emberAfPushNetworkIndex(uint8_t networkIndex);
1750 /** @brief Sets the current network to the callback network and adds it to
1751 * the stack of networks maintained by the framework. Every call to this API
1752 * must be paired with a subsequent call to ::emberAfPopNetworkIndex.
1755 EmberStatus emberAfPushCallbackNetworkIndex(void);
1756 /** @brief Sets the current network to that of the given endpoint and adds it
1757 * to the stack of networks maintained by the framework. Every call to this
1758 * API must be paired with a subsequent call to ::emberAfPopNetworkIndex.
1761 EmberStatus emberAfPushEndpointNetworkIndex(chip::EndpointId endpoint);
1762 /** @brief Removes the topmost network from the stack of networks maintained by
1763 * the framework and sets the current network to the new topmost network.
1764 * Every call to this API must be paired with a prior call to
1765 * ::emberAfPushNetworkIndex, ::emberAfPushCallbackNetworkIndex, or
1766 * ::emberAfPushEndpointNetworkIndex.
1769 EmberStatus emberAfPopNetworkIndex(void);
1770 /** @brief Returns the primary endpoint of the given network index or 0xFF if
1771 * no endpoints belong to the network.
1774 uint8_t emberAfPrimaryEndpointForNetworkIndex(uint8_t networkIndex);
1775 /** @brief Returns the primary endpoint of the current network index or 0xFF if
1776 * no endpoints belong to the current network.
1779 uint8_t emberAfPrimaryEndpointForCurrentNetworkIndex(void);
1781 #if !defined(DOXYGEN_SHOULD_SKIP_THIS)
1782 /** @brief Initializes the stack of networks maintained by the framework,
1783 * including setting the default network.
1785 * @return An ::EmberStatus value that indicates either that the network stack
1786 * has been successfully initialized or the reason for failure.
1788 EmberStatus emAfInitializeNetworkIndexStack(void);
1789 void emAfAssertNetworkIndexStackIsEmpty(void);
1791 /** @brief Basic initialization API to be invoked before ::emberAfMain.
1793 void emberAfMainInit(void);
1795 /** @brief This function effectively serves as the application main.
1797 int emberAfMain(MAIN_FUNCTION_PARAMETERS);
1799 /** @} End network utility functions */
1801 /** @} END addtogroup */
1803 #if !defined(DOXYGEN_SHOULD_SKIP_THIS)
1804 #if defined(EMBER_TEST)
1805 #define EMBER_TEST_ASSERT(x) assert(x)
1807 #define EMBER_TEST_ASSERT(x)
1811 /** @brief The maximum power level that can be used by the chip.
1813 // Note: This is a #define for now but could be a real function call in the future.
1814 #define emberAfMaxPowerLevel() (3)
1817 * @brief API for parsing a cluster-specific message. Implemented by
1820 EmberAfStatus emberAfClusterSpecificCommandParse(EmberAfClusterCommand * cmd);