Alarm messages are stored for an unlimited time by the parent in dedicated memory for delivery to a hibernating sleepy child.
Alarm messages can be unicast or broadcast with the following APS data (defined in ember-types.h):
•Profile ID: EMBER_PRIVATE_PROFILE_ID.
•Endpoint: the source and destination endpoints are ignored.
•Cluster ID: EMBER_BROADCAST_ALARM_CLUSTER, EMBER_UNICAST_ALARM_CLUSTER, or EMBER_CACHED_UNICAST_ALARM_CLUSTER
Only the profile ID and cluster ID are used by the stack to identify alarm messages. Messages with cluster ID EMBER_BROADCAST_ALARM_CLUSTER may only be broadcast. Messages with cluster ID EMBER_UNICAST_ALARM_CLUSTER may only be unicast. Messages with cluster ID EMBER_CACHED_UNICAST_ALARM_CLUSTER are only sent by the stack.
Alarm messages are sent and received using the standard message calls and callbacks.
There are two new configuration parameters that control the size of the alarm buffers.
•EMBER_BROADCAST_ALARM_DATA_SIZE (or EZSP_CONFIG_BROADCAST_ALARM_DATA_SIZE in EZSP)
•EMBER_UNICAST_ALARM_DATA_SIZE (or EZSP_CONFIG_UNICAST_ALARM_DATA_SIZE in EZSP)
The first is the size in bytes of the (single) buffer for broadcast alarms. The second is the size in bytes of the per-child unicast alarm buffers. These can be in the inclusive range 0 .. EMBER_MAXIMUM_ALARM_DATA_SIZE (16). The default for both values is 0.
Unicast alarm messages are sent using emberSendUnicast() (or ezspSendUnicast()) with the sleepy child as the destination (determined by node ID or EUI64). The profile ID must be EMBER_PRIVATE_PROFILE_ID and the cluster ID must be EMBER_UNICAST_ALARM_CLUSTER.
Unicast alarm data is stored in a special RAM table. There are EMBER_CHILD_TABLE_SIZE entries in the table. Each entry is EMBER_UNICAST_ALARM_DATA_SIZE bytes.
When a child polls, if there is a unicast alarm message waiting on the parent, the parent will send it to the child using cluster ID EMBER_CACHED_UNICAST_ALARM_CLUSTER. The stack sends an ACK message back to the parent, which then clears that child’s pending unicast alarm flag.
When a parent receives a unicast alarm message whose destination is a sleepy end device child of that node, the payload of the message is saved until the child polls for data. To conserve memory, the values of the length fields are not saved. The alarm will be forwarded to the child using the EMBER_CACHED_UNICAST_ALARM_CLUSTER cluster ID. Note that while it is possible to request an APS ACK on the Alarm unicast, the ACK is generated by the child and therefore won’t be sent until the child picks up the alarm, which is likely to be well outside of the retry timing of the sender, so the sender’s MessageSentHandler will generally indicate EMBER_DELIVERY_FAILED unless the alarm is received within the normal stack retry timing + Indirect Transmission Timeout.
The payload of a unicast alarm consists of three one-byte length fields followed by three variable-length fields. (Note that alarm messages not following this payload format will be discarded at the parent!)
1. flags length (value >= 0) 2. priority length (value = 0 or value =1) 3. data length (value > 0) 4. flags (arbitrary values, up to application) 5. priority (unsigned integer; values can be arbitrary per application, but stack gives precedence to higher values) 6. payload (up to application)
The three lengths must total EMBER_UNICAST_ALARM_DATA_SIZE (EZSP_CONFIG_UNICAST_ALARM_DATA_SIZE) or less.
When a unicast alarm message arrives at its destination, it is passed to the application via ember/ezspIncomingMessageHandler(). The payload received in the IncomingMessageHandler will be of length set by the Unicast Alarm Data Size and will consist of the flag bytes (if length > 0), then the priority byte (if length non-zero), then the alarm payload bytes. If the sum of all these lengths is less than the Unicast Alarm Data Size configuration setting, then the remaining bytes will be padded with 0×00.
If a unicast alarm arrives when a previous one is still pending, the two payloads are combined. This combining is controlled by the length fields in the arriving message. The incoming flag bytes are OR’ed with those of the pending message. If the priority field is not present, or if it is present and the incoming priority value is equal or greater than the pending priority value, the pending data is replaced by the incoming data.
Because the length fields are not saved, the application designer must fix on a set of field lengths that will be used for all unicast alarm message sent to a particular device.
For more information on Alarms, please see the documentation for EMBER_UNICAST_ALARM_CLUSTER in the Stack API Guide, ember-types.h documentation.
Broadcast alarm messages are sent using emberSendBroadcast() with a destination of EMBER_RX_ON_WHEN_IDLE_BROADCAST_ADDRESS. Unlike unicast alarm messages, the contents is not divided into fields, it is just a payload that will be delivered to all devices in the network.
Broadcast alarm data is stored in a new RAM array. The length of this array is EMBER_BROADCAST_ALARM_DATA_SIZE bytes.
When a broadcast alarm message arrives, the message payload replaces the array contents.
When a child polls, if there is a broadcast alarm message waiting on the parent, the parent will send it to the child. The stack on the child sends an explicit ack to the parent, which then marks the child as having received the current alarm broadcast.
For more information on Alarms, please see the documentation for EMBER_BROADCAST_ALARM_CLUSTER in the Stack API Guide, ember-types.h documentation.
When a sleepy child polls, the parent will send messages in this priority (highest to lowest).