// This file is generated by Simplicity Studio.  Please do not edit manually.
//
//

// This c file provides stubs for all callbacks. These stubs
// will be used in the case where user defined implementations
// of the callbacks have not been provided.
#include "app/framework/include/af.h"
#include "app/framework/util/util.h"    // emberAfGetPageFrom8bitEncodedChanPg()
#include PLATFORM_HEADER
#include "app/framework/plugin/ota-server-policy/ota-server-policy.h"
#include CONFIGURATION_HEADER
#include EMBER_AF_API_TRANSPORT_MQTT



/** @brief Add To Current App Tasks
 *
 * This function is only useful to sleepy end devices.  This function will note
 * the passed item as part of a set of tasks the application has outstanding
 * (e.g. message sent requiring APS acknwoledgement).  This will affect how the
 * application behaves with regard to sleeping and polling.  Until the
 * outstanding task is completed, the device may poll more frequently and sleep
 * less often.
 *
 * @param tasks   Ver.: always
 */
void emberAfAddToCurrentAppTasksCallback(EmberAfApplicationTask tasks)
{
}

/** @brief Allow Network Write Attribute
 *
 * This function is called by the application framework before it writes an
 * attribute in response to a write attribute request from an external device.
 * The value passed into this callback is the value to which the attribute is to
 * be set by the framework.
        Example:	In mirroring simple metering data
 * on an Energy Services Interface (ESI) (formerly called Energy Service Portal
 * (ESP) in SE 1.0).), a mirrored simple meter needs to write read-only
 * attributes on its mirror. The-meter-mirror sample application, located in
 * app/framework/sample-apps, uses this callback to allow the mirrored device to
 * write simple metering attributes on the mirror regardless of the fact that
 * most simple metering attributes are defined as read-only by the ZigBee
 * specification.
        Note:	The ZCL specification does not (as of this
 * writing) specify any permission-level security for writing writeable
 * attributes. As far as the ZCL specification is concerned, if an attribute is
 * writeable, any device that has a link key for the device should be able to
 * write that attribute. Furthermore if an attribute is read only, it should not
 * be written over the air. Thus, if you implement permissions for writing
 * attributes as a feature, you MAY be operating outside the specification. This
 * is unlikely to be a problem for writing read-only attributes, but it may be a
 * problem for attributes that are writeable according to the specification but
 * restricted by the application implementing this callback.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 * @param attributeId   Ver.: always
 * @param mask   Ver.: always
 * @param manufacturerCode   Ver.: always
 * @param value   Ver.: always
 * @param type   Ver.: always
 */
EmberAfAttributeWritePermission emberAfAllowNetworkWriteAttributeCallback(uint8_t endpoint,
                                                                          EmberAfClusterId clusterId,
                                                                          EmberAfAttributeId attributeId,
                                                                          uint8_t mask,
                                                                          uint16_t manufacturerCode,
                                                                          uint8_t* value,
                                                                          uint8_t type)
{
  return EMBER_ZCL_ATTRIBUTE_WRITE_PERMISSION_ALLOW_WRITE_NORMAL; // Default
}

/** @brief Attribute Read Access
 *
 * This function is called whenever the Application Framework needs to check
 * access permission for an attribute read.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 * @param manufacturerCode   Ver.: always
 * @param attributeId   Ver.: always
 */
bool emberAfAttributeReadAccessCallback(uint8_t endpoint,
                                        EmberAfClusterId clusterId,
                                        uint16_t manufacturerCode,
                                        uint16_t attributeId)
{
  return true;
}

/** @brief Attribute Write Access
 *
 * This function is called whenever the Application Framework needs to check
 * access permission for an attribute write.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 * @param manufacturerCode   Ver.: always
 * @param attributeId   Ver.: always
 */
bool emberAfAttributeWriteAccessCallback(uint8_t endpoint,
                                         EmberAfClusterId clusterId,
                                         uint16_t manufacturerCode,
                                         uint16_t attributeId)
{
  return true;
}

/** @brief Groups Cluster Clear Group Table
 *
 * This function is called by the framework when the application should clear
 * the group table.
 *
 * @param endpoint The endpoint.  Ver.: always
 */
void emberAfGroupsClusterClearGroupTableCallback(uint8_t endpoint)
{
}

/** @brief Scenes Cluster ClearSceneTable
 *
 * This function is called by the framework when the application should clear
 * the scene table.
 *
 * @param endpoint The endpoint.  Ver.: always
 */
void emberAfScenesClusterClearSceneTableCallback(uint8_t endpoint)
{
}

/** @brief Key Establishment Cluster Client Command Received
 *
 * This function is called by the application framework when a server-to-client
 * key establishment command is received but has yet to be handled by the
 * framework code.  This function should return a bool value indicating whether
 * the command has been handled by the application code and should not be
 * further processed by the framework.
 *
 * @param cmd   Ver.: always
 */
bool emberAfKeyEstablishmentClusterClientCommandReceivedCallback(EmberAfClusterCommand *cmd)
{
  return false;
}

/** @brief Cluster Init
 *
 * This function is called when a specific cluster is initialized. It gives the
 * application an opportunity to take care of cluster initialization procedures.
 * It is called exactly once for each endpoint where cluster is present.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 */
void emberAfClusterInitCallback(uint8_t endpoint,
											EmberAfClusterId clusterId)
{
}

/** @brief Default Response
 *
 * This function is called by the application framework when a Default Response
 * command is received from an external device.  The application should return
 * true if the message was processed or false if it was not.
 *
 * @param clusterId The cluster identifier of this response.  Ver.: always
 * @param commandId The command identifier to which this is a response.  Ver.:
 * always
 * @param status Specifies either SUCCESS or the nature of the error that was
 * detected in the received command.  Ver.: always
 */
bool emberAfDefaultResponseCallback(EmberAfClusterId clusterId,
                                    uint8_t commandId,
                                    EmberAfStatus status)
{
  return false;
}

/** @brief Discover Attributes Response
 *
 * This function is called by the application framework when a Discover
 * Attributes Response or Discover Attributes Extended Response command is
 * received from an external device.  The Discover Attributes Response command
 * contains a bool indicating if discovery is complete and a list of zero or
 * more attribute identifier/type records. The final argument indicates whether
 * the response is in the extended format or not.  The application should return
 * true if the message was processed or false if it was not.
 *
 * @param clusterId The cluster identifier of this response.  Ver.: always
 * @param discoveryComplete Indicates whether there are more attributes to be
 * discovered.  true if there are no more attributes to be discovered.  Ver.:
 * always
 * @param buffer Buffer containing the list of attribute identifier/type
 * records.  Ver.: always
 * @param bufLen The length in bytes of the list.  Ver.: always
 * @param extended Indicates whether the response is in the extended format or
 * not.  Ver.: always
 */
bool emberAfDiscoverAttributesResponseCallback(EmberAfClusterId clusterId,
                                               bool discoveryComplete,
                                               uint8_t *buffer,
                                               uint16_t bufLen,
                                               bool extended)
{
  return false;
}

/** @brief Discover Commands Generated Response
 *
 * This function is called by the framework when Discover Commands Generated
 * Response is received.
 *
 * @param clusterId The cluster identifier of this response.  Ver.: always
 * @param manufacturerCode Manufacturer code  Ver.: always
 * @param discoveryComplete Indicates whether there are more commands to be
 * discovered.  Ver.: always
 * @param commandIds Buffer containing the list of command identifiers.  Ver.:
 * always
 * @param commandIdCount The length of bytes of the list, whish is the same as
 * the number of identifiers.  Ver.: always
 */
bool emberAfDiscoverCommandsGeneratedResponseCallback(EmberAfClusterId clusterId,
                                                      uint16_t manufacturerCode,
                                                      bool discoveryComplete,
                                                      uint8_t *commandIds,
                                                      uint16_t commandIdCount)
{
  return false;
}

/** @brief Discover Commands Received Response
 *
 * This function is called by the framework when Discover Commands Received
 * Response is received.
 *
 * @param clusterId The cluster identifier of this response.  Ver.: always
 * @param manufacturerCode Manufacturer code  Ver.: always
 * @param discoveryComplete Indicates whether there are more commands to be
 * discovered.  Ver.: always
 * @param commandIds Buffer containing the list of command identifiers.  Ver.:
 * always
 * @param commandIdCount The length of bytes of the list, whish is the same as
 * the number of identifiers.  Ver.: always
 */
bool emberAfDiscoverCommandsReceivedResponseCallback(EmberAfClusterId clusterId,
                                                     uint16_t manufacturerCode,
                                                     bool discoveryComplete,
                                                     uint8_t *commandIds,
                                                     uint16_t commandIdCount)
{
  return false;
}

/** @brief Eeprom Init
 *
 * Tells the system to initialize the EEPROM if it is not already initialized.
 *
 */
void emberAfEepromInitCallback(void)
{
}

/** @brief Eeprom Note Initialized State
 *
 * Records the state of the EEPROM so that an intelligent driver (like the
 * EEPROM plugin) can re-initialize the driver prior to any calls to it.
 *
 * @param state The state of the EEPROM, false=re-initalization needed,
 * true=no-re-init needed  Ver.: always
 */
void emberAfEepromNoteInitializedStateCallback(bool state)
{
}

/** @brief Eeprom Shutdown
 *
 * Tells the system to shutdown the EEPROM if it is not already shutdown.
 *
 */
void emberAfEepromShutdownCallback(void)
{
}

/** @brief Groups Cluster Endpoint In Group
 *
 * This function is called by the framework when it needs to determine if an
 * endpoint is a member of a group.  The application should return true if the
 * endpoint is a member of the group and false otherwise.
 *
 * @param endpoint The endpoint.  Ver.: always
 * @param groupId The group identifier.  Ver.: always
 */
bool emberAfGroupsClusterEndpointInGroupCallback(uint8_t endpoint,
                                                 uint16_t groupId)
{
  return false;
}

/** @brief External Attribute Read
 *
 * Like emberAfExternalAttributeWriteCallback above, this function is called
 * when the framework needs to read an attribute that is not stored within the
 * Application Framework's data structures.
        All of the important
 * information about the attribute itself is passed as a pointer to an
 * EmberAfAttributeMetadata struct, which is stored within the application and
 * used to manage the attribute. A complete description of the
 * EmberAfAttributeMetadata struct is provided in
 * app/framework/include/af-types.h
        This function assumes that the
 * application is able to read the attribute, write it into the passed buffer,
 * and return immediately. Any attributes that require a state machine for
 * reading and writing are not really candidates for externalization at the
 * present time. The Application Framework does not currently include a state
 * machine for reading or writing attributes that must take place across a
 * series of application ticks. Attributes that cannot be read in a timely
 * manner should be stored within the Application Framework and updated
 * occasionally by the application code from within the
 * emberAfMainTickCallback.
        If the application was successfully able to
 * read the attribute and write it into the passed buffer, it should return a
 * value of EMBER_ZCL_STATUS_SUCCESS. Any other return value indicates the
 * application was not able to read the attribute.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 * @param attributeMetadata   Ver.: always
 * @param manufacturerCode   Ver.: always
 * @param buffer   Ver.: always
 */
EmberAfStatus emberAfExternalAttributeReadCallback(uint8_t endpoint,
                                                   EmberAfClusterId clusterId,
                                                   EmberAfAttributeMetadata *attributeMetadata,
                                                   uint16_t manufacturerCode,
                                                   uint8_t *buffer)
{
  return EMBER_ZCL_STATUS_FAILURE;
}

/** @brief External Attribute Write
 *
 * This function is called whenever the Application Framework needs to write an
 * attribute which is not stored within the data structures of the Application
 * Framework itself. One of the new features in Version 2 is the ability to
 * store attributes outside the Framework. This is particularly useful for
 * attributes that do not need to be stored because they can be read off the
 * hardware when they are needed, or are stored in some central location used by
 * many modules within the system. In this case, you can indicate that the
 * attribute is stored externally. When the framework needs to write an external
 * attribute, it makes a call to this callback.
        This callback is very
 * useful for host micros which need to store attributes in persistent memory.
 * Because each host micro (used with an Ember NCP) has its own type of
 * persistent memory storage, the Application Framework does not include the
 * ability to mark attributes as stored in flash the way that it does for Ember
 * SoCs like the EM35x. On a host micro, any attributes that need to be stored
 * in persistent memory should be marked as external and accessed through the
 * external read and write callbacks. Any host code associated with the
 * persistent storage should be implemented within this callback.
        All of
 * the important information about the attribute itself is passed as a pointer
 * to an EmberAfAttributeMetadata struct, which is stored within the application
 * and used to manage the attribute. A complete description of the
 * EmberAfAttributeMetadata struct is provided in
 * app/framework/include/af-types.h.
        This function assumes that the
 * application is able to write the attribute and return immediately. Any
 * attributes that require a state machine for reading and writing are not
 * candidates for externalization at the present time. The Application Framework
 * does not currently include a state machine for reading or writing attributes
 * that must take place across a series of application ticks. Attributes that
 * cannot be written immediately should be stored within the Application
 * Framework and updated occasionally by the application code from within the
 * emberAfMainTickCallback.
        If the application was successfully able to
 * write the attribute, it returns a value of EMBER_ZCL_STATUS_SUCCESS. Any
 * other return value indicates the application was not able to write the
 * attribute.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 * @param attributeMetadata   Ver.: always
 * @param manufacturerCode   Ver.: always
 * @param buffer   Ver.: always
 */
EmberAfStatus emberAfExternalAttributeWriteCallback(uint8_t endpoint,
                                                    EmberAfClusterId clusterId,
                                                    EmberAfAttributeMetadata *attributeMetadata,
                                                    uint16_t manufacturerCode,
                                                    uint8_t *buffer)
{
	return EMBER_ZCL_STATUS_FAILURE;
}

/** @brief Get Current App Tasks
 *
 * This function is only useful to sleepy end devices.  This function will
 * return the set of tasks the application has outstanding.  These tasks affect
 * how the application behaves with regard to sleeping and polling.
 *
 */
EmberAfApplicationTask emberAfGetCurrentAppTasksCallback(void)
{
  return 0;
}

/** @brief Get Current Poll Control
 *
 * This function will retrieve the current poll control that the system is using
 * for the current network.  This is determined by examining all the scheduled
 * events and obtaining the most restrictive poll control context across all
 * events.  The most restrictive poll control is EMBER_AF_SHORT_POLL followed by
 * EMBER_AF_LONG_POLL.
 *
 */
EmberAfEventPollControl emberAfGetCurrentPollControlCallback(void)
{
  return EMBER_AF_LONG_POLL;
}

/** @brief Get Current Poll Interval Ms
 *
 * This function is only useful to end devices.  This function will return the
 * current poll interval (in milliseconds) for the current network.  This
 * interval is the maximum amount of time a child is currently waiting between
 * polls of its parent.
 *
 */
uint32_t emberAfGetCurrentPollIntervalMsCallback(void)
{
  return 0;
}

/** @brief Get Current Poll Interval Qs
 *
 * This function is only useful to end devices.  This function will return the
 * current poll interval (in quarter seconds) for the current network.  This
 * interval is the maximum amount of time a child is currently waiting between
 * polls of its parent.
 *
 */
uint32_t emberAfGetCurrentPollIntervalQsCallback(void)
{
  return 0;
}

/** @brief Get Current Sleep Control
 *
 * This function will retrieve the current sleep control that the system is
 * using.  This is determined by examining all the scheduled events and
 * obtaining the most restrictive sleep control context across all events.  The
 * most restrictive sleep control is EMBER_AF_STAY_AWAKE followed by
 * EMBER_AF_OK_TO_SLEEP.
 *
 */
EmberAfEventSleepControl emberAfGetCurrentSleepControlCallback(void)
{
  return EMBER_AF_OK_TO_SLEEP;
}

/** @brief Get Current Time
 *
 * This callback is called when device attempts to get current time from the
 * hardware. If this device has means to retrieve exact time, then this method
 * should implement it. If the callback can't provide the exact time it should
 * return 0 to indicate failure. Default action is to return 0, which indicates
 * that device does not have access to real time.
 *
 */
uint32_t emberAfGetCurrentTimeCallback(void)
{
  return 0;
}

/** @brief Get Default Poll Control
 *
 * This function will retrieve the default poll control for the current network
 * as previously set by emberAfSetDefaultPollControlCallback().  The default
 * poll control will limit whether the network can long poll.
 *
 */
EmberAfEventPollControl emberAfGetDefaultPollControlCallback(void)
{
  return EMBER_AF_LONG_POLL;
}

/** @brief Get Default Sleep Control
 *
 * This function will retrieve the default sleep control the system is using as
 * previously set by emberAfSetDefaultSleepControlCallback().  The default sleep
 * control will limit whether the device can sleep.
 *
 */
EmberAfEventSleepControl emberAfGetDefaultSleepControlCallback(void)
{
  return EMBER_AF_OK_TO_SLEEP;
}

/** @brief Get Endpoint By Index
 *
 * Get the endpoint number based on the passed index.  By default the framework
 * handles this by managing endpoints based on the precompiled configuration
 * defined in AppBuilder.  This callback can override this behavior at runtime
 * and provide additional endpoints or different data than the compiled values. 
 * If the index is overridden than the callback shall return true and set the
 * endpointReturn parameter accordingly. A value of 0xFF means the endpoint
 * doesn't exist at that index.
        Otherwise false must be returned by the
 * callback and the default framework behavior will be executed.  This is only
 * applicable to the SOC devices.
 *
 * @param index The index of the endpoint.  Ver.: always
 * @param endpointReturn The value of endpoint.  Ver.: always
 */
bool emberAfGetEndpointByIndexCallback(uint8_t index,
                                       uint8_t* endpointReturn)
{
  return false;
}

/** @brief Get Endpoint Description
 *
 * This callback is called by the framework whenever it receives a ZDO request
 * to enumerate the details about an endpoint.  By default the framework
 * provides the information based on the precompiled endpoint information as
 * defined in AppBuilder.  This callback can override that behavior at runtime
 * and return different information.  If the endpoint information is being
 * overridden then the callback must return true.  Otherwise it should return
 * false, which allows the framework to perform its default behavior.  This is
 * only applicable to SOC devices.
 *
 * @param endpoint The endpoint number that is being queried.  Ver.: always
 * @param result This is a pointer to a data structure where the endpoint
 * information is written if the callback is providing the information.  Ver.:
 * always
 */
bool emberAfGetEndpointDescriptionCallback(uint8_t endpoint,
                                           EmberEndpointDescription* result)
{
  return false;
}

/** @brief Get Endpoint Info
 *
 * This function is a callback to an application implemented endpoint that
 * operates outside the normal application framework.  When the framework wishes
 * to perform operations with that endpoint it uses this callback to retrieve
 * the endpoint's information.  If the endpoint exists and the application can
 * provide data then true shall be returned.  Otherwise the callback must return
 * false.
 *
 * @param endpoint The endpoint to retrieve data for.  Ver.: always
 * @param returnNetworkIndex The index corresponding to the ZigBee network the
 * endpoint belongs to.  If not using a multi-network device, 0 must be
 * returned.  Otherwise on a multi-network device the stack will switch to this
 * network before sending the message.  Ver.: always
 * @param returnEndpointInfo A pointer to a data struct that will be written
 * with information about the endpoint.  Ver.: always
 */
bool emberAfGetEndpointInfoCallback(uint8_t endpoint,
                                    uint8_t* returnNetworkIndex,
                                    EmberAfEndpointInfoStruct* returnEndpointInfo)
{
  return false;
}

/** @brief Get Long Poll Interval Ms
 *
 * This function is only useful to end devices.  This function will return the
 * long poll interval (in milliseconds) for the current network.  This interval
 * is the maximum amount of time a child will wait between polls of its parent
 * when it is not expecting data.
 *
 */
uint32_t emberAfGetLongPollIntervalMsCallback(void)
{
  return 0;
}

/** @brief Get Long Poll Interval Qs
 *
 * This function is only useful to end devices.  This function will return the
 * long poll interval (in quarter seconds) for the current network.  This
 * interval is the maximum amount of time a child will wait between polls of its
 * parent when it is not expecting data.
 *
 */
uint32_t emberAfGetLongPollIntervalQsCallback(void)
{
  return 0;
}

/** @brief Get Short Poll Interval Ms
 *
 * This function is only useful to sleepy end devices.  This function will
 * return the short poll interval (in milliseconds) for the current network. 
 * This interval is the maximum amount of time a child will wait between polls
 * of its parent when it is expecting data.
 *
 */
uint16_t emberAfGetShortPollIntervalMsCallback(void)
{
  return 0;
}

/** @brief Get Short Poll Interval Qs
 *
 * This function is only useful to sleepy end devices.  This function will
 * return the short poll interval (in quarter seconds) for the current network. 
 * This interval is the maximum amount of time a child will wait between polls
 * of its parent when it is expecting data.
 *
 */
uint16_t emberAfGetShortPollIntervalQsCallback(void)
{
  return 0;
}

/** @brief Get Wake Timeout Bitmask
 *
 * This function is only useful to sleepy end devices.  This function will
 * return the wake timeout bitmask for the current network.  The bitmask
 * determines which tasks will timeout automatically and which tasks require
 * manual removal from the task list.
 *
 */
EmberAfApplicationTask emberAfGetWakeTimeoutBitmaskCallback(void)
{
  return 0;
}

/** @brief Get Wake Timeout Ms
 *
 * This function is only useful to sleepy end devices.  This function will
 * return the wake timeout (in milliseconds) for the current network.  This
 * timeout is the maximum amount of time a child will wait for a task in the
 * wake bitmask to finish.  While waiting, the device will short poll.
 *
 */
uint16_t emberAfGetWakeTimeoutMsCallback(void)
{
  return 0;
}

/** @brief Get Wake Timeout Qs
 *
 * This function is only useful to sleepy end devices.  This function will
 * return the wake timeout (in quarter seconds) for the current network.  This
 * timeout is the maximum amount of time a child will wait for a task in the
 * wake bitmask to finish.  While waiting, the device will short poll.
 *
 */
uint16_t emberAfGetWakeTimeoutQsCallback(void)
{
  return 0;
}

/** @brief Initiate Inter Pan Key Establishment
 *
 * This function is called by the framework to initiate key establishment with a
 * remote device on a different PAN.  The application should return
 * EMBER_SUCCESS if key establishment was initiated successfully.  The
 * application should call ::emberAfInterPanKeyEstablishmentCallback as events
 * occur.
 *
 * @param panId The PAN id of the remote device.  Ver.: always
 * @param eui64 The EUI64 of the remote device.  Ver.: always
 */
EmberStatus emberAfInitiateInterPanKeyEstablishmentCallback(EmberPanId panId,
                                                            const EmberEUI64 eui64)
{
  return EMBER_LIBRARY_NOT_PRESENT;
}

/** @brief Initiate Key Establishment
 *
 * This function is called by the framework to initiate key establishment with a
 * remote device.  The application should return EMBER_SUCCESS if key
 * establishment was initiated successfully.  The application should call
 * ::emberAfKeyEstablishmentCallback as events occur.
 *
 * @param nodeId The node id of the remote device.  Ver.: always
 * @param endpoint The endpoint on the remote device.  Ver.: always
 */
EmberStatus emberAfInitiateKeyEstablishmentCallback(EmberNodeId nodeId,
                                                    uint8_t endpoint)
{
  return EMBER_LIBRARY_NOT_PRESENT;
}

/** @brief Initiate Partner Link Key Exchange
 *
 * This function is called by the framework to initiate a partner link key
 * exchange with a remote device.  The application should return EMBER_SUCCESS
 * if the partner link key exchange was initiated successfully.  When the
 * partner link key exchange completes, the application should call the given
 * callback.
 *
 * @param target The node id of the remote device.  Ver.: always
 * @param endpoint The key establishment endpoint of the remote device.  Ver.:
 * always
 * @param callback The callback that should be called when the partner link key
 * exchange completse.  Ver.: always
 */
EmberStatus emberAfInitiatePartnerLinkKeyExchangeCallback(EmberNodeId target,
                                                          uint8_t endpoint,
                                                          EmberAfPartnerLinkKeyExchangeCallback *callback)
{
  return EMBER_LIBRARY_NOT_PRESENT;
}

/** @brief Inter Pan Key Establishment
 *
 * A callback by the key-establishment code to indicate an event has occurred. 
 * For error codes this is purely a notification.  For non-error status codes
 * (besides LINK_KEY_ESTABLISHED), it is the application's chance to allow or
 * disallow the operation.  If the application returns true then the key
 * establishment is allowed to proceed.  If it returns false, then key
 * establishment is aborted.  LINK_KEY_ESTABLISHED is a notification of success.
 *
 * @param status   Ver.: always
 * @param amInitiator   Ver.: always
 * @param panId   Ver.: always
 * @param eui64   Ver.: always
 * @param delayInSeconds   Ver.: always
 */
bool emberAfInterPanKeyEstablishmentCallback(EmberAfKeyEstablishmentNotifyMessage status,
                                             bool amInitiator,
                                             EmberPanId panId,
                                             const EmberEUI64 eui64,
                                             uint8_t delayInSeconds)
{
  return true;
}

/** @brief Interpan Send Message
 *
 * This function will send a raw MAC message with interpan frame format using
 * the passed parameters.
 *
 * @param header Interpan header info  Ver.: always
 * @param messageLength The length of the message received or to send  Ver.:
 * always
 * @param message The message data received or to send.  Ver.: always
 */
EmberStatus emberAfInterpanSendMessageCallback(EmberAfInterpanHeader* header,
                                               uint16_t messageLength,
                                               uint8_t* message)
{
  return EMBER_LIBRARY_NOT_PRESENT;
}

/** @brief Key Establishment
 *
 * A callback by the key-establishment code to indicate an event has occurred. 
 * For error codes this is purely a notification.  For non-error status codes
 * (besides LINK_KEY_ESTABLISHED), it is the application's chance to allow or
 * disallow the operation.  If the application returns true then the key
 * establishment is allowed to proceed.  If it returns false, then key
 * establishment is aborted.  LINK_KEY_ESTABLISHED is a notification of success.
 *
 * @param status   Ver.: always
 * @param amInitiator   Ver.: always
 * @param partnerShortId   Ver.: always
 * @param delayInSeconds   Ver.: always
 */
bool emberAfKeyEstablishmentCallback(EmberAfKeyEstablishmentNotifyMessage status,
                                     bool amInitiator,
                                     EmberNodeId partnerShortId,
                                     uint8_t delayInSeconds)
{
  return true;
}

/** @brief Main Init
 *
 * This function is called from the application's main function. It gives the
 * application a chance to do any initialization required at system startup. Any
 * code that you would normally put into the top of the application's main()
 * routine should be put into this function. This is called before the clusters,
 * plugins, and the network are initialized so some functionality is not yet
 * available.
        Note: No callback in the Application Framework is
 * associated with resource cleanup. If you are implementing your application on
 * a Unix host where resource cleanup is a consideration, we expect that you
 * will use the standard Posix system calls, including the use of atexit() and
 * handlers for signals such as SIGTERM, SIGINT, SIGCHLD, SIGPIPE and so on. If
 * you use the signal() function to register your signal handler, please mind
 * the returned value which may be an Application Framework function. If the
 * return value is non-null, please make sure that you call the returned
 * function from your handler to avoid negating the resource cleanup of the
 * Application Framework itself.
 *
 */
void emberAfMainInitCallback(void)
{
}

/** @brief Main Tick
 *
 * Whenever main application tick is called, this callback will be called at the
 * end of the main tick execution.
 *
 */
void emberAfMainTickCallback(void)
{
}

/** @brief Scenes Cluster Make Invalid
 *
 * This function is called to invalidate the valid attribute in the Scenes
 * cluster.
 *
 * @param endpoint   Ver.: always
 */
EmberAfStatus emberAfScenesClusterMakeInvalidCallback(uint8_t endpoint)
{
  return EMBER_ZCL_STATUS_UNSUP_CLUSTER_COMMAND;
}

/** @brief Ncp Init
 *
 * This function is called when the network coprocessor is being initialized,
 * either at startup or upon reset.  It provides applications on opportunity to
 * perform additional configuration of the NCP.  The function is always called
 * twice when the NCP is initialized.  In the first invocation, memoryAllocation
 * will be true and the application should only issue EZSP commands that affect
 * memory allocation on the NCP.  For example, tables on the NCP can be resized
 * in the first call.  In the second invocation, memoryAllocation will be false
 * and the application should only issue EZSP commands that do not affect memory
 * allocation.  For example, tables on the NCP can be populated in the second
 * call.  This callback is not called on SoCs.
 *
 * @param memoryAllocation   Ver.: always
 */
void emberAfNcpInitCallback(bool memoryAllocation)
{
}

/** @brief Ncp Is Awake Isr
 *
 * This function is called IN ISR CONTEXT.  It notes that the NCP is awake after
 * sleeping.  Care should be taken to do minimal processing in this ISR handler
 * function.
 *
 */
void emberAfNcpIsAwakeIsrCallback(void)
{
}

/** @brief Network Key Update Complete
 *
 * This is called by the framework when a network key update operation started
 * by the trust center is complete.
 *
 * @param status   Ver.: always
 */
void emberAfNetworkKeyUpdateCompleteCallback(EmberStatus status)
{
}

/** @brief Ota Bootload
 *
 * The platform specific routine to bootload the device from a ZigBee
 * over-the-air upgrade file.
 *
 * @param id A pointer to the structure that contains the information about what
 * OTA image to bootload.  Ver.: always
 * @param ncpUpgradeTagId The tag ID of the upgrade data that will be used to
 * bootload the device.  Ver.: always
 */
uint8_t emberAfOtaBootloadCallback(const EmberAfOtaImageId* id,
                                   uint16_t ncpUpgradeTagId)
{
  // Please implement me
  emberAfCorePrintln("Not supported.");
  return 1;
}

/** @brief Ota Client Bootload
 *
 * This callback is fired when the OTA Client recevies a command to bootload the
 * newly downloaded OTA image.  This callback will perform the platform specific
 * to bootload their device.
 *
 * @param id This is the identifier relating to the image that has been
 * downloaded and is ready for bootload.  Ver.: always
 */
void emberAfOtaClientBootloadCallback(const EmberAfOtaImageId* id)
{
  // Any final preperation prior to the bootload should be done here.
  // It is assumed that the device will reset in most all cases.
  // Please implement me.
}

/** @brief Ota Client Custom Verify
 *
 * This callback is executed by the OTA client after the signature verification
 * has successfully completed.  It allows the device to do its own custom
 * verification of the image (such as verifying that the EBL is intact).
 *
 * @param newVerification This indicates if a new verification should be
 * started.  Ver.: always
 * @param id This is ID of the image to be verified.  Ver.: always
 */
EmberAfImageVerifyStatus emberAfOtaClientCustomVerifyCallback(bool newVerification,
                                                              const EmberAfOtaImageId* id)
{
  // Manufacturing specific checks can be made to the image in this function to
  // determine if it is valid.  This function is called AFTER cryptographic 
  // checks have passed.  If the cryptographic checks failed, this function will
  // never be called.
  
  // The function shall return one of the following based on its own 
  // verification process.
  // 1) EMBER_AF_IMAGE_GOOD - the image has passed all checks
  // 2) EMBER_AF_IMAGE_BAD  - the image is not valid 
  // 3) EMBER_AF_IMAGE_VERIFY_IN_PROGRESS - the image is valid so far, but more
  //      checks are needed.  This callback shall be re-executed later to 
  //      continue verification.  This allows other code in the framework to run.
  return EMBER_AF_IMAGE_GOOD;
}

/** @brief Ota Client Download Complete
 *
 * This callback indicates that the OTA client has completed the download of a
 * file.  If the file has been completely downloaded and cryptographic checks
 * have been turned on, then those will be performed prior to this callback and
 * that outcome included in the 'success' result.  On failure, this callback is
 * merely informative, and the return type is ignored.  On succesful download,
 * this callback allows the client to perform any additional verification of the
 * downloaded image and return that result to the OTA server.
 *
 * @param success This indicates the success or failure of the download and
 * cryptographic verification process (if applicable).  Ver.: always
 * @param id This is the image identifier information that corresponds to the
 * download result.  Ver.: always
 */
bool emberAfOtaClientDownloadCompleteCallback(EmberAfOtaDownloadResult success,
                                              const EmberAfOtaImageId* id)
{
  // At this point the image has been completely downloaded and cryptographic 
  // checks (if applicable) have been performed.

  if (!success) {
    emberAfOtaBootloadClusterPrintln("Download failed.");
    return true;   // return value is ignored
  }
  
  // This is for any additional validation that needs to be performed
  // on the image by the application.
  
  // The results of checks here will be returned back to the OTA server
  // in the Upgrade End request.
  return true;
}

/** @brief Ota Client Incoming Message Raw
 *
 * This callback is for processing incoming messages for the Over-the-air
 * bootload cluster client.  ZCL will not process the message and instead hand
 * the raw over the air data to the callback for its own processing.
 *
 * @param message A pointer to the structure containing the message buffer and
 * other information about it.  Ver.: always
 */
bool emberAfOtaClientIncomingMessageRawCallback(EmberAfClusterCommand *message)
{
  return false;
}

/** @brief Ota Client Start
 *
 * This callback should be called when the profile specific registration has
 * completed successfully.  It will start the client's state machine that will
 * find the OTA server, query it for the next image, download the image, wait
 * for the bootload message, and kick off the bootload.
 *
 */
void emberAfOtaClientStartCallback(void)
{
}

/** @brief Ota Client Version Info
 *
 * This function is called by the OTA client when a new query will occur to the
 * server asking what the next version of firmware is.  The client can inform
 * the cluster software as to what information to use in the query (and
 * subsequent download).
 *
 * @param currentImageInfo This is the information to use in the next query by
 * the client cluster code.  It contains the manufacturer ID, image type ID, and
 * the firmware version to be specified in the query message sent to the server.
 *  Ver.: always
 * @param hardwareVersion This is a pointer to the hardware version to use in
 * the query.  If no hardware version should be used, then
 * EMBER_AF_INVALID_HARDWARE_VERSION should be used.  Ver.: always
 */
void emberAfOtaClientVersionInfoCallback(EmberAfOtaImageId* currentImageInfo,
                                         uint16_t* hardwareVersion)
{
  // Customer will fill in the image info with their manufacturer ID,
  // image type ID, and current software version number.
  // The deviceSpecificFileEui64 can be ignored.

  // It may be necessary to dynamically determine this by talking to
  // another device, as is the case with a host talking to an NCP device.

  // However, this routine will be called repeatedly so it may be wise
  // to cache the data!

/* This is commented out since the #defines below are not defined.

  if (currentImageInfo != NULL) {
    MEMSET(currentImageInfo, 0, sizeof(EmberAfOtaImageId));
    currentImageInfo->manufacturerId  = EMBER_AF_MANUFACTURER_CODE;
    currentImageInfo->imageTypeId     = EMBER_AF_IMAGE_TYPE_ID;
    currentImageInfo->firmwareVersion = EMBER_AF_CUSTOM_FIRMWARE_VERSION;
  }

  if (hardwareVersion != NULL) {
    *hardwareVersion = EMBER_AF_INVALID_HARDWARE_VERSION;
  }

  assert(false);
*/
}

/** @brief Ota Storage Close
 *
 * This callback shuts down the ZigBee Over-the-air storage module.
 *
 */
void emberAfOtaStorageCloseCallback(void)
{
  // Please implement me.
  assert(false);
}

/** @brief Ota Storage Driver Download Finish
 *
 * This callback defines the low-level means by which a device records the final
 * offset value of the download image.
 *
 * @param offset The value of the final offset of the image download.  Ver.:
 * always
 */
void emberAfOtaStorageDriverDownloadFinishCallback(uint32_t offset)
{
  // The storage driver and the rest of the OTA bootload code will not function correctly unless it is implemnted.
  // Please implement me.
  assert(false);
}

/** @brief Ota Storage Driver Init
 *
 * The initialization code for the OTA storage driver.
 *
 */
bool emberAfOtaStorageDriverInitCallback(void)
{
  // The storage driver and the rest of the OTA bootload code will not function correctly unless it is implemnted.
  // Please implement me.
  assert(false);
  return false;
}

/** @brief Ota Storage Driver Invalidate Image
 *
 * This callback invalidates the image stored on disk so that it will not be
 * bootloaded, and it will not be a valid image that is in the middle of
 * downloading.
 *
 */
EmberAfOtaStorageStatus emberAfOtaStorageDriverInvalidateImageCallback(void)
{
  // The storage driver and the rest of the OTA bootload code will not function correctly unless it is implemnted.
  // Please implement me.
  assert(false);
  return EMBER_AF_OTA_STORAGE_ERROR;
}

/** @brief Ota Storage Driver Read
 *
 * This callback defines the low-level means by which a device reads from the
 * OTA storage device.
 *
 * @param offset The address offset from the start of the storage device where
 * data is to be read.  Ver.: always
 * @param length The length of the data to be read from the storage device. 
 * Ver.: always
 * @param returnData A pointer where the data read from the device should be
 * written to.  Ver.: always
 */
bool emberAfOtaStorageDriverReadCallback(uint32_t offset,
                                         uint32_t length,
                                         uint8_t* returnData)
{
  // The storage driver and the rest of the OTA bootload code will not function correctly unless it is implemnted.
  // Please implement me.
  assert(false);
  return false;
}

/** @brief Ota Storage Driver Retrieve Last Stored Offset
 *
 * This callback defines the low-level means by which a device retrieves the
 * last persistently recorded download offset.  This may be different than last
 * actual download offset.
 *
 */
uint32_t emberAfOtaStorageDriverRetrieveLastStoredOffsetCallback(void)
{
  // The storage driver and the rest of the OTA bootload code will not function correctly unless it is implemnted.
  // Please implement me.
  assert(false);
  return 0;
}

/** @brief Ota Storage Driver Write
 *
 * This callback defines the low-level means by which a device reads from the
 * OTA storage device.
 *
 * @param dataToWrite A pointer to the data that will be written to the storage
 * device.  Ver.: always
 * @param offset The address offset from the start of the storage device where
 * data will be written.  Ver.: always
 * @param length The length of the data to be written to the storage device. 
 * Ver.: always
 */
bool emberAfOtaStorageDriverWriteCallback(const uint8_t* dataToWrite,
                                          uint32_t offset,
                                          uint32_t length)
{
  // The storage driver and the rest of the OTA bootload code will not function correctly unless it is implemnted.
  // Please implement me.
  assert(false);
  return false;
}

/** @brief Partner Link Key Exchange Request
 *
 * This function is called by the framework on SOC platforms when a remote node
 * requests a partner link key exchange.  The application should return
 * EMBER_SUCCESS to accept the request or any other status to reject it.  On
 * network coprocessor platforms, this function will not be called because the
 * NCP handles partner link key exchange requests based on the binding policy.
 *
 * @param partner The EUI of the remote node.  Ver.: always
 */
EmberStatus emberAfPartnerLinkKeyExchangeRequestCallback(EmberEUI64 partner)
{
  return EMBER_LIBRARY_NOT_PRESENT;
}

/** @brief Partner Link Key Exchange Response
 *
 * This function is called by the framework when a remote node requests a
 * partner link key exchange.  The application should return true to accept the
 * request or false to reject it.  On network coprocessor platforms, this
 * function will not be called because the NCP handles partner link key exchange
 * requests based on the binding policy.
 *
 * @param sender The EUI of the remote node.  Ver.: always
 * @param status The ZDO response status.  Ver.: always
 */
void emberAfPartnerLinkKeyExchangeResponseCallback(EmberNodeId sender,
                                                   EmberZdoStatus status)
{
}

/** @brief Performing Key Establishment
 *
 * This function is called by the framework to determine if the device is
 * performing key establishment.  The application should return true if key
 * establishment is in progress.
 *
 */
bool emberAfPerformingKeyEstablishmentCallback(void)
{
  return false;
}

/** @brief Reset To Factory Defaults
 *
 * This function is called by the Basic server plugin when a request to reset
 * to factory defaults is received. The plugin will reset attributes managed by
 * the framework to their default values. The application should perform any
 * other necessary reset-related operations in this callback, including
 * resetting any externally-stored attributes.
 *
 * @param endpoint   Ver.: always
 */
void emberAfPluginBasicResetToFactoryDefaultsCallback(uint8_t endpoint)
{
}

/** @brief Button Event
 *
 * This allows another module to get notification when a button is pressed and
 * released but the button joining plugin did not handle it. This callback is
 * NOT called in ISR context so there are no restrictions on what code can
 * execute.
 *
 * @param buttonNumber The button number that was pressed. Ver.: always
 * @param buttonPressDurationMs The length of time button was held down before
 * it was released. Ver.: always
 */
void emberAfPluginButtonJoiningButtonEventCallback(uint8_t buttonNumber,
                                                   uint32_t buttonPressDurationMs)
{
}

/** @brief Compute Pwm from HSV
 *
 * This function is called from the color server when it is time for the PWMs to
 * be driven with a new value from the HSV values.
 *
 * @param endpoint The identifying endpoint Ver.: always
 */
void emberAfPluginColorControlServerComputePwmFromHsvCallback(uint8_t endpoint)
{
}

/** @brief Compute Pwm from HSV
 *
 * This function is called from the color server when it is time for the PWMs to
 * be driven with a new value from the color temperature.
 *
 * @param endpoint The identifying endpoint Ver.: always
 */
void emberAfPluginColorControlServerComputePwmFromTempCallback(uint8_t endpoint)
{
}

/** @brief Compute Pwm from HSV
 *
 * This function is called from the color server when it is time for the PWMs to
 * be driven with a new value from the color X and color Y values.
 *
 * @param endpoint The identifying endpoint Ver.: always
 */
void emberAfPluginColorControlServerComputePwmFromXyCallback(uint8_t endpoint)
{
}

/** @brief Broadcast Sent
 *
 * This function is called when a new MTORR broadcast has been successfully
 * sent by the concentrator plugin.
 *
 */
void emberAfPluginConcentratorBroadcastSentCallback(void)
{
}

/** @brief Rollover
 *
 * This function is called every time a counter exceeds its threshold.
 *
 * @param type The counter that rolled over Ver.: always
 */
void emberAfPluginCountersRolloverCallback(EmberCounterType type)
{
}

/*
 *
 * Called when the device table has been initialized.
 *
 *@param index:  Index of the removed device.
 *
 */
void emberAfPluginDeviceTableIndexAddedCallback(uint16_t index)
{
}

/*
 *
 * Called when the device has been removed from the table.
 *
 *@param currentIndex:  Index of the removed device.
 *
 */
void emberAfPluginDeviceTableIndexRemovedCallback(uint16_t currentIndex)
{
}

/*
 *
 * Called when the device table has been initialized.
 *
 */
void emberAfPluginDeviceTableInitialized(void)
{
}

/** @brief Client Complete
 *
 * This function is called by the EZ-Mode Commissioning plugin when client
 * commissioning completes.
 *
 * @param bindingIndex The binding index that was created or
 * ::EMBER_NULL_BINDING if an error occurred. Ver.: always
 */
void emberAfPluginEzmodeCommissioningClientCompleteCallback(uint8_t bindingIndex)
{
}

/** @brief Bad File Descriptor
 *
 * The indicated file descriptor has been detected to be bad; for example,
 * the file descriptor caused an EBADF error on a select() call. The file
 * descriptor will be omitted from subsequent file descriptor polling. The
 * application responsible for the file descriptor should take steps to
 * recover and clean up.
 *
 * @param fd The bad file descriptor Ver.: always
 */
void emberAfPluginFileDescriptorDispatchBadFileDescriptorCallback(int fd)
{
}

/** @brief Select File Descriptors
 *
 * This function is called when the Gateway plugin will do a select() call to
 * yield the processor until it has a timed event that needs to execute. The
 * function implementor may add additional file descriptors that the
 * application will monitor with select() for data ready. These file
 * descriptors must be read file descriptors. The number of file descriptors
 * added must be returned by the function (0 for none added).
 *
 * @param list A pointer to a list of File descriptors that the function
 * implementor may append to Ver.: always
 * @param maxSize The maximum number of elements that the function implementor
 * may add. Ver.: always
 */
int emberAfPluginGatewaySelectFileDescriptorsCallback(int*list,
                                                      int maxSize)
{
  return 0;
}

/** @brief Level Control Cluster Server Post Init
 *
 * Following resolution of the Current Level at startup for this endpoint,
 * perform any additional initialization needed; e.g., synchronize hardware
 * state.
 *
 * @param endpoint Endpoint that is being initialized  Ver.: always
 */
void emberAfPluginLevelControlClusterServerPostInitCallback(uint8_t endpoint)
{
}

/** @brief Complete
 *
 * This callback notifies the user that the network creation process has
 * completed successfully.
 *
 * @param network The network that the network creator plugin successfully
 * formed. Ver.: always
 * @param usedSecondaryChannels Whether or not the network creator wants to
 * form a network on the secondary channels Ver.: always
 */
void emberAfPluginNetworkCreatorCompleteCallback(const EmberNetworkParameters *network,
                                                 bool usedSecondaryChannels)
{
}

/** @brief Get Pan Id
 *
 * This callback is called when the Network Creator plugin needs the PAN ID for
 * the network it is about to create. By default, the callback will return a
 * random 16-bit value.
 *
 */
EmberPanId emberAfPluginNetworkCreatorGetPanIdCallback(void)
{
	return halCommonGetRandom();
}


/** @brief Finished
 *
 * This callback is fired when the network-find plugin is finished with the
 * forming or joining process. The result of the operation will be returned in
 * the status parameter.
 *
 * @param status   Ver.: always
 */
void emberAfPluginNetworkFindFinishedCallback(EmberStatus status)
{
}

/** @brief Get Enable Scanning All Channels
 *
 * Returns true is the fallback on scanning all channels is enabled,
 * false if not.
 */
bool emberAfPluginNetworkFindGetEnableScanningAllChannelsCallback(void)
{
#ifdef EMBER_AF_PLUGIN_NETWORK_FIND_ENABLE_ALL_CHANNELS
	return true;
#else
	return false;
#endif
}

/** @brief Get Energy Threshold For Channel
 *
 * This callback is called during the energy scan when forming the network.
 * Should the energy level exceed the value returned by this callback, the
 * current channel will not be considered a suitable candidate for forming.
 * Should none of the channels in the channel mask be considered suitable,
 * the scan will fall back on all channels, including those not on the
 * channel mask. The return value is RSSI, in dBm.
 * This callback is called only when the fallback functionality is enabled.
 *
 * @param pgChan   Ver.: always
 */
int8_t emberAfPluginNetworkFindGetEnergyThresholdForChannelCallback(uint8_t pgChan)
{
#if defined(EMBER_AF_PLUGIN_NETWORK_FIND_SUB_GHZ)
  return emberAfGetPageFrom8bitEncodedChanPg(pgChan) == 0
         ? EMBER_AF_PLUGIN_NETWORK_FIND_CUT_OFF_VALUE
		 : EMBER_AF_PLUGIN_NETWORK_FIND_SUB_GHZ_CUT_OFF_VALUE;
#elif defined(EMBER_AF_PLUGIN_NETWORK_FIND)
	return EMBER_AF_PLUGIN_NETWORK_FIND_CUT_OFF_VALUE;
#else
  return 127;   // Highest possible int8_t (the return type). The value does not matter anyway but we need to return _something_.
#endif
}

/** @brief Get Radio Power For Channel
 *
 * This callback is called by the framework when it is setting the radio power
 * during the discovery process. The framework will set the radio power
 * depending on what is returned by this callback.
 *
 * @param pgChan   Ver.: always
 */
int8_t emberAfPluginNetworkFindGetRadioPowerForChannelCallback(uint8_t pgChan)
{
  return EMBER_AF_PLUGIN_NETWORK_FIND_RADIO_TX_POWER;
}

/** @brief Join
 *
 * This callback is called by the plugin when a joinable network has been
 * found. If the application returns true, the plugin will attempt to join the
 * network. Otherwise, the plugin will ignore the network and continue
 * searching. Applications can use this callback to implement a network
 * blacklist.
 *
 * @param networkFound   Ver.: always
 * @param lqi   Ver.: always
 * @param rssi   Ver.: always
 */
bool emberAfPluginNetworkFindJoinCallback(EmberZigbeeNetwork *networkFound,
                                          uint8_t lqi,
                                          int8_t rssi)
{
  return true;
}

/** @brief On/off Cluster Server Post Init
 *
 * Following resolution of the On/Off state at startup for this endpoint, perform any
 * additional initialization needed; e.g., synchronize hardware state.
 *
 * @param endpoint Endpoint that is being initialized  Ver.: always
 */
void emberAfPluginOnOffClusterServerPostInitCallback(uint8_t endpoint)
{
}


/** @brief GetClientDelayUnits
 *
 * Called when the server receives an Image Block Request from a client that
 * supports rate limiting using the Minimum Block Period feature. This callback
 * gives the server a chance to decide which units the client uses for the
 * Minimum Block Period, seconds or milliseconds. The server can also return
 * OTA_SERVER_DISCOVER_CLIENT_DELAY_UNITS, which causes the plugin code to test
 * the client by sending it a preset delay value. The length of time the client
 * delays determines which units it uses. For more information on this feature,
 * please read the plugin option descriptions under the OTA Server plugin.
 *
 * @param clientNodeId     Ver.: always
 * @param clientEui64      Ver.: always
 *
 * For return values, see ota-server-policy.h. An unknown return value will
 * result in the same behavior as if OTA_SERVER_CLIENT_USES_MILLISECONDS had
 * been returned.
 */
uint8_t emberAfPluginOtaServerPolicyGetClientDelayUnits(EmberNodeId clientNodeId,
                                                        EmberEUI64 clientEui64)
{
  return OTA_SERVER_DISCOVER_CLIENT_DELAY_UNITS;
}

/** @brief Configured
 *
 * This callback is called by the Reporting plugin whenever a reporting entry
 * is configured, including when entries are deleted or updated. The
 * application can use this callback for scheduling readings or measurements
 * based on the minimum and maximum reporting interval for the entry. The
 * application should return EMBER_ZCL_STATUS_SUCCESS if it can support the
 * configuration or an error status otherwise. Note: attribute reporting is
 * required for many clusters and attributes, so rejecting a reporting
 * configuration may violate ZigBee specifications.
 *
 * @param entry   Ver.: always
 */
EmberAfStatus emberAfPluginReportingConfiguredCallback(const EmberAfPluginReportingEntry *entry)
{
	return EMBER_ZCL_STATUS_SUCCESS;
}

/** @brief Configured
 *
 * This callback is called by the Reporting plugin to get the default reporting
 * configuration values from user if there is no default value available within
 * af generated default reporting configuration tabel. The application need to
 * write to the minInterval, maxInterval and reportable change in the passed
 * IO pointer in the arguement while handleing this callback, then application
 * shall return true if it has provided the default values or else false for
 * reporting plugin to further handleing.
 *
 * @param entry   Ver.: always
 */
bool emberAfPluginReportingGetDefaultReportingConfigCallback(EmberAfPluginReportingEntry *entry)
{
	// Change the values as appropriate for the application.
	entry->data.reported.minInterval = 1;
	entry->data.reported.maxInterval = 0xFFFE;
	entry->data.reported.reportableChange = 1;
	entry->direction = EMBER_ZCL_REPORTING_DIRECTION_REPORTED;
	return true;
}

/** @brief Remove Mirror
 *
 * This function is called by the Simple Metering client plugin whenever a
 * Remove Mirror command is received. The application should return the
 * endpoint on which the mirror has been removed. If the mirror could not be
 * removed, the application should return 0xFFFF.
 *
 * @param requestingDeviceIeeeAddress   Ver.: always
 */
uint16_t emberAfPluginSimpleMeteringClientRemoveMirrorCallback(EmberEUI64 requestingDeviceIeeeAddress)
{
  return 0xFFFF;
}

/** @brief Request Mirror
 *
 * This function is called by the Simple Metering client plugin whenever a
 * Request Mirror command is received. The application should return the
 * endpoint to which the mirror has been assigned. If no mirror could be
 * assigned, the application should return 0xFFFF.
 *
 * @param requestingDeviceIeeeAddress   Ver.: always
 */
uint16_t emberAfPluginSimpleMeteringClientRequestMirrorCallback(EmberEUI64 requestingDeviceIeeeAddress)
{
  return 0xFFFF;
}

/** @brief Post Attribute Change
 *
 * This function is called by the application framework after it changes an
 * attribute value. The value passed into this callback is the value to which
 * the attribute was set by the framework.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 * @param attributeId   Ver.: always
 * @param mask   Ver.: always
 * @param manufacturerCode   Ver.: always
 * @param type   Ver.: always
 * @param size   Ver.: always
 * @param value   Ver.: always
 */
void emberAfPostAttributeChangeCallback(uint8_t endpoint,
                                        EmberAfClusterId clusterId,
                                        EmberAfAttributeId attributeId,
                                        uint8_t mask,
                                        uint16_t manufacturerCode,
                                        uint8_t type,
                                        uint8_t size,
                                        uint8_t* value)
{
}

/** @brief Pre Attribute Change
 *
 * This function is called by the application framework before it changes an
 * attribute value.  The value passed into this callback is the value to which
 * the attribute is to be set by the framework.  The application should return
 * ::EMBER_ZCL_STATUS_SUCCESS to permit the change or any other ::EmberAfStatus
 * to reject it.
 *
 * @param endpoint   Ver.: always
 * @param clusterId   Ver.: always
 * @param attributeId   Ver.: always
 * @param mask   Ver.: always
 * @param manufacturerCode   Ver.: always
 * @param type   Ver.: always
 * @param size   Ver.: always
 * @param value   Ver.: always
 */
EmberAfStatus emberAfPreAttributeChangeCallback(uint8_t endpoint,
                                                EmberAfClusterId clusterId,
                                                EmberAfAttributeId attributeId,
                                                uint8_t mask,
                                                uint16_t manufacturerCode,
                                                uint8_t type,
                                                uint8_t size,
                                                uint8_t* value)
{
  return EMBER_ZCL_STATUS_SUCCESS;
}

/** @brief Pre Cli Send
 *
 * This function is called by the framework when it is about to pass a message
 * constructed over CLI to the stack primitives for sending. If the function
 * returns true it is assumed that the callback has consumed and processed the
 * message. The framework will not do any further processing on the message.
   
 *     If the function returns false then it is assumed that the callback has
 * not processed the message and the framework will continue to process
 * accordingly.
 *
 * @param apsFrame The structure containing the APS frame  Ver.: always
 * @param source Source Node Id  Ver.: always
 * @param destination Destintion Node Id  Ver.: always
 * @param message Pointer to the message payload  Ver.: always
 * @param messageLength Length of the message payload  Ver.: always
 */
bool emberAfPreCliSendCallback(EmberApsFrame* apsFrame,
                               EmberNodeId source,
                               EmberNodeId destination,
                               uint8_t* message,
                               uint16_t messageLength)
{
  return false;
}

/** @brief Pre Command Received
 *
 * This callback is the second in the Application Framework's message processing
 * chain. At this point in the processing of incoming over-the-air messages, the
 * application has determined that the incoming message is a ZCL command. It
 * parses enough of the message to populate an EmberAfClusterCommand struct. The
 * Application Framework defines this struct value in a local scope to the
 * command processing but also makes it available through a global pointer
 * called emberAfCurrentCommand, in app/framework/util/util.c. When command
 * processing is complete, this pointer is cleared.
 *
 * @param cmd   Ver.: always
 */
bool emberAfPreCommandReceivedCallback(EmberAfClusterCommand* cmd)
{
  return false;
}

/** @brief Pre Ncp Reset
 *
 * This function will be called prior to the reset of the NCP by the host.
 *
 */
void emberAfPreNcpResetCallback(void)
{
}

/** @brief Pre ZDO Message Received
 *
 * This function passes the application an incoming ZDO message and gives the
 * appictation the opportunity to handle it. By default, this callback returns
 * false indicating that the incoming ZDO message has not been handled and
 * should be handled by the Application Framework.
 *
 * @param emberNodeId   Ver.: always
 * @param apsFrame   Ver.: always
 * @param message   Ver.: always
 * @param length   Ver.: always
 */
bool emberAfPreZDOMessageReceivedCallback(EmberNodeId emberNodeId,
                                          EmberApsFrame* apsFrame,
                                          uint8_t* message,
                                          uint16_t length)
{
  return false;
}

/** @brief Scenes Cluster Recall Saved Scene
 *
 * This function is called by the framework when the application should recall a
 * saved scene.
 *
 * @param endpoint The endpoint.  Ver.: always
 * @param groupId The group identifier.  Ver.: always
 * @param sceneId The scene identifier.  Ver.: always
 */
EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(uint8_t endpoint,
                                                           uint16_t groupId,
                                                           uint8_t sceneId)
{
  return EMBER_ZCL_STATUS_FAILURE;
}

/** @brief Registration Abort
 *
 * This callback is called when the device should abort the registration
 * process.
 *
 */
void emberAfRegistrationAbortCallback(void)
{
}

/** @brief Registration
 *
 * This callback is called when the device joins a network and the process of
 * registration is complete. This callback provides a success value of true if
 * the registration process was successful and a value of false if registration
 * failed.
 *
 * @param success true if registration succeeded, false otherwise.  Ver.: always
 */
void emberAfRegistrationCallback(bool success)
{
}

/** @brief Registration Start
 *
 * This callback is called when the device joins a network and the registration
 * process should begin.  The application should return EMBER_SUCCESS if the
 * registration process started successfully.  When registration is complete,
 * the application should call emberAfRegistrationCallback with an indication of
 * success or failure.
 *
 */
EmberStatus emberAfRegistrationStartCallback(void)
{
  return EMBER_LIBRARY_NOT_PRESENT;
}

/** @brief Remote Delete Binding Permission
 *
 * This function is called by the framework to request permission to service the
 * remote delete binding request. Return EMBER_SUCCESS to allow request,
 * anything else to disallow request.
 *
 * @param index index to an Ember binding table entry  Ver.: always
 */
EmberStatus emberAfRemoteDeleteBindingPermissionCallback(uint8_t index)
{
  return EMBER_SUCCESS; // default
}

/** @brief Remote Set Binding Permission
 *
 * This function is called by the framework to request permission to service the
 * remote set binding request. Return EMBER_SUCCESS to allow request, anything
 * else to disallow request.
 *
 * @param entry Ember Binding Tablet Entry  Ver.: always
 */
EmberStatus emberAfRemoteSetBindingPermissionCallback(const EmberBindingTableEntry *entry)
{
  return EMBER_SUCCESS; // default
}

/** @brief Remove From Current App Tasks
 *
 * This function is only useful to sleepy end devices.  This function will
 * remove the passed item from the set of tasks the application has outstanding
 * (e.g. message sent requiring APS acknwoledgement).  This will affect how the
 * application behaves with regard to sleeping and polling.  Removing the item
 * from the list of outstanding tasks may allow the device to sleep longer and
 * poll less frequently.  If there are other outstanding tasks the system may
 * still have to stay away and poll more often.
 *
 * @param tasks   Ver.: always
 */
void emberAfRemoveFromCurrentAppTasksCallback(EmberAfApplicationTask tasks)
{
}

/** @brief Scenes Cluster Remove Scenes In Group
 *
 * This function removes the scenes from a specified group.
 *
 * @param endpoint Endpoint  Ver.: always
 * @param groupId Group ID  Ver.: always
 */
void emberAfScenesClusterRemoveScenesInGroupCallback(uint8_t endpoint,
                                                     uint16_t groupId)
{
}

/** @brief Security Init
 *
 * This callback is called by the framework to give the application a chance to
 * modify the security settings of the node during network initialization. 
 * Depending on the context when this callback is called, the pointer to the
 * initial security state may be NULL, which means the initial security state
 * can no longer be modified as the node is already operating on the network.
 *
 * @param state   Ver.: always
 * @param extended   Ver.: always
 * @param trustCenter   Ver.: always
 */
void emberAfSecurityInitCallback(EmberInitialSecurityState *state,
                                 EmberExtendedSecurityBitmask *extended,
                                 bool trustCenter)
{
}

/** @brief Key Establishment Cluster Server Command Received
 *
 * This function is called by the application framework when a client-to-server
 * key establishment command is received but has yet to be handled by the
 * framework code.  This function should return a bool value indicating whether
 * the command has been handled by the application code and should not be
 * further processed by the framework.
 *
 * @param cmd   Ver.: always
 */
bool emberAfKeyEstablishmentClusterServerCommandReceivedCallback(EmberAfClusterCommand *cmd)
{
  return false;
}

/** @brief Set Default Poll Control
 *
 * This function will set the default poll control for the current network to
 * control whether or not it can long poll.
 *
 * @param control   Ver.: always
 */
void emberAfSetDefaultPollControlCallback(EmberAfEventPollControl control)
{
}

/** @brief Set Default Sleep Control
 *
 * This function will set the default behavior of a sleeping device to control
 * whether or not it must stay awake.  A device that stays awake does not sleep
 * at all.  Otherwise, the device can sleep between events when appropriate.
 *
 * @param control   Ver.: always
 */
void emberAfSetDefaultSleepControlCallback(EmberAfEventSleepControl control)
{
}

/** @brief Set Long Poll Interval Ms
 *
 * This function is only useful to end devices.  This function will set the long
 * poll interval (in milliseconds) for the current network.  This interval is
 * the maximum amount of time a child will wait between polls of its parent when
 * it is not expecting data.
 *
 * @param longPollIntervalMs   Ver.: always
 */
void emberAfSetLongPollIntervalMsCallback(uint32_t longPollIntervalMs)
{
}

/** @brief Set Long Poll Interval Qs
 *
 * This function is only useful to end devices.  This function will set the long
 * poll interval (in quarter seconds) for the current network.  This interval is
 * the maximum amount of time a child will wait between polls of its parent when
 * it is not expecting data.
 *
 * @param longPollIntervalQs   Ver.: always
 */
void emberAfSetLongPollIntervalQsCallback(uint32_t longPollIntervalQs)
{
}

/** @brief Set Short Poll Interval Ms
 *
 * This function is only useful to sleepy end devices.  This function will set
 * the short poll interval (in milliseconds) for the current network.  This
 * interval is the maximum amount of time a child will wait between polls of its
 * parent when it is expecting data.
 *
 * @param shortPollIntervalMs   Ver.: always
 */
void emberAfSetShortPollIntervalMsCallback(uint16_t shortPollIntervalMs)
{
}

/** @brief Set Short Poll Interval Qs
 *
 * This function is only useful to sleepy end devices.  This function will set
 * the short poll interval (in quarter seconds) for the current network.  This
 * interval is the maximum amount of time a child will wait between polls of its
 * parent when it is expecting data.
 *
 * @param shortPollIntervalQs   Ver.: always
 */
void emberAfSetShortPollIntervalQsCallback(uint16_t shortPollIntervalQs)
{
}

/** @brief Set Time
 *
 * This callback should be implemented, if the device has access to real time
 * clock, and has an ability to update that clock. The application framework
 * expects to be passed the utcTime which is the number of seconds since the
 * year 2000. Default implementation does nothing. Note: This function used to
 * take time in year, month, day, hour, min, sec. We have changed this to
 * utcTime in order to conserve code space.
 *
 * @param utcTime   Ver.: always
 */
void emberAfSetTimeCallback(uint32_t utcTime)
{
}

/** @brief Set Wake Timeout Bitmask
 *
 * This function is only useful to sleepy end devices.  This function will set
 * the wake timeout bitmask for the current network.  The bitmask determines
 * which tasks will timeout automatically and which tasks require manual removal
 * from the task list.
 *
 * @param tasks   Ver.: always
 */
void emberAfSetWakeTimeoutBitmaskCallback(EmberAfApplicationTask tasks)
{
}

/** @brief Set Wake Timeout Ms
 *
 * This function is only useful to sleepy end devices.  This function will set
 * the wake timeout (in milliseconds) for the current network.  This timeout is
 * the maximum amount of time a child will wait for a task in the wake bitmask
 * to finish.  While waiting, the device will short poll.
 *
 * @param wakeTimeoutMs   Ver.: always
 */
void emberAfSetWakeTimeoutMsCallback(uint16_t wakeTimeoutMs)
{
}

/** @brief Set Wake Timeout Qs
 *
 * This function is only useful to sleepy end devices.  This function will set
 * the wake timeout (in quarter seconds) for the current network.  This timeout
 * is the maximum amount of time a child will wait for a task in the wake
 * bitmask to finish.  While waiting, the device will short poll.
 *
 * @param wakeTimeoutQs   Ver.: always
 */
void emberAfSetWakeTimeoutQsCallback(uint16_t wakeTimeoutQs)
{
}

/** @brief Stack Status
 *
 * This function is called by the application framework from the stack status
 * handler.  This callbacks provides applications an opportunity to be notified
 * of changes to the stack status and take appropriate action.  The return code
 * from this callback is ignored by the framework.  The framework will always
 * process the stack status after the callback returns.
 *
 * @param status   Ver.: always
 */
bool emberAfStackStatusCallback(EmberStatus status)
{
  return false;
}

/** @brief Start Move
 *
 * This function is called to initiate the process for a device to move (rejoin)
 * to a new parent.
 *
 */
bool emberAfStartMoveCallback(void)
{
  return false;
}

/** @brief Stop Move
 *
 * This function is called to cancel a previously scheduled move (rejoin) to a
 * new parent.
 *
 */
void emberAfStopMoveCallback(void)
{
}

/** @brief Scenes Cluster Store Current Scene
 *
 * This function is called by the framework when the application should store
 * the current scene.  If an entry already exists in the scene table with the
 * same scene and group ids, the application should update the entry with the
 * current scene.  Otherwise, a new entry should be adde to the scene table, if
 * possible.
 *
 * @param endpoint The endpoint.  Ver.: always
 * @param groupId The group identifier.  Ver.: always
 * @param sceneId The scene identifier.  Ver.: always
 */
EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(uint8_t endpoint,
                                                            uint16_t groupId,
                                                            uint8_t sceneId)
{
  return EMBER_ZCL_STATUS_FAILURE;
}

/** @brief Trust Center Keepalive Abort
 *
 * This callback is called when the device should abort the trust center
 * keepalive process.
 *
 */
void emberAfTrustCenterKeepaliveAbortCallback(void)
{
}

/** @brief Trust Center Keepalive Update
 *
 * This callback is called when the device finishes registration (successfully
 * or otherwise) and the trust center keepalive process must be updated.  If the
 * keepalive process has not been started, then it is started.  Otherwise if the
 * keepalive is in the process of searching for the TC, it will process the
 * result of that Trust Center search operation.
 *
 * @param registrationComplete   Ver.: always
 */
void emberAfTrustCenterKeepaliveUpdateCallback(bool registrationComplete)
{
}

/** @brief Write Attributes Response
 *
 * This function is called by the application framework when a Write Attributes
 * Response command is received from an external device.  The application should
 * return true if the message was processed or false if it was not.
 *
 * @param clusterId The cluster identifier of this response.  Ver.: always
 * @param buffer Buffer containing the list of write attribute status records. 
 * Ver.: always
 * @param bufLen The length in bytes of the list.  Ver.: always
 */
bool emberAfWriteAttributesResponseCallback(EmberAfClusterId clusterId,
                                            uint8_t *buffer,
                                            uint16_t bufLen)
{
  return false;
}

/** @brief Zigbee Key Establishment
 *
 * A callback to the application to notify it of the status of the request for a
 * Link Key.
 *
 * @param partner partner The IEEE address of the partner device.  Or all zeros
 * if the Key establishment failed.  Ver.: always
 * @param status The status of the key establishment.  Ver.: always
 */
void emberAfZigbeeKeyEstablishmentCallback(EmberEUI64 partner,
                                           EmberKeyStatus status)
{
}

/** @brief came back from EM4
 *
 * This callback would be implemented in idle/sleep
            plugin by the
 * name emberAfCameBackFromEM4Callback and
            will be called by the
 * framework. It lets the
            plugin/app know the board is back from
 * EM4. So if the
            app wants to restore something, it can do it.
 *
 */
void emberAfcamebackfromEM4Callback(void)
{
}
