restyled
diff --git a/src/app/clusters/barrier-control-server/barrier-control-server-cli.c b/src/app/clusters/barrier-control-server/barrier-control-server-cli.c
index 1d39b13..f0440c4 100644
--- a/src/app/clusters/barrier-control-server/barrier-control-server-cli.c
+++ b/src/app/clusters/barrier-control-server/barrier-control-server-cli.c
@@ -31,93 +31,97 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the Barrier Control Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#include "barrier-control-server.h"
-static bool getBarrierPositionDescription(uint8_t endpoint,
- const char **descriptionLocation)
+static bool getBarrierPositionDescription(uint8_t endpoint, const char ** descriptionLocation)
{
- bool descriptionWasSet = true;
- switch (emAfPluginBarrierControlServerGetBarrierPosition(endpoint)) {
+ bool descriptionWasSet = true;
+ switch (emAfPluginBarrierControlServerGetBarrierPosition(endpoint))
+ {
case EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN:
- *descriptionLocation = "open";
- break;
+ *descriptionLocation = "open";
+ break;
case EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED:
- *descriptionLocation = "closed";
- break;
+ *descriptionLocation = "closed";
+ break;
default:
- if (emAfPluginBarrierControlServerIsPartialBarrierSupported(endpoint)) {
- descriptionWasSet = false;
- } else {
- *descriptionLocation = "unknown";
- }
- }
- return descriptionWasSet;
+ if (emAfPluginBarrierControlServerIsPartialBarrierSupported(endpoint))
+ {
+ descriptionWasSet = false;
+ }
+ else
+ {
+ *descriptionLocation = "unknown";
+ }
+ }
+ return descriptionWasSet;
}
static void printSafetyStatus(uint16_t safetyStatus)
{
- emberAfAppPrint("SafetyStatus: 0x%2X (", safetyStatus);
- if (safetyStatus != 0) {
- if (READBITS(safetyStatus,
- EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT)) {
- emberAfAppPrint("lockout,");
+ emberAfAppPrint("SafetyStatus: 0x%2X (", safetyStatus);
+ if (safetyStatus != 0)
+ {
+ if (READBITS(safetyStatus, EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT))
+ {
+ emberAfAppPrint("lockout,");
+ }
+ if (READBITS(safetyStatus, EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_TEMPER_DETECTED))
+ {
+ emberAfAppPrint("tamper,");
+ }
+ if (READBITS(safetyStatus, EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_FAILED_COMMUNICATION))
+ {
+ emberAfAppPrint("communication,");
+ }
+ if (READBITS(safetyStatus, EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_POSITION_FAILURE))
+ {
+ emberAfAppPrint("position,");
+ }
}
- if (READBITS(safetyStatus,
- EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_TEMPER_DETECTED)) {
- emberAfAppPrint("tamper,");
+ else
+ {
+ emberAfAppPrint("OK");
}
- if (READBITS(safetyStatus,
- EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_FAILED_COMMUNICATION)) {
- emberAfAppPrint("communication,");
- }
- if (READBITS(safetyStatus,
- EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_POSITION_FAILURE)) {
- emberAfAppPrint("position,");
- }
- } else {
- emberAfAppPrint("OK");
- }
- emberAfAppPrintln(")");
+ emberAfAppPrintln(")");
}
// plugin barrier-control-server status <endpoint:1>
void emAfPluginBarrierControlServerStatusCommand(void)
{
- uint8_t endpoint = (uint8_t)emberUnsignedCommandArgument(0);
- uint8_t barrierPosition
- = emAfPluginBarrierControlServerGetBarrierPosition(endpoint);
- const char *description;
- emberAfAppPrint("BarrierPosition: %d%%", barrierPosition);
- if (getBarrierPositionDescription(endpoint, &description)) {
- emberAfAppPrint(" (%s)", description);
- }
- emberAfAppPrintln("");
- printSafetyStatus(emAfPluginBarrierControlServerGetSafetyStatus(endpoint));
+ uint8_t endpoint = (uint8_t) emberUnsignedCommandArgument(0);
+ uint8_t barrierPosition = emAfPluginBarrierControlServerGetBarrierPosition(endpoint);
+ const char * description;
+ emberAfAppPrint("BarrierPosition: %d%%", barrierPosition);
+ if (getBarrierPositionDescription(endpoint, &description))
+ {
+ emberAfAppPrint(" (%s)", description);
+ }
+ emberAfAppPrintln("");
+ printSafetyStatus(emAfPluginBarrierControlServerGetSafetyStatus(endpoint));
}
// plugin barrier-control-server open <endpoint:1>
// plugin barrier-control-server close <endpoint:1>
void emAfPluginBarrierControlServerOpenOrCloseCommand(void)
{
- uint8_t endpoint = (uint8_t)emberUnsignedCommandArgument(0);
- bool open = emberStringCommandArgument(-1, NULL)[0] == 'o';
- uint8_t barrierPosition
- = (open
- ? EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN
- : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- emAfPluginBarrierControlServerSetBarrierPosition(endpoint, barrierPosition);
- emAfPluginBarrierControlServerIncrementEvents(endpoint, open, false);
+ uint8_t endpoint = (uint8_t) emberUnsignedCommandArgument(0);
+ bool open = emberStringCommandArgument(-1, NULL)[0] == 'o';
+ uint8_t barrierPosition =
+ (open ? EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ emAfPluginBarrierControlServerSetBarrierPosition(endpoint, barrierPosition);
+ emAfPluginBarrierControlServerIncrementEvents(endpoint, open, false);
- const char *description;
- assert(getBarrierPositionDescription(endpoint, &description));
- emberAfAppPrintln("Barrier is now %s", description);
+ const char * description;
+ assert(getBarrierPositionDescription(endpoint, &description));
+ emberAfAppPrintln("Barrier is now %s", description);
}
// plugin barrier-control-server remote-lockout <endpoint:1> <setOrClear:1>
@@ -126,32 +130,30 @@
// plugin barrier-control-server position-failure <endpoint:1> <setOrClear:1>
void emAfPluginBarrierControlServerSafetyStatusCommand(void)
{
- uint8_t endpoint = (uint8_t)emberUnsignedCommandArgument(0);
- bool doSet = ((uint8_t)emberUnsignedCommandArgument(1)) == 1;
- uint8_t bit
- = (emberStringCommandArgument(-1, NULL)[0] == 'r'
- ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT
- : (emberStringCommandArgument(-1, NULL)[0] == 't'
- ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_TEMPER_DETECTED
- : (emberStringCommandArgument(-1, NULL)[0] == 'f'
- ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_FAILED_COMMUNICATION
- : EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_POSITION_FAILURE)));
+ uint8_t endpoint = (uint8_t) emberUnsignedCommandArgument(0);
+ bool doSet = ((uint8_t) emberUnsignedCommandArgument(1)) == 1;
+ uint8_t bit =
+ (emberStringCommandArgument(-1, NULL)[0] == 'r'
+ ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT
+ : (emberStringCommandArgument(-1, NULL)[0] == 't'
+ ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_TEMPER_DETECTED
+ : (emberStringCommandArgument(-1, NULL)[0] == 'f' ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_FAILED_COMMUNICATION
+ : EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_POSITION_FAILURE)));
- uint16_t safetyStatus
- = emAfPluginBarrierControlServerGetSafetyStatus(endpoint);
- if (doSet) {
- SETBITS(safetyStatus, bit);
- } else {
- CLEARBITS(safetyStatus, bit);
- }
+ uint16_t safetyStatus = emAfPluginBarrierControlServerGetSafetyStatus(endpoint);
+ if (doSet)
+ {
+ SETBITS(safetyStatus, bit);
+ }
+ else
+ {
+ CLEARBITS(safetyStatus, bit);
+ }
- EmberAfStatus status
- = emberAfWriteServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_SAFETY_STATUS_ATTRIBUTE_ID,
- (uint8_t *)&safetyStatus,
- ZCL_BITMAP16_ATTRIBUTE_TYPE);
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ EmberAfStatus status =
+ emberAfWriteServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, ZCL_BARRIER_SAFETY_STATUS_ATTRIBUTE_ID,
+ (uint8_t *) &safetyStatus, ZCL_BITMAP16_ATTRIBUTE_TYPE);
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
- printSafetyStatus(safetyStatus);
+ printSafetyStatus(safetyStatus);
}
diff --git a/src/app/clusters/barrier-control-server/barrier-control-server-test.c b/src/app/clusters/barrier-control-server/barrier-control-server-test.c
index 37800de..1ee4bab 100644
--- a/src/app/clusters/barrier-control-server/barrier-control-server-test.c
+++ b/src/app/clusters/barrier-control-server/barrier-control-server-test.c
@@ -31,15 +31,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Unit test for barrier-control-server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
-#include "barrier-control-server.h"
#include "app/framework/test/script/afv2-scripted.h"
+#include "barrier-control-server.h"
// -----------------------------------------------------------------------------
// Utilities
@@ -49,60 +49,50 @@
static long getAttribute(EmberAfAttributeId attributeId)
{
- unsigned long data = 0;
- EmberAfStatus status = emberAfReadServerAttribute(1, // endpoint
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- attributeId,
- (uint8_t *)&data,
- 1); // ignored in stub below
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
- return data;
+ unsigned long data = 0;
+ EmberAfStatus status = emberAfReadServerAttribute(1, // endpoint
+ ZCL_BARRIER_CONTROL_CLUSTER_ID, attributeId, (uint8_t *) &data,
+ 1); // ignored in stub below
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ return data;
}
-#define addGetAttributeCheck(attributeId, value) \
- addFunctionCheck("getAttribute(%d)", \
- (value), \
- getAttribute, \
- 1, \
- (attributeId))
+#define addGetAttributeCheck(attributeId, value) addFunctionCheck("getAttribute(%d)", (value), getAttribute, 1, (attributeId))
// -------------------------------------
// goToPercent Action
PERFORMER(goToPercent)
{
- // Generated by AppBuilder from Barrier Control cluster XML.
- extern bool emberAfBarrierControlClusterBarrierControlGoToPercentCallback(uint8_t);
- uint8_t percentOpen = (uint8_t)action->contents[0];
- scriptAssert(action,
- emberAfBarrierControlClusterBarrierControlGoToPercentCallback(percentOpen));
+ // Generated by AppBuilder from Barrier Control cluster XML.
+ extern bool emberAfBarrierControlClusterBarrierControlGoToPercentCallback(uint8_t);
+ uint8_t percentOpen = (uint8_t) action->contents[0];
+ scriptAssert(action, emberAfBarrierControlClusterBarrierControlGoToPercentCallback(percentOpen));
}
PRINTER(goToPercent)
{
- uint8_t percentOpen = (uint8_t)action->contents[0];
- fprintf(stderr, "Move barrier to %d%%", percentOpen);
+ uint8_t percentOpen = (uint8_t) action->contents[0];
+ fprintf(stderr, "Move barrier to %d%%", percentOpen);
}
ACTION(goToPercent, i);
-#define addGoToPercentAction(percentOpen) \
- addAction(&goToPercentActionType, (percentOpen))
+#define addGoToPercentAction(percentOpen) addAction(&goToPercentActionType, (percentOpen))
// -------------------------------------
// stop Action
PERFORMER(stop)
{
- // Generated by AppBuilder from Barrier Control cluster XML.
- extern bool emberAfBarrierControlClusterBarrierControlStopCallback(void);
- scriptAssert(action,
- emberAfBarrierControlClusterBarrierControlStopCallback());
+ // Generated by AppBuilder from Barrier Control cluster XML.
+ extern bool emberAfBarrierControlClusterBarrierControlStopCallback(void);
+ scriptAssert(action, emberAfBarrierControlClusterBarrierControlStopCallback());
}
PRINTER(stop)
{
- fprintf(stderr, "Stop barrier movement");
+ fprintf(stderr, "Stop barrier movement");
}
ACTION(stop, i); // added one fake integer parameter to please preprocessor
@@ -114,119 +104,80 @@
EmberStatus emberAfSendImmediateDefaultResponse(EmberAfStatus status)
{
- functionCallCheck("emberAfSendImmediateDefaultResponse", "i", status);
- return EMBER_SUCCESS;
+ functionCallCheck("emberAfSendImmediateDefaultResponse", "i", status);
+ return EMBER_SUCCESS;
}
-#define addDefaultResponseCheck(status) \
- addSimpleCheck("emberAfSendImmediateDefaultResponse", \
- "i", \
- (status))
+#define addDefaultResponseCheck(status) addSimpleCheck("emberAfSendImmediateDefaultResponse", "i", (status))
// -------------------------------------
// initialState Check
// The BarrierPosition attribute should be closed to start and the MovingState
// attribute should be set to STOPPED.
-#define addInitialStateCheck() \
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, \
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED); \
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, \
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+#define addInitialStateCheck() \
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED); \
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
// -------------------------------------
// setRemoteLockout Action
static void setRemoteLockout(bool set)
{
- uint16_t remoteLockoutBit
- = (set
- ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT
- : 0);
- assert(emberAfWriteServerAttribute(1, // endpoint
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_SAFETY_STATUS_ATTRIBUTE_ID,
- (uint8_t *)&remoteLockoutBit,
- ZCL_BITMAP16_ATTRIBUTE_TYPE)
- == EMBER_ZCL_STATUS_SUCCESS);
+ uint16_t remoteLockoutBit = (set ? EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT : 0);
+ assert(emberAfWriteServerAttribute(1, // endpoint
+ ZCL_BARRIER_CONTROL_CLUSTER_ID, ZCL_BARRIER_SAFETY_STATUS_ATTRIBUTE_ID,
+ (uint8_t *) &remoteLockoutBit, ZCL_BITMAP16_ATTRIBUTE_TYPE) == EMBER_ZCL_STATUS_SUCCESS);
}
-#define addSetRemoteLockoutAction(set) \
- addSimpleAction("setRemoteLockout(%ld)", setRemoteLockout, 1, (set))
+#define addSetRemoteLockoutAction(set) addSimpleAction("setRemoteLockout(%ld)", setRemoteLockout, 1, (set))
// --------------------------------------
// openCloseEvents Action
-static void setOpenCloseEvents(uint16_t openEvents,
- uint16_t closeEvents,
- uint16_t commandOpenEvents,
- uint16_t commandCloseEvents)
+static void setOpenCloseEvents(uint16_t openEvents, uint16_t closeEvents, uint16_t commandOpenEvents, uint16_t commandCloseEvents)
{
- uint16_t *values[] = {
- &openEvents, // ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID
- &closeEvents, // ZCL_BARRIER_CLOSE_EVENTS_ATTRIBUTE_ID
- &commandOpenEvents, // ZCL_BARRIER_COMMAND_OPEN_EVENTS_ATTRIBUTE_ID
- &commandCloseEvents, // ZCL_BARRIER_COMMAND_CLOSE_EVENTS_ATTRIBUTE_ID
- NULL,
- };
- EmberAfAttributeId attributeId = ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID;
- for (uint16_t *value = values[0]; value != NULL; value++, attributeId++) {
- assert(emberAfWriteServerAttribute(1, // endpoint
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- attributeId,
- (uint8_t *)value,
- ZCL_INT16U_ATTRIBUTE_TYPE)
- == EMBER_ZCL_STATUS_SUCCESS);
- }
+ uint16_t * values[] = {
+ &openEvents, // ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID
+ &closeEvents, // ZCL_BARRIER_CLOSE_EVENTS_ATTRIBUTE_ID
+ &commandOpenEvents, // ZCL_BARRIER_COMMAND_OPEN_EVENTS_ATTRIBUTE_ID
+ &commandCloseEvents, // ZCL_BARRIER_COMMAND_CLOSE_EVENTS_ATTRIBUTE_ID
+ NULL,
+ };
+ EmberAfAttributeId attributeId = ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID;
+ for (uint16_t * value = values[0]; value != NULL; value++, attributeId++)
+ {
+ assert(emberAfWriteServerAttribute(1, // endpoint
+ ZCL_BARRIER_CONTROL_CLUSTER_ID, attributeId, (uint8_t *) value,
+ ZCL_INT16U_ATTRIBUTE_TYPE) == EMBER_ZCL_STATUS_SUCCESS);
+ }
}
-#define addSetOpenCloseEventsAction(openEvents, \
- closeEvents, \
- commandOpenEvents, \
- commandCloseEvents) \
- addSimpleAction("setOpenCloseEvents(%ld, %ld, %ld, %ld)", \
- setOpenCloseEvents, \
- 4, \
- (openEvents), \
- (closeEvents), \
- (commandOpenEvents), \
- (commandCloseEvents))
+#define addSetOpenCloseEventsAction(openEvents, closeEvents, commandOpenEvents, commandCloseEvents) \
+ addSimpleAction("setOpenCloseEvents(%ld, %ld, %ld, %ld)", setOpenCloseEvents, 4, (openEvents), (closeEvents), \
+ (commandOpenEvents), (commandCloseEvents))
// --------------------------------------
// openCloseEvents Check
-#define addOpenCloseEventsCheck(openEvents, \
- closeEvents, \
- commandOpenEvents, \
- commandCloseEvents) \
- addGetAttributeCheck(ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID, \
- (openEvents)); \
- addGetAttributeCheck(ZCL_BARRIER_CLOSE_EVENTS_ATTRIBUTE_ID, \
- (closeEvents)); \
- addGetAttributeCheck(ZCL_BARRIER_COMMAND_OPEN_EVENTS_ATTRIBUTE_ID, \
- (commandOpenEvents)); \
- addGetAttributeCheck(ZCL_BARRIER_COMMAND_CLOSE_EVENTS_ATTRIBUTE_ID, \
- (commandCloseEvents)); \
+#define addOpenCloseEventsCheck(openEvents, closeEvents, commandOpenEvents, commandCloseEvents) \
+ addGetAttributeCheck(ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID, (openEvents)); \
+ addGetAttributeCheck(ZCL_BARRIER_CLOSE_EVENTS_ATTRIBUTE_ID, (closeEvents)); \
+ addGetAttributeCheck(ZCL_BARRIER_COMMAND_OPEN_EVENTS_ATTRIBUTE_ID, (commandOpenEvents)); \
+ addGetAttributeCheck(ZCL_BARRIER_COMMAND_CLOSE_EVENTS_ATTRIBUTE_ID, (commandCloseEvents));
// -------------------------------------
// setPartialBarrier Action
static void setPartialBarrier(bool set)
{
- uint8_t partialBarrierBit
- = (set
- ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER
- : 0);
- assert(emberAfWriteServerAttribute(1, // endpoint
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
- (uint8_t *)&partialBarrierBit,
- ZCL_BITMAP8_ATTRIBUTE_TYPE)
- == EMBER_ZCL_STATUS_SUCCESS);
+ uint8_t partialBarrierBit = (set ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER : 0);
+ assert(emberAfWriteServerAttribute(1, // endpoint
+ ZCL_BARRIER_CONTROL_CLUSTER_ID, ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
+ (uint8_t *) &partialBarrierBit, ZCL_BITMAP8_ATTRIBUTE_TYPE) == EMBER_ZCL_STATUS_SUCCESS);
}
-#define addSetPartialBarrierBitAction(set) \
- addSimpleAction("setPartialBarrier(%ld)", setPartialBarrier, 1, (set))
+#define addSetPartialBarrierBitAction(set) addSimpleAction("setPartialBarrier(%ld)", setPartialBarrier, 1, (set))
// -----------------------------------------------------------------------------
// Tests
@@ -236,96 +187,82 @@
static void reallyOpenTest(bool partialBarrier)
{
- addInitialStateCheck();
- runScript();
+ addInitialStateCheck();
+ runScript();
- // Set/clear the partial barrier bit depending on what test we are running.
- addSetPartialBarrierBitAction(partialBarrier);
- addGetAttributeCheck(ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
- (partialBarrier
- ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER
- : 0));
- runScript();
+ // Set/clear the partial barrier bit depending on what test we are running.
+ addSetPartialBarrierBitAction(partialBarrier);
+ addGetAttributeCheck(ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
+ (partialBarrier ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER : 0));
+ runScript();
- // If we get a percent higher than 100, we send back INVALID_VALUE.
- addGoToPercentAction(101);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_INVALID_VALUE);
- runScript();
+ // If we get a percent higher than 100, we send back INVALID_VALUE.
+ addGoToPercentAction(101);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_INVALID_VALUE);
+ runScript();
- // If we get a percent that is not 0 or 100 and we do not have the
- // PartialBarrier bit set in the Capabilities attribute, then we send back
- // INVALID_VALUE.
- addGoToPercentAction(50);
- addDefaultResponseCheck((partialBarrier
- ? EMBER_ZCL_STATUS_SUCCESS
- : EMBER_ZCL_STATUS_INVALID_VALUE));
- addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- (partialBarrier
- ? 50
- : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED));
- runScript();
+ // If we get a percent that is not 0 or 100 and we do not have the
+ // PartialBarrier bit set in the Capabilities attribute, then we send back
+ // INVALID_VALUE.
+ addGoToPercentAction(50);
+ addDefaultResponseCheck((partialBarrier ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_INVALID_VALUE));
+ addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
+ (partialBarrier ? 50 : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED));
+ runScript();
- // Reset the barrier to closed.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addInitialStateCheck();
- runScript();
+ // Reset the barrier to closed.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addInitialStateCheck();
+ runScript();
- // We are closed right now, so if we receive an open, we should open the door.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
- // Halfway through the opening of the door if we read the Position attribute,
- // we will get an invalid value because the PartialBarrier bit is note set in
- // the Capabilities attribute...sure. Also, the MovingState attribute should
- // be set appropriately.
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- (partialBarrier
- ? 50
- : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_OPENING);
- addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- runScript();
+ // We are closed right now, so if we receive an open, we should open the door.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
+ // Halfway through the opening of the door if we read the Position attribute,
+ // we will get an invalid value because the PartialBarrier bit is note set in
+ // the Capabilities attribute...sure. Also, the MovingState attribute should
+ // be set appropriately.
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
+ (partialBarrier ? 50 : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_OPENING);
+ addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ runScript();
- // Once the door is opened, the MovingState attribute should go back to
- // STOPPED.
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- runScript();
+ // Once the door is opened, the MovingState attribute should go back to
+ // STOPPED.
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ runScript();
- // If we try to open the door again, we should just stay at open.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- runScript();
+ // If we try to open the door again, we should just stay at open.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ runScript();
- // Let's close the door again, for fun.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- runScript();
+ // Let's close the door again, for fun.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ runScript();
}
static void openTest(void)
{
- reallyOpenTest(false); // PartialBarrier bit of Capabilities attribute is off
+ reallyOpenTest(false); // PartialBarrier bit of Capabilities attribute is off
}
static void openPartialBarrierTest(void)
{
- reallyOpenTest(true); // PartialBarrier bit of Capabilities attribute is on
+ reallyOpenTest(true); // PartialBarrier bit of Capabilities attribute is on
}
// -------------------------------------
@@ -333,85 +270,72 @@
static void reallyCloseTest(bool partialBarrier)
{
- addInitialStateCheck();
- runScript();
+ addInitialStateCheck();
+ runScript();
- // Set/clear the partial barrier bit depending on what test we are running.
- addSetPartialBarrierBitAction(partialBarrier);
- addGetAttributeCheck(ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
- (partialBarrier
- ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER
- : 0));
- runScript();
+ // Set/clear the partial barrier bit depending on what test we are running.
+ addSetPartialBarrierBitAction(partialBarrier);
+ addGetAttributeCheck(ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
+ (partialBarrier ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER : 0));
+ runScript();
- // If we try to close the door again, we should just stay at close.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(1);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addRunAction(1);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- runScript();
+ // If we try to close the door again, we should just stay at close.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(1);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addRunAction(1);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ runScript();
- // Open the door and then close it all the way.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
- // Halfway through the closing of the door if we read the Position attribute,
- // we will get an invalid value because the PartialBarrier bit is not set in
- // the Capabilities attribute...sure. Also, the MovingState attribute should
- // be set appropriately.
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- (partialBarrier
- ? 50
- : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_CLOSING);
- addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ // Open the door and then close it all the way.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
+ // Halfway through the closing of the door if we read the Position attribute,
+ // we will get an invalid value because the PartialBarrier bit is not set in
+ // the Capabilities attribute...sure. Also, the MovingState attribute should
+ // be set appropriately.
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
+ (partialBarrier ? 50 : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_CLOSING);
+ addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- // Once the door is opened, the MovingState attribute should go back to
- // STOPPED.
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- runScript();
+ // Once the door is opened, the MovingState attribute should go back to
+ // STOPPED.
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ runScript();
- // If we try to close the door again, we should just stay at close.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- runScript();
+ // If we try to close the door again, we should just stay at close.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addRunAction(1 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ runScript();
- // Let's open the door again, for fun.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- runScript();
+ // Let's open the door again, for fun.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ runScript();
}
static void closeTest(void)
{
- reallyCloseTest(false); // PartialBarrier bit of Capabilities attribute is off
+ reallyCloseTest(false); // PartialBarrier bit of Capabilities attribute is off
}
static void closePartialBarrierTest(void)
{
- reallyCloseTest(true); // PartialBarrier bit of Capabilities attribute is on
+ reallyCloseTest(true); // PartialBarrier bit of Capabilities attribute is on
}
// --------------------------------------
@@ -419,84 +343,70 @@
static void reallyStopTest(bool partialBarrier)
{
- addInitialStateCheck();
- runScript();
+ addInitialStateCheck();
+ runScript();
- // Set/clear the partial barrier bit depending on what test we are running.
- addSetPartialBarrierBitAction(partialBarrier);
- addGetAttributeCheck(ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
- (partialBarrier
- ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER
- : 0));
- runScript();
+ // Set/clear the partial barrier bit depending on what test we are running.
+ addSetPartialBarrierBitAction(partialBarrier);
+ addGetAttributeCheck(ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
+ (partialBarrier ? EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER : 0));
+ runScript();
- // Start to open the door, and then stop midway. The door should remain at the
- // stopped position. The BarrierPosition attribute returns 0xFF, since the
- // PartialBarrier bit in the Capabilities attribute is not set.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_OPENING);
- addStopAction();
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- (partialBarrier
- ? 50
- : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- runScript();
+ // Start to open the door, and then stop midway. The door should remain at the
+ // stopped position. The BarrierPosition attribute returns 0xFF, since the
+ // PartialBarrier bit in the Capabilities attribute is not set.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_OPENING);
+ addStopAction();
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
+ (partialBarrier ? 50 : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ runScript();
- // Start the opening of the barrier again. It should open up fully.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- runScript();
+ // Start the opening of the barrier again. It should open up fully.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ runScript();
- // Start to close the door, and then stop midway. The door should remain at the
- // stopped position. The BarrierPosition attribute returns 0xFF, since the
- // PartialBarrier bit in the Capabilities attribute is not set.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_CLOSING);
- addStopAction();
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- (partialBarrier
- ? 50
- : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- runScript();
+ // Start to close the door, and then stop midway. The door should remain at the
+ // stopped position. The BarrierPosition attribute returns 0xFF, since the
+ // PartialBarrier bit in the Capabilities attribute is not set.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_CLOSING);
+ addStopAction();
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
+ (partialBarrier ? 50 : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ runScript();
- // Start the closing of the barrier again. It should close up fully.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- runScript();
+ // Start the closing of the barrier again. It should close up fully.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addGetAttributeCheck(ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ runScript();
}
static void stopTest(void)
{
- reallyStopTest(false); // PartialBarrier bit of Capabilities attribute is off
+ reallyStopTest(false); // PartialBarrier bit of Capabilities attribute is off
}
static void stopPartialBarrierTest(void)
{
- reallyStopTest(true); // PartialBarrier bit of Capabilities attribute is on
+ reallyStopTest(true); // PartialBarrier bit of Capabilities attribute is on
}
// -------------------------------------
@@ -504,48 +414,44 @@
static void remoteLockoutTest(void)
{
- addInitialStateCheck();
- runScript();
+ addInitialStateCheck();
+ runScript();
- // If we try to open the door, we should fail because the RemoteLockout bit
- // in the SafetyStatus attribute is set. The door should remain closed.
- addSetRemoteLockoutAction(true);
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_FAILURE);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- runScript();
+ // If we try to open the door, we should fail because the RemoteLockout bit
+ // in the SafetyStatus attribute is set. The door should remain closed.
+ addSetRemoteLockoutAction(true);
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_FAILURE);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ runScript();
- // Clear the RemoteLockout bit of the SafetyStatus attribute and try to
- // open the door. We should be able to do so now.
- addSetRemoteLockoutAction(false);
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- runScript();
+ // Clear the RemoteLockout bit of the SafetyStatus attribute and try to
+ // open the door. We should be able to do so now.
+ addSetRemoteLockoutAction(false);
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ runScript();
- // Set the RemoteLockout bit of the SafetyStatus attribute again - we should
- // not be able to close the door.
- addSetRemoteLockoutAction(true);
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_FAILURE);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- runScript();
+ // Set the RemoteLockout bit of the SafetyStatus attribute again - we should
+ // not be able to close the door.
+ addSetRemoteLockoutAction(true);
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_FAILURE);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ runScript();
- // Clear the RemoteLockout bit of the SafetyStatus attribute again - we should
- // now be able to close the door.
- addSetRemoteLockoutAction(false);
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- runScript();
+ // Clear the RemoteLockout bit of the SafetyStatus attribute again - we should
+ // now be able to close the door.
+ addSetRemoteLockoutAction(false);
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addGetAttributeCheck(ZCL_BARRIER_POSITION_ATTRIBUTE_ID, EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ runScript();
}
// -------------------------------------
@@ -553,67 +459,67 @@
static void openCloseEventsTest(void)
{
- addInitialStateCheck();
- runScript();
+ addInitialStateCheck();
+ runScript();
- // At boot, the open/close events attributes should all be 0.
- addOpenCloseEventsCheck(0, 0, 0, 0);
- runScript();
+ // At boot, the open/close events attributes should all be 0.
+ addOpenCloseEventsCheck(0, 0, 0, 0);
+ runScript();
- // Open the door. Open event counts should be incremented.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(1, 0, 1, 0);
- runScript();
+ // Open the door. Open event counts should be incremented.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(1, 0, 1, 0);
+ runScript();
- // Close the door. Close event counts should be incremented.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(1, 1, 1, 1);
- runScript();
+ // Close the door. Close event counts should be incremented.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(1, 1, 1, 1);
+ runScript();
- // Open the door half way. Open event counts should be incremented.
- addSetPartialBarrierBitAction(true);
- addGoToPercentAction(50);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(2, 1, 2, 1);
- runScript();
+ // Open the door half way. Open event counts should be incremented.
+ addSetPartialBarrierBitAction(true);
+ addGoToPercentAction(50);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(2, 1, 2, 1);
+ runScript();
- // Open the door the rest of the way. Only the command event count should be incremented.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(2, 1, 3, 1);
- runScript();
+ // Open the door the rest of the way. Only the command event count should be incremented.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(2, 1, 3, 1);
+ runScript();
- // Close the door half way. Only the command event count should be incremented.
- addGoToPercentAction(50);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(2, 1, 3, 2);
- runScript();
+ // Close the door half way. Only the command event count should be incremented.
+ addGoToPercentAction(50);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(50 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(2, 1, 3, 2);
+ runScript();
- // Close the door the rest of the way. Both close event counts should be incremented.
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(2, 2, 3, 3);
- runScript();
+ // Close the door the rest of the way. Both close event counts should be incremented.
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(51 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(2, 2, 3, 3);
+ runScript();
- // Set all of the event counts equal to the maximum value for a 16-bit unsigned
- // integer in Zigbee (0xFFFE). Make sure the value doesn't roll past that.
- addSetOpenCloseEventsAction(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE);
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE);
- addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
- addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
- addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
- addOpenCloseEventsCheck(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE);
+ // Set all of the event counts equal to the maximum value for a 16-bit unsigned
+ // integer in Zigbee (0xFFFE). Make sure the value doesn't roll past that.
+ addSetOpenCloseEventsAction(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE);
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE);
+ addGoToPercentAction(EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED);
+ addDefaultResponseCheck(EMBER_ZCL_STATUS_SUCCESS);
+ addRunAction(101 * MIN_POSITION_CHANGE_DELAY_MS);
+ addOpenCloseEventsCheck(0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE);
}
// -----------------------------------------------------------------------------
@@ -622,22 +528,22 @@
// --------------------------------------
// Miscellaneous
-uint8_t emAfPluginReportingConditionallyAddReportingEntry(EmberAfPluginReportingEntry* newEntry)
+uint8_t emAfPluginReportingConditionallyAddReportingEntry(EmberAfPluginReportingEntry * newEntry)
{
- assert("this function should not be called" == NULL);
- return 0;
+ assert("this function should not be called" == NULL);
+ return 0;
}
// -------------------------------------
// Messaging Stubs
static EmberApsFrame apsFrame = {
- .destinationEndpoint = 1, // endpoint
+ .destinationEndpoint = 1, // endpoint
};
static EmberAfClusterCommand clusterCommand = {
- .apsFrame = &apsFrame,
+ .apsFrame = &apsFrame,
};
-EmberAfClusterCommand *emAfCurrentCommand = &clusterCommand;
+EmberAfClusterCommand * emAfCurrentCommand = &clusterCommand;
// -------------------------------------
// Cluster Event Stubs
@@ -647,139 +553,160 @@
static void barrierControlClusterEventHandler(void)
{
- // Generated by AppBuilder.
- extern void emberAfBarrierControlClusterServerTickCallback(uint8_t);
- emberAfBarrierControlClusterServerTickCallback(1); // endpoint
+ // Generated by AppBuilder.
+ extern void emberAfBarrierControlClusterServerTickCallback(uint8_t);
+ emberAfBarrierControlClusterServerTickCallback(1); // endpoint
}
-EmberStatus emberAfScheduleServerTick(uint8_t endpoint,
- EmberAfClusterId clusterId,
- uint32_t delayMs)
+EmberStatus emberAfScheduleServerTick(uint8_t endpoint, EmberAfClusterId clusterId, uint32_t delayMs)
{
- assert(clusterId == ZCL_BARRIER_CONTROL_CLUSTER_ID);
- emberEventControlSetDelayMS(barrierControlClusterEventControl, delayMs);
- return EMBER_SUCCESS;
+ assert(clusterId == ZCL_BARRIER_CONTROL_CLUSTER_ID);
+ emberEventControlSetDelayMS(barrierControlClusterEventControl, delayMs);
+ return EMBER_SUCCESS;
}
-EmberStatus emberAfDeactivateServerTick(uint8_t endpoint,
- EmberAfClusterId clusterId)
+EmberStatus emberAfDeactivateServerTick(uint8_t endpoint, EmberAfClusterId clusterId)
{
- assert(clusterId == ZCL_BARRIER_CONTROL_CLUSTER_ID);
- emberEventControlSetInactive(barrierControlClusterEventControl);
- return EMBER_SUCCESS;
+ assert(clusterId == ZCL_BARRIER_CONTROL_CLUSTER_ID);
+ emberEventControlSetInactive(barrierControlClusterEventControl);
+ return EMBER_SUCCESS;
}
// -------------------------------------
// Attribute stubs
-typedef struct {
- void *valueLocation;
- uint8_t size;
+typedef struct
+{
+ void * valueLocation;
+ uint8_t size;
} AttributeData;
-#define ATTRIBUTE_DATA_ENTRY(storage) { &(storage), sizeof((storage)), }
-#define ATTRIBUTE_DATA_ENTRY_NULL() { NULL, 0, }
+#define ATTRIBUTE_DATA_ENTRY(storage) \
+ { \
+ &(storage), sizeof((storage)), \
+ }
+#define ATTRIBUTE_DATA_ENTRY_NULL() \
+ { \
+ NULL, 0, \
+ }
-static EmberStatus readOrWriteAttribute(uint8_t endpoint,
- EmberAfClusterId cluster,
- EmberAfAttributeId attributeId,
- uint8_t *dataPtr,
- uint8_t dataTypeOrReadLength,
- bool read)
+static EmberStatus readOrWriteAttribute(uint8_t endpoint, EmberAfClusterId cluster, EmberAfAttributeId attributeId,
+ uint8_t * dataPtr, uint8_t dataTypeOrReadLength, bool read)
{
- static uint8_t movingState = 0;
- static uint16_t safetyStatus = 0;
- static uint8_t capabilities = 0;
- static uint16_t openEvents = 0;
- static uint16_t closeEvents = 0;
- static uint16_t commandOpenEvents = 0;
- static uint16_t commandCloseEvents = 0;
- static uint16_t openOrClosePeriod = 0;
- static uint8_t position = EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED;
- static const AttributeData attributeData[] = {
- ATTRIBUTE_DATA_ENTRY_NULL(), // 0x0000
- ATTRIBUTE_DATA_ENTRY(movingState), // 0x0001
- ATTRIBUTE_DATA_ENTRY(safetyStatus), // 0x0002
- ATTRIBUTE_DATA_ENTRY(capabilities), // 0x0003
- ATTRIBUTE_DATA_ENTRY(openEvents), // 0x0004
- ATTRIBUTE_DATA_ENTRY(closeEvents), // 0x0004
- ATTRIBUTE_DATA_ENTRY(commandOpenEvents), // 0x0006
- ATTRIBUTE_DATA_ENTRY(commandCloseEvents), // 0x0007
- ATTRIBUTE_DATA_ENTRY(openOrClosePeriod), // 0x0008
- ATTRIBUTE_DATA_ENTRY(openOrClosePeriod), // 0x0009
- ATTRIBUTE_DATA_ENTRY(position), // 0x000A
- };
+ static uint8_t movingState = 0;
+ static uint16_t safetyStatus = 0;
+ static uint8_t capabilities = 0;
+ static uint16_t openEvents = 0;
+ static uint16_t closeEvents = 0;
+ static uint16_t commandOpenEvents = 0;
+ static uint16_t commandCloseEvents = 0;
+ static uint16_t openOrClosePeriod = 0;
+ static uint8_t position = EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED;
+ static const AttributeData attributeData[] = {
+ ATTRIBUTE_DATA_ENTRY_NULL(), // 0x0000
+ ATTRIBUTE_DATA_ENTRY(movingState), // 0x0001
+ ATTRIBUTE_DATA_ENTRY(safetyStatus), // 0x0002
+ ATTRIBUTE_DATA_ENTRY(capabilities), // 0x0003
+ ATTRIBUTE_DATA_ENTRY(openEvents), // 0x0004
+ ATTRIBUTE_DATA_ENTRY(closeEvents), // 0x0004
+ ATTRIBUTE_DATA_ENTRY(commandOpenEvents), // 0x0006
+ ATTRIBUTE_DATA_ENTRY(commandCloseEvents), // 0x0007
+ ATTRIBUTE_DATA_ENTRY(openOrClosePeriod), // 0x0008
+ ATTRIBUTE_DATA_ENTRY(openOrClosePeriod), // 0x0009
+ ATTRIBUTE_DATA_ENTRY(position), // 0x000A
+ };
- const AttributeData *attribute = attributeData + attributeId;
- assert(cluster == ZCL_BARRIER_CONTROL_CLUSTER_ID);
- if (attributeId > COUNTOF(attributeData) || attribute->valueLocation == NULL) {
- assert("unknown attribute ID!" == NULL);
- }
+ const AttributeData * attribute = attributeData + attributeId;
+ assert(cluster == ZCL_BARRIER_CONTROL_CLUSTER_ID);
+ if (attributeId > COUNTOF(attributeData) || attribute->valueLocation == NULL)
+ {
+ assert("unknown attribute ID!" == NULL);
+ }
- if (read) {
- MEMMOVE(dataPtr, attribute->valueLocation, attribute->size);
- } else {
- MEMMOVE(attribute->valueLocation, dataPtr, attribute->size);
- }
+ if (read)
+ {
+ MEMMOVE(dataPtr, attribute->valueLocation, attribute->size);
+ }
+ else
+ {
+ MEMMOVE(attribute->valueLocation, dataPtr, attribute->size);
+ }
- return EMBER_ZCL_STATUS_SUCCESS;
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-EmberAfStatus emberAfReadServerAttribute(uint8_t endpoint,
- EmberAfClusterId cluster,
- EmberAfAttributeId attributeId,
- uint8_t* dataPtr,
- uint8_t readLength)
+EmberAfStatus emberAfReadServerAttribute(uint8_t endpoint, EmberAfClusterId cluster, EmberAfAttributeId attributeId,
+ uint8_t * dataPtr, uint8_t readLength)
{
- return readOrWriteAttribute(endpoint,
- cluster,
- attributeId,
- dataPtr,
- readLength,
- true);
+ return readOrWriteAttribute(endpoint, cluster, attributeId, dataPtr, readLength, true);
}
-EmberAfStatus emberAfWriteServerAttribute(uint8_t endpoint,
- EmberAfClusterId cluster,
- EmberAfAttributeId attributeId,
- uint8_t* dataPtr,
- uint8_t dataType)
+EmberAfStatus emberAfWriteServerAttribute(uint8_t endpoint, EmberAfClusterId cluster, EmberAfAttributeId attributeId,
+ uint8_t * dataPtr, uint8_t dataType)
{
- return readOrWriteAttribute(endpoint,
- cluster,
- attributeId,
- dataPtr,
- dataType,
- false);
+ return readOrWriteAttribute(endpoint, cluster, attributeId, dataPtr, dataType, false);
}
// -----------------------------------------------------------------------------
// Main
static Test tests[] = {
- { "open-test", openTest, },
- { "open-partial-barrier-test", openPartialBarrierTest, },
- { "close-test", closeTest, },
- { "close-partial-barrier-test", closePartialBarrierTest, },
- { "stop-test", stopTest, },
- { "stop-partial-barrier-test", stopPartialBarrierTest, },
- { "remote-lockout-test", remoteLockoutTest, },
- { "open-close-events-test", openCloseEventsTest, },
- { NULL, NULL, },
+ {
+ "open-test",
+ openTest,
+ },
+ {
+ "open-partial-barrier-test",
+ openPartialBarrierTest,
+ },
+ {
+ "close-test",
+ closeTest,
+ },
+ {
+ "close-partial-barrier-test",
+ closePartialBarrierTest,
+ },
+ {
+ "stop-test",
+ stopTest,
+ },
+ {
+ "stop-partial-barrier-test",
+ stopPartialBarrierTest,
+ },
+ {
+ "remote-lockout-test",
+ remoteLockoutTest,
+ },
+ {
+ "open-close-events-test",
+ openCloseEventsTest,
+ },
+ {
+ NULL,
+ NULL,
+ },
};
-int main(int argc, char *argv[])
+int main(int argc, char * argv[])
{
- Thunk test = parseTestArgument(argc, argv, tests);
- test();
- fprintf(stderr, " done ]\n");
- return 0;
+ Thunk test = parseTestArgument(argc, argv, tests);
+ test();
+ fprintf(stderr, " done ]\n");
+ return 0;
}
void scriptTickCallback(void)
{
- static EmberEventData data[] = {
- { &barrierControlClusterEventControl, barrierControlClusterEventHandler, },
- { NULL, NULL, },
- };
- emberRunEvents(data);
+ static EmberEventData data[] = {
+ {
+ &barrierControlClusterEventControl,
+ barrierControlClusterEventHandler,
+ },
+ {
+ NULL,
+ NULL,
+ },
+ };
+ emberRunEvents(data);
}
diff --git a/src/app/clusters/barrier-control-server/barrier-control-server.c b/src/app/clusters/barrier-control-server/barrier-control-server.c
index 0e9f42b..9e49763 100644
--- a/src/app/clusters/barrier-control-server/barrier-control-server.c
+++ b/src/app/clusters/barrier-control-server/barrier-control-server.c
@@ -31,196 +31,160 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Implementation for the Barrier Control Server plugin.
+ * @brief Implementation for the Barrier Control
+ *Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-#include "af.h"
#include "barrier-control-server.h"
+#include "af.h"
// We need this for initializating default reporting configurations.
#include "app/framework/plugin/reporting/reporting.h"
-typedef struct {
- uint8_t currentPosition;
- uint8_t targetPosition;
- bool increasing;
- uint32_t delayMs;
+typedef struct
+{
+ uint8_t currentPosition;
+ uint8_t targetPosition;
+ bool increasing;
+ uint32_t delayMs;
} State;
static State state;
#ifdef EMBER_SCRIPTED_TEST
- #define ZCL_USING_BARRIER_CONTROL_CLUSTER_OPEN_PERIOD_ATTRIBUTE
- #define ZCL_USING_BARRIER_CONTROL_CLUSTER_CLOSE_PERIOD_ATTRIBUTE
- #define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_OPEN_EVENTS_ATTRIBUTE
- #define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_CLOSE_EVENTS_ATTRIBUTE
- #define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_COMMAND_OPEN_EVENTS_ATTRIBUTE
- #define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_COMMAND_CLOSE_EVENTS_ATTRIBUTE
+#define ZCL_USING_BARRIER_CONTROL_CLUSTER_OPEN_PERIOD_ATTRIBUTE
+#define ZCL_USING_BARRIER_CONTROL_CLUSTER_CLOSE_PERIOD_ATTRIBUTE
+#define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_OPEN_EVENTS_ATTRIBUTE
+#define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_CLOSE_EVENTS_ATTRIBUTE
+#define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_COMMAND_OPEN_EVENTS_ATTRIBUTE
+#define ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_COMMAND_CLOSE_EVENTS_ATTRIBUTE
#endif
// -----------------------------------------------------------------------------
// Framework initialization
-void emberAfPluginBarrierControlServerInitCallback(void)
-{
-}
+void emberAfPluginBarrierControlServerInitCallback(void) {}
// -----------------------------------------------------------------------------
// Accessing attributes
uint8_t emAfPluginBarrierControlServerGetBarrierPosition(uint8_t endpoint)
{
- uint8_t position;
- EmberAfStatus status = emberAfReadServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- &position,
- sizeof(position));
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
- return position;
+ uint8_t position;
+ EmberAfStatus status = emberAfReadServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
+ &position, sizeof(position));
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ return position;
}
-void emAfPluginBarrierControlServerSetBarrierPosition(uint8_t endpoint,
- uint8_t position)
+void emAfPluginBarrierControlServerSetBarrierPosition(uint8_t endpoint, uint8_t position)
{
- EmberAfStatus status
- = emberAfWriteServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
- &position,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ EmberAfStatus status = emberAfWriteServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, ZCL_BARRIER_POSITION_ATTRIBUTE_ID,
+ &position, ZCL_INT8U_ATTRIBUTE_TYPE);
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
}
bool emAfPluginBarrierControlServerIsPartialBarrierSupported(uint8_t endpoint)
{
- uint8_t bitmap;
- EmberAfStatus status
- = emberAfReadServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID,
- &bitmap,
- sizeof(bitmap));
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
- return READBITS(bitmap, EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER);
+ uint8_t bitmap;
+ EmberAfStatus status = emberAfReadServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID,
+ ZCL_BARRIER_CAPABILITIES_ATTRIBUTE_ID, &bitmap, sizeof(bitmap));
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ return READBITS(bitmap, EMBER_AF_BARRIER_CONTROL_CAPABILITIES_PARTIAL_BARRIER);
}
static uint16_t getOpenOrClosePeriod(uint8_t endpoint, bool open)
{
- uint16_t period = 0;
- EmberAfAttributeId attributeId = 0xFFFF;
+ uint16_t period = 0;
+ EmberAfAttributeId attributeId = 0xFFFF;
#if defined(ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_OPEN_PERIOD_ATTRIBUTE)
- if (open) {
- attributeId = ZCL_BARRIER_OPEN_PERIOD_ATTRIBUTE_ID;
- }
+ if (open)
+ {
+ attributeId = ZCL_BARRIER_OPEN_PERIOD_ATTRIBUTE_ID;
+ }
#endif
#if defined(ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_CLOSE_PERIOD_ATTRIBUTE)
- if (!open) {
- attributeId = ZCL_BARRIER_CLOSE_PERIOD_ATTRIBUTE_ID;
- }
+ if (!open)
+ {
+ attributeId = ZCL_BARRIER_CLOSE_PERIOD_ATTRIBUTE_ID;
+ }
#endif
- if (attributeId != 0xFFFF) {
- EmberAfStatus status
- = emberAfReadServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- attributeId,
- (uint8_t *)&period,
- sizeof(period));
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
- }
+ if (attributeId != 0xFFFF)
+ {
+ EmberAfStatus status =
+ emberAfReadServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, attributeId, (uint8_t *) &period, sizeof(period));
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ }
- return period;
+ return period;
}
static void setMovingState(uint8_t endpoint, uint8_t state)
{
- EmberAfStatus status
- = emberAfWriteServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID,
- &state,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ EmberAfStatus status = emberAfWriteServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID,
+ ZCL_BARRIER_MOVING_STATE_ATTRIBUTE_ID, &state, ZCL_ENUM8_ATTRIBUTE_TYPE);
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
}
uint16_t emAfPluginBarrierControlServerGetSafetyStatus(uint8_t endpoint)
{
- uint16_t safetyStatus;
- EmberAfStatus status
- = emberAfReadServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- ZCL_BARRIER_SAFETY_STATUS_ATTRIBUTE_ID,
- (uint8_t *)&safetyStatus,
- sizeof(safetyStatus));
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
- return safetyStatus;
+ uint16_t safetyStatus;
+ EmberAfStatus status =
+ emberAfReadServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, ZCL_BARRIER_SAFETY_STATUS_ATTRIBUTE_ID,
+ (uint8_t *) &safetyStatus, sizeof(safetyStatus));
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ return safetyStatus;
}
static bool isRemoteLockoutOn(uint8_t endpoint)
{
- uint16_t safetyStatus
- = emAfPluginBarrierControlServerGetSafetyStatus(endpoint);
- return READBITS(safetyStatus,
- EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT);
+ uint16_t safetyStatus = emAfPluginBarrierControlServerGetSafetyStatus(endpoint);
+ return READBITS(safetyStatus, EMBER_AF_BARRIER_CONTROL_SAFETY_STATUS_REMOTE_LOCKOUT);
}
-void emAfPluginBarrierControlServerIncrementEvents(uint8_t endpoint,
- bool open,
- bool command)
+void emAfPluginBarrierControlServerIncrementEvents(uint8_t endpoint, bool open, bool command)
{
- uint8_t mask = (0
+ uint8_t mask = (0
#if defined(ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_OPEN_EVENTS_ATTRIBUTE)
- | (open && !command
- ? BIT(0)
- : 0)
+ | (open && !command ? BIT(0) : 0)
#endif
#if defined(ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_CLOSE_EVENTS_ATTRIBUTE)
- | (!open && !command
- ? BIT(1)
- : 0)
+ | (!open && !command ? BIT(1) : 0)
#endif
#if defined(ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_COMMAND_OPEN_EVENTS_ATTRIBUTE)
- | (open && command
- ? BIT(2)
- : 0)
+ | (open && command ? BIT(2) : 0)
#endif
#if defined(ZCL_USING_BARRIER_CONTROL_CLUSTER_BARRIER_COMMAND_CLOSE_EVENTS_ATTRIBUTE)
- | (!open && command
- ? BIT(3)
- : 0)
+ | (!open && command ? BIT(3) : 0)
#endif
- );
+ );
- EmberAfAttributeId baseEventAttributeId = ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID;
- for (size_t bit = 0; bit < 4; bit++) {
- if (READBIT(mask, bit)) {
- EmberAfAttributeId attributeId = baseEventAttributeId + bit;
- uint16_t events;
- EmberAfStatus status
- = emberAfReadServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- attributeId,
- (uint8_t *)&events,
- sizeof(events));
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ EmberAfAttributeId baseEventAttributeId = ZCL_BARRIER_OPEN_EVENTS_ATTRIBUTE_ID;
+ for (size_t bit = 0; bit < 4; bit++)
+ {
+ if (READBIT(mask, bit))
+ {
+ EmberAfAttributeId attributeId = baseEventAttributeId + bit;
+ uint16_t events;
+ EmberAfStatus status = emberAfReadServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, attributeId,
+ (uint8_t *) &events, sizeof(events));
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
- // Section 7.1.2.1.5-8 says that this events counter SHALL NOT roll over.
- // The maximum 16-bit unsigned integer in Zigbee is 0xFFFE, so we have this
- // check here.
- if (events != UINT16_MAX - 1) {
- events++;
- status = emberAfWriteServerAttribute(endpoint,
- ZCL_BARRIER_CONTROL_CLUSTER_ID,
- attributeId,
- (uint8_t *)&events,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- assert(status == EMBER_ZCL_STATUS_SUCCESS);
- }
+ // Section 7.1.2.1.5-8 says that this events counter SHALL NOT roll over.
+ // The maximum 16-bit unsigned integer in Zigbee is 0xFFFE, so we have this
+ // check here.
+ if (events != UINT16_MAX - 1)
+ {
+ events++;
+ status = emberAfWriteServerAttribute(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, attributeId, (uint8_t *) &events,
+ ZCL_INT16U_ATTRIBUTE_TYPE);
+ assert(status == EMBER_ZCL_STATUS_SUCCESS);
+ }
+ }
}
- }
}
// -----------------------------------------------------------------------------
@@ -228,72 +192,72 @@
static uint8_t getCurrentPosition(uint8_t endpoint)
{
- // If the BarrierPosition attribute does not store the exact position of the
- // barrier, then it will be set to 0xFF. If this is the case, then we have no
- // way of knowing the position of the barrier. Let's guess that the barrier is
- // open so that we don't leave the barrier open when it should be closed.
- uint8_t currentPositionFromAttribute
- = emAfPluginBarrierControlServerGetBarrierPosition(endpoint);
- return ((currentPositionFromAttribute
- == EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN)
- ? EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN
- : currentPositionFromAttribute);
+ // If the BarrierPosition attribute does not store the exact position of the
+ // barrier, then it will be set to 0xFF. If this is the case, then we have no
+ // way of knowing the position of the barrier. Let's guess that the barrier is
+ // open so that we don't leave the barrier open when it should be closed.
+ uint8_t currentPositionFromAttribute = emAfPluginBarrierControlServerGetBarrierPosition(endpoint);
+ return ((currentPositionFromAttribute == EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN)
+ ? EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN
+ : currentPositionFromAttribute);
}
-static uint32_t calculateDelayMs(uint8_t endpoint,
- uint8_t targetPosition,
- bool *opening)
+static uint32_t calculateDelayMs(uint8_t endpoint, uint8_t targetPosition, bool * opening)
{
- uint8_t currentPosition
- = emAfPluginBarrierControlServerGetBarrierPosition(endpoint);
- *opening = targetPosition > currentPosition;
- uint8_t positionDelta = (*opening
- ? targetPosition - currentPosition
- : currentPosition - targetPosition);
- uint16_t openOrClosePeriodDs = getOpenOrClosePeriod(endpoint, *opening);
- uint32_t openOrClosePeriodMs
- = openOrClosePeriodDs * MILLISECOND_TICKS_PER_DECISECOND;
+ uint8_t currentPosition = emAfPluginBarrierControlServerGetBarrierPosition(endpoint);
+ *opening = targetPosition > currentPosition;
+ uint8_t positionDelta = (*opening ? targetPosition - currentPosition : currentPosition - targetPosition);
+ uint16_t openOrClosePeriodDs = getOpenOrClosePeriod(endpoint, *opening);
+ uint32_t openOrClosePeriodMs = openOrClosePeriodDs * MILLISECOND_TICKS_PER_DECISECOND;
- // We use a minimum delay so that our barrier changes position in a realistic
- // amount of time.
- if (openOrClosePeriodDs == 0 || positionDelta == 0) {
- return MIN_POSITION_CHANGE_DELAY_MS;
- } else {
- uint32_t delayMs = openOrClosePeriodMs / positionDelta;
- return (delayMs < MIN_POSITION_CHANGE_DELAY_MS
- ? MIN_POSITION_CHANGE_DELAY_MS
- : delayMs);
- }
+ // We use a minimum delay so that our barrier changes position in a realistic
+ // amount of time.
+ if (openOrClosePeriodDs == 0 || positionDelta == 0)
+ {
+ return MIN_POSITION_CHANGE_DELAY_MS;
+ }
+ else
+ {
+ uint32_t delayMs = openOrClosePeriodMs / positionDelta;
+ return (delayMs < MIN_POSITION_CHANGE_DELAY_MS ? MIN_POSITION_CHANGE_DELAY_MS : delayMs);
+ }
}
void emberAfBarrierControlClusterServerTickCallback(uint8_t endpoint)
{
- if (state.currentPosition == state.targetPosition) {
- emAfPluginBarrierControlServerSetBarrierPosition(endpoint, state.currentPosition);
- setMovingState(endpoint, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- emberAfDeactivateServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID);
- } else {
- if (state.increasing) {
- if (++state.currentPosition == 1) {
- // Zero -> nonzero: open event
- emAfPluginBarrierControlServerIncrementEvents(endpoint, true, false);
- }
- } else {
- if (--state.currentPosition == 0) {
- // Nonzero -> zero: close event
- emAfPluginBarrierControlServerIncrementEvents(endpoint, false, false);
- }
+ if (state.currentPosition == state.targetPosition)
+ {
+ emAfPluginBarrierControlServerSetBarrierPosition(endpoint, state.currentPosition);
+ setMovingState(endpoint, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ emberAfDeactivateServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID);
}
- emAfPluginBarrierControlServerSetBarrierPosition(endpoint,
- (emAfPluginBarrierControlServerIsPartialBarrierSupported(endpoint)
- ? state.currentPosition
- : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
- setMovingState(endpoint,
- (state.increasing
- ? EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_OPENING
- : EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_CLOSING));
- emberAfScheduleServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, state.delayMs);
- }
+ else
+ {
+ if (state.increasing)
+ {
+ if (++state.currentPosition == 1)
+ {
+ // Zero -> nonzero: open event
+ emAfPluginBarrierControlServerIncrementEvents(endpoint, true, false);
+ }
+ }
+ else
+ {
+ if (--state.currentPosition == 0)
+ {
+ // Nonzero -> zero: close event
+ emAfPluginBarrierControlServerIncrementEvents(endpoint, false, false);
+ }
+ }
+ emAfPluginBarrierControlServerSetBarrierPosition(endpoint,
+ (emAfPluginBarrierControlServerIsPartialBarrierSupported(endpoint)
+ ? state.currentPosition
+ : EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_UNKNOWN));
+ setMovingState(
+ endpoint,
+ (state.increasing ? EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_OPENING : EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_CLOSING));
+ emberAfScheduleServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, state.delayMs);
+ }
}
// -----------------------------------------------------------------------------
@@ -301,54 +265,59 @@
static void sendDefaultResponse(EmberAfStatus status)
{
- if (emberAfSendImmediateDefaultResponse(status) != EMBER_SUCCESS) {
- emberAfBarrierControlClusterPrintln("Failed to send default response");
- }
+ if (emberAfSendImmediateDefaultResponse(status) != EMBER_SUCCESS)
+ {
+ emberAfBarrierControlClusterPrintln("Failed to send default response");
+ }
}
bool emberAfBarrierControlClusterBarrierControlGoToPercentCallback(uint8_t percentOpen)
{
- uint8_t endpoint = emberAfCurrentCommand()->apsFrame->destinationEndpoint;
- EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
+ uint8_t endpoint = emberAfCurrentCommand()->apsFrame->destinationEndpoint;
+ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
- emberAfBarrierControlClusterPrintln("RX: GoToPercentCallback p=%d", percentOpen);
+ emberAfBarrierControlClusterPrintln("RX: GoToPercentCallback p=%d", percentOpen);
- if (isRemoteLockoutOn(endpoint)) {
- status = EMBER_ZCL_STATUS_FAILURE;
- } else if (percentOpen > 100 // "100" means "100%", so greater than that is invalid
- || (!emAfPluginBarrierControlServerIsPartialBarrierSupported(endpoint)
- && percentOpen != EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED
- && percentOpen != EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN)) {
- status = EMBER_ZCL_STATUS_INVALID_VALUE;
- } else {
- state.currentPosition = getCurrentPosition(endpoint);
- state.targetPosition = percentOpen;
- state.delayMs = calculateDelayMs(endpoint,
- state.targetPosition,
- &state.increasing);
- emberAfBarrierControlClusterPrintln("Scheduling barrier move from %d to %d with %dms delay",
- state.currentPosition,
- state.targetPosition,
- state.delayMs);
- emberAfScheduleServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, state.delayMs);
-
- if (state.currentPosition < state.targetPosition) {
- emAfPluginBarrierControlServerIncrementEvents(endpoint, true, true);
- } else if (state.currentPosition > state.targetPosition) {
- emAfPluginBarrierControlServerIncrementEvents(endpoint, false, true);
+ if (isRemoteLockoutOn(endpoint))
+ {
+ status = EMBER_ZCL_STATUS_FAILURE;
}
- }
+ else if (percentOpen > 100 // "100" means "100%", so greater than that is invalid
+ || (!emAfPluginBarrierControlServerIsPartialBarrierSupported(endpoint) &&
+ percentOpen != EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_CLOSED &&
+ percentOpen != EMBER_ZCL_BARRIER_CONTROL_BARRIER_POSITION_OPEN))
+ {
+ status = EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
+ else
+ {
+ state.currentPosition = getCurrentPosition(endpoint);
+ state.targetPosition = percentOpen;
+ state.delayMs = calculateDelayMs(endpoint, state.targetPosition, &state.increasing);
+ emberAfBarrierControlClusterPrintln("Scheduling barrier move from %d to %d with %dms delay", state.currentPosition,
+ state.targetPosition, state.delayMs);
+ emberAfScheduleServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID, state.delayMs);
- sendDefaultResponse(status);
+ if (state.currentPosition < state.targetPosition)
+ {
+ emAfPluginBarrierControlServerIncrementEvents(endpoint, true, true);
+ }
+ else if (state.currentPosition > state.targetPosition)
+ {
+ emAfPluginBarrierControlServerIncrementEvents(endpoint, false, true);
+ }
+ }
- return true;
+ sendDefaultResponse(status);
+
+ return true;
}
bool emberAfBarrierControlClusterBarrierControlStopCallback(void)
{
- uint8_t endpoint = emberAfCurrentCommand()->apsFrame->destinationEndpoint;
- emberAfDeactivateServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID);
- setMovingState(endpoint, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
- sendDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ uint8_t endpoint = emberAfCurrentCommand()->apsFrame->destinationEndpoint;
+ emberAfDeactivateServerTick(endpoint, ZCL_BARRIER_CONTROL_CLUSTER_ID);
+ setMovingState(endpoint, EMBER_ZCL_BARRIER_CONTROL_MOVING_STATE_STOPPED);
+ sendDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
diff --git a/src/app/clusters/barrier-control-server/barrier-control-server.h b/src/app/clusters/barrier-control-server/barrier-control-server.h
index a6007f9..96cfcd7 100644
--- a/src/app/clusters/barrier-control-server/barrier-control-server.h
+++ b/src/app/clusters/barrier-control-server/barrier-control-server.h
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief APIs for the Barrier Control Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// There are helper getter/setting APIs that are shared between the core
@@ -47,8 +47,7 @@
// This will always either set the current BarrierPosition attribute value or
// assert.
-void emAfPluginBarrierControlServerSetBarrierPosition(uint8_t endpoint,
- uint8_t barrierPosition);
+void emAfPluginBarrierControlServerSetBarrierPosition(uint8_t endpoint, uint8_t barrierPosition);
// This will either return whether or not the PartialBarrier bit is set in the
// Capabilities attribute value, or it will assert.
@@ -57,9 +56,7 @@
// This will increment the OpenEvents, CloseEvents, CommandOpenEvents, and
// CommandCloseEvents attribute values depending on which combination of the
// open and command arguments are passed, or assert.
-void emAfPluginBarrierControlServerIncrementEvents(uint8_t endpoint,
- bool open,
- bool command);
+void emAfPluginBarrierControlServerIncrementEvents(uint8_t endpoint, bool open, bool command);
// This will read the SafetyStatus attribute and return the value, or assert.
uint16_t emAfPluginBarrierControlServerGetSafetyStatus(uint8_t endpoint);
diff --git a/src/app/clusters/basic/basic.c b/src/app/clusters/basic/basic.c
index 8313146..904ac2c 100644
--- a/src/app/clusters/basic/basic.c
+++ b/src/app/clusters/basic/basic.c
@@ -31,11 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Implementation for the Basic Server Cluster plugin.
+ * @brief Implementation for the Basic Server Cluster
+ *plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "../../include/af.h"
@@ -43,9 +44,9 @@
bool emberAfBasicClusterResetToFactoryDefaultsCallback(void)
{
- emberAfBasicClusterPrintln("RX: ResetToFactoryDefaultsCallback");
- emberAfResetAttributes(emberAfCurrentEndpoint());
- emberAfPluginBasicResetToFactoryDefaultsCallback(emberAfCurrentEndpoint());
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfBasicClusterPrintln("RX: ResetToFactoryDefaultsCallback");
+ emberAfResetAttributes(emberAfCurrentEndpoint());
+ emberAfPluginBasicResetToFactoryDefaultsCallback(emberAfCurrentEndpoint());
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
diff --git a/src/app/clusters/color-control-server/color-control-server.c b/src/app/clusters/color-control-server/color-control-server.c
index 23e2657..91f6eab 100644
--- a/src/app/clusters/color-control-server/color-control-server.c
+++ b/src/app/clusters/color-control-server/color-control-server.c
@@ -31,46 +31,50 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Color Control Server plugin.
+ * @brief Routines for the Color Control Server
+ *plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
#include "app/framework/util/attribute-storage.h"
#ifdef EMBER_AF_PLUGIN_REPORTING
- #include "app/framework/plugin/reporting/reporting.h"
+#include "app/framework/plugin/reporting/reporting.h"
#endif
#define COLOR_TEMP_CONTROL emberAfPluginColorControlServerTempTransitionEventControl
-#define COLOR_XY_CONTROL emberAfPluginColorControlServerXyTransitionEventControl
-#define COLOR_HSV_CONTROL emberAfPluginColorControlServerHueSatTransitionEventControl
+#define COLOR_XY_CONTROL emberAfPluginColorControlServerXyTransitionEventControl
+#define COLOR_HSV_CONTROL emberAfPluginColorControlServerHueSatTransitionEventControl
// move mode
-enum {
- MOVE_MODE_STOP = 0x00,
- MOVE_MODE_UP = 0x01,
- MOVE_MODE_DOWN = 0x03
+enum
+{
+ MOVE_MODE_STOP = 0x00,
+ MOVE_MODE_UP = 0x01,
+ MOVE_MODE_DOWN = 0x03
};
-enum {
- COLOR_MODE_HSV = 0x00,
- COLOR_MODE_CIE_XY = 0x01,
- COLOR_MODE_TEMPERATURE = 0x02
+enum
+{
+ COLOR_MODE_HSV = 0x00,
+ COLOR_MODE_CIE_XY = 0x01,
+ COLOR_MODE_TEMPERATURE = 0x02
};
-enum {
- HSV_TO_HSV = 0x00,
- HSV_TO_CIE_XY = 0x01,
- HSV_TO_TEMPERATURE = 0x02,
- CIE_XY_TO_HSV = 0x10,
- CIE_XY_TO_CIE_XY = 0x11,
- CIE_XY_TO_TEMPERATURE = 0x12,
- TEMPERATURE_TO_HSV = 0x20,
- TEMPERATURE_TO_CIE_XY = 0x21,
- TEMPERATURE_TO_TEMPERATURE = 0x22
+enum
+{
+ HSV_TO_HSV = 0x00,
+ HSV_TO_CIE_XY = 0x01,
+ HSV_TO_TEMPERATURE = 0x02,
+ CIE_XY_TO_HSV = 0x10,
+ CIE_XY_TO_CIE_XY = 0x11,
+ CIE_XY_TO_TEMPERATURE = 0x12,
+ TEMPERATURE_TO_HSV = 0x20,
+ TEMPERATURE_TO_CIE_XY = 0x21,
+ TEMPERATURE_TO_TEMPERATURE = 0x22
};
EmberEventControl emberAfPluginColorControlServerTempTransitionEventControl;
@@ -95,28 +99,30 @@
#define REPORT_FAILED 0xFF
-typedef struct {
- uint8_t initialHue;
- uint8_t currentHue;
- uint8_t finalHue;
- uint16_t stepsRemaining;
- uint16_t stepsTotal;
- uint8_t endpoint;
- bool up;
- bool repeat;
+typedef struct
+{
+ uint8_t initialHue;
+ uint8_t currentHue;
+ uint8_t finalHue;
+ uint16_t stepsRemaining;
+ uint16_t stepsTotal;
+ uint8_t endpoint;
+ bool up;
+ bool repeat;
} ColorHueTransitionState;
static ColorHueTransitionState colorHueTransitionState;
-typedef struct {
- uint16_t initialValue;
- uint16_t currentValue;
- uint16_t finalValue;
- uint16_t stepsRemaining;
- uint16_t stepsTotal;
- uint16_t lowLimit;
- uint16_t highLimit;
- uint8_t endpoint;
+typedef struct
+{
+ uint16_t initialValue;
+ uint16_t currentValue;
+ uint16_t finalValue;
+ uint16_t stepsRemaining;
+ uint16_t stepsTotal;
+ uint16_t lowLimit;
+ uint16_t highLimit;
+ uint8_t endpoint;
} Color16uTransitionState;
static Color16uTransitionState colorXTransitionState;
@@ -127,13 +133,10 @@
static Color16uTransitionState colorSaturationTransitionState;
// Forward declarations:
-static bool computeNewColor16uValue(Color16uTransitionState *p);
+static bool computeNewColor16uValue(Color16uTransitionState * p);
static void stopAllColorTransitions(void);
-static void handleModeSwitch(uint8_t endpoint,
- uint8_t newColorMode);
-static bool shouldExecuteIfOff(uint8_t endpoint,
- uint8_t optionMask,
- uint8_t optionOverride);
+static void handleModeSwitch(uint8_t endpoint, uint8_t newColorMode);
+static bool shouldExecuteIfOff(uint8_t endpoint, uint8_t optionMask, uint8_t optionOverride);
#ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_HSV
static uint8_t addHue(uint8_t hue1, uint8_t hue2);
@@ -151,190 +154,150 @@
static uint16_t readColorY(uint8_t endpoint);
#endif
-static uint16_t computeTransitionTimeFromStateAndRate(Color16uTransitionState *p,
- uint16_t rate);
+static uint16_t computeTransitionTimeFromStateAndRate(Color16uTransitionState * p, uint16_t rate);
// convenient token handling functions
static uint8_t readColorMode(uint8_t endpoint)
{
- uint8_t colorMode;
+ uint8_t colorMode;
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID,
- (uint8_t *)&colorMode,
- sizeof(uint8_t)));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID,
+ (uint8_t *) &colorMode, sizeof(uint8_t)));
- return colorMode;
+ return colorMode;
}
static uint16_t readColorTemperature(uint8_t endpoint)
{
- uint16_t colorTemperature;
+ uint16_t colorTemperature;
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
- (uint8_t *)&colorTemperature,
- sizeof(uint16_t)));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
+ (uint8_t *) &colorTemperature, sizeof(uint16_t)));
- return colorTemperature;
+ return colorTemperature;
}
static uint16_t readColorTemperatureMin(uint8_t endpoint)
{
- uint16_t colorTemperatureMin;
- EmberStatus status;
+ uint16_t colorTemperatureMin;
+ EmberStatus status;
- status =
- emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMP_PHYSICAL_MIN_ATTRIBUTE_ID,
- (uint8_t *)&colorTemperatureMin,
- sizeof(uint16_t));
+ status =
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMP_PHYSICAL_MIN_ATTRIBUTE_ID,
+ (uint8_t *) &colorTemperatureMin, sizeof(uint16_t));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- colorTemperatureMin = MIN_TEMPERATURE_VALUE;
- }
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ colorTemperatureMin = MIN_TEMPERATURE_VALUE;
+ }
- return colorTemperatureMin;
+ return colorTemperatureMin;
}
static uint16_t readColorTemperatureMax(uint8_t endpoint)
{
- uint16_t colorTemperatureMax;
- EmberStatus status;
+ uint16_t colorTemperatureMax;
+ EmberStatus status;
- status =
- emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMP_PHYSICAL_MAX_ATTRIBUTE_ID,
- (uint8_t *)&colorTemperatureMax,
- sizeof(uint16_t));
+ status =
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMP_PHYSICAL_MAX_ATTRIBUTE_ID,
+ (uint8_t *) &colorTemperatureMax, sizeof(uint16_t));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- colorTemperatureMax = MAX_TEMPERATURE_VALUE;
- }
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ colorTemperatureMax = MAX_TEMPERATURE_VALUE;
+ }
- return colorTemperatureMax;
+ return colorTemperatureMax;
}
static uint16_t readColorTemperatureCoupleToLevelMin(uint8_t endpoint)
{
- uint16_t colorTemperatureCoupleToLevelMin;
- EmberStatus status;
+ uint16_t colorTemperatureCoupleToLevelMin;
+ EmberStatus status;
- status =
- emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_TEMPERATURE_LEVEL_MIN_MIREDS_ATTRIBUTE_ID,
- (uint8_t *)&colorTemperatureCoupleToLevelMin,
- sizeof(uint16_t));
+ status = emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID,
+ ZCL_COLOR_CONTROL_TEMPERATURE_LEVEL_MIN_MIREDS_ATTRIBUTE_ID,
+ (uint8_t *) &colorTemperatureCoupleToLevelMin, sizeof(uint16_t));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- // Not less than the physical min.
- colorTemperatureCoupleToLevelMin = readColorTemperatureMin(endpoint);
- }
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ // Not less than the physical min.
+ colorTemperatureCoupleToLevelMin = readColorTemperatureMin(endpoint);
+ }
- return colorTemperatureCoupleToLevelMin;
+ return colorTemperatureCoupleToLevelMin;
}
static uint8_t readLevelControlCurrentLevel(uint8_t endpoint)
{
- uint8_t currentLevel;
- EmberStatus status;
+ uint8_t currentLevel;
+ EmberStatus status;
- status =
- emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)¤tLevel,
- sizeof(uint8_t));
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) ¤tLevel, sizeof(uint8_t));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- currentLevel = 0x7F; // midpoint of range 0x01-0xFE
- }
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ currentLevel = 0x7F; // midpoint of range 0x01-0xFE
+ }
- return currentLevel;
+ return currentLevel;
}
static void writeRemainingTime(uint8_t endpoint, uint16_t remainingTime)
{
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_REMAINING_TIME_ATTRIBUTE_ID,
- (uint8_t *)&remainingTime,
- ZCL_INT16U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_REMAINING_TIME_ATTRIBUTE_ID,
+ (uint8_t *) &remainingTime, ZCL_INT16U_ATTRIBUTE_TYPE));
}
static void writeColorMode(uint8_t endpoint, uint8_t colorMode)
{
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_ENHANCED_COLOR_MODE_ATTRIBUTE_ID,
- (uint8_t *)&colorMode,
- ZCL_INT8U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_ENHANCED_COLOR_MODE_ATTRIBUTE_ID,
+ (uint8_t *) &colorMode, ZCL_INT8U_ATTRIBUTE_TYPE));
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID,
- (uint8_t *)&colorMode,
- ZCL_INT8U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID,
+ (uint8_t *) &colorMode, ZCL_INT8U_ATTRIBUTE_TYPE));
}
static void writeHue(uint8_t endpoint, uint8_t hue)
{
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID,
- (uint8_t *)&hue,
- ZCL_INT8U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID,
+ (uint8_t *) &hue, ZCL_INT8U_ATTRIBUTE_TYPE));
}
static void writeSaturation(uint8_t endpoint, uint8_t saturation)
{
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
- (uint8_t *)&saturation,
- ZCL_INT8U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
+ (uint8_t *) &saturation, ZCL_INT8U_ATTRIBUTE_TYPE));
}
static void writeColorX(uint8_t endpoint, uint16_t colorX)
{
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
- (uint8_t *)&colorX,
- ZCL_INT16U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
+ (uint8_t *) &colorX, ZCL_INT16U_ATTRIBUTE_TYPE));
}
static void writeColorY(uint8_t endpoint, uint16_t colorY)
{
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
- (uint8_t *)&colorY,
- ZCL_INT16U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
+ (uint8_t *) &colorY, ZCL_INT16U_ATTRIBUTE_TYPE));
}
static void writeColorTemperature(uint8_t endpoint, uint16_t colorTemperature)
{
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfWriteServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
- (uint8_t *)&colorTemperature,
- ZCL_INT16U_ATTRIBUTE_TYPE));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfWriteServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
+ (uint8_t *) &colorTemperature, ZCL_INT16U_ATTRIBUTE_TYPE));
}
// -------------------------------------------------------------------------
@@ -349,469 +312,486 @@
* @param saturation Ver.: always
* @param transitionTime Ver.: always
*/
-bool emberAfColorControlClusterMoveToHueAndSaturationCallback(uint8_t hue,
- uint8_t saturation,
- uint16_t transitionTime,
- uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterMoveToHueAndSaturationCallback(uint8_t hue, uint8_t saturation, uint16_t transitionTime,
+ uint8_t optionsMask, uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
- uint8_t currentHue = readHue(endpoint);
- bool moveUp;
+ uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t currentHue = readHue(endpoint);
+ bool moveUp;
- if (transitionTime == 0) {
- transitionTime++;
- }
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
- // limit checking: hue and saturation are 0..254. Spec dictates we ignore
- // this and report a malformed packet.
- if (hue > MAX_HUE_VALUE || saturation > MAX_SATURATION_VALUE) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
- return true;
- }
+ // limit checking: hue and saturation are 0..254. Spec dictates we ignore
+ // this and report a malformed packet.
+ if (hue > MAX_HUE_VALUE || saturation > MAX_SATURATION_VALUE)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
+ return true;
+ }
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ // compute shortest direction
+ if (hue > currentHue)
+ {
+ moveUp = (hue - currentHue) < HALF_MAX_UINT8T;
+ }
+ else
+ {
+ moveUp = (currentHue - hue) > HALF_MAX_UINT8T;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_HSV);
+
+ // now, kick off the state machine.
+ initHueSat(endpoint);
+
+ colorHueTransitionState.initialHue = currentHue;
+ colorHueTransitionState.currentHue = currentHue;
+ colorHueTransitionState.finalHue = hue;
+ colorHueTransitionState.stepsRemaining = transitionTime;
+ colorHueTransitionState.stepsTotal = transitionTime;
+ colorHueTransitionState.endpoint = endpoint;
+ colorHueTransitionState.up = moveUp;
+ colorHueTransitionState.repeat = false;
+
+ colorSaturationTransitionState.initialValue = readSaturation(endpoint);
+ colorSaturationTransitionState.currentValue = readSaturation(endpoint);
+ colorSaturationTransitionState.finalValue = saturation;
+ colorSaturationTransitionState.stepsRemaining = transitionTime;
+ colorSaturationTransitionState.stepsTotal = transitionTime;
+ colorSaturationTransitionState.endpoint = endpoint;
+ colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
+ colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- // compute shortest direction
- if (hue > currentHue) {
- moveUp = (hue - currentHue) < HALF_MAX_UINT8T;
- } else {
- moveUp = (currentHue - hue) > HALF_MAX_UINT8T;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_HSV);
-
- // now, kick off the state machine.
- initHueSat(endpoint);
-
- colorHueTransitionState.initialHue = currentHue;
- colorHueTransitionState.currentHue = currentHue;
- colorHueTransitionState.finalHue = hue;
- colorHueTransitionState.stepsRemaining = transitionTime;
- colorHueTransitionState.stepsTotal = transitionTime;
- colorHueTransitionState.endpoint = endpoint;
- colorHueTransitionState.up = moveUp;
- colorHueTransitionState.repeat = false;
-
- colorSaturationTransitionState.initialValue = readSaturation(endpoint);
- colorSaturationTransitionState.currentValue = readSaturation(endpoint);
- colorSaturationTransitionState.finalValue = saturation;
- colorSaturationTransitionState.stepsRemaining = transitionTime;
- colorSaturationTransitionState.stepsTotal = transitionTime;
- colorSaturationTransitionState.endpoint = endpoint;
- colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
- colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterMoveHueCallback(uint8_t moveMode,
- uint8_t rate,
- uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterMoveHueCallback(uint8_t moveMode, uint8_t rate, uint8_t optionsMask, uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ if (moveMode == EMBER_ZCL_HUE_MOVE_MODE_STOP)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_HSV);
+
+ // now, kick off the state machine.
+ initHueSat(endpoint);
+
+ colorHueTransitionState.initialHue = readHue(endpoint);
+ colorHueTransitionState.currentHue = readHue(endpoint);
+ if (moveMode == EMBER_ZCL_HUE_MOVE_MODE_UP)
+ {
+ colorHueTransitionState.finalHue = addHue(readHue(endpoint), rate);
+ colorHueTransitionState.up = true;
+ }
+ else if (moveMode == EMBER_ZCL_HUE_MOVE_MODE_DOWN)
+ {
+ colorHueTransitionState.finalHue = subtractHue(readHue(endpoint), rate);
+ colorHueTransitionState.up = false;
+ }
+ else
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
+ return true;
+ }
+ colorHueTransitionState.stepsRemaining = TRANSITION_TIME_1S;
+ colorHueTransitionState.stepsTotal = TRANSITION_TIME_1S;
+ colorHueTransitionState.endpoint = endpoint;
+ colorHueTransitionState.repeat = true;
+ // hue movement can last forever. Indicate this with a remaining time of
+ // maxint.
+ writeRemainingTime(endpoint, MAX_INT16U_VALUE);
+
+ colorSaturationTransitionState.stepsRemaining = 0;
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- if (moveMode == EMBER_ZCL_HUE_MOVE_MODE_STOP) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
- }
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_HSV);
-
- // now, kick off the state machine.
- initHueSat(endpoint);
-
- colorHueTransitionState.initialHue = readHue(endpoint);
- colorHueTransitionState.currentHue = readHue(endpoint);
- if (moveMode == EMBER_ZCL_HUE_MOVE_MODE_UP) {
- colorHueTransitionState.finalHue = addHue(readHue(endpoint),
- rate);
- colorHueTransitionState.up = true;
- } else if (moveMode == EMBER_ZCL_HUE_MOVE_MODE_DOWN) {
- colorHueTransitionState.finalHue = subtractHue(readHue(endpoint),
- rate);
- colorHueTransitionState.up = false;
- } else {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
- return true;
- }
- colorHueTransitionState.stepsRemaining = TRANSITION_TIME_1S;
- colorHueTransitionState.stepsTotal = TRANSITION_TIME_1S;
- colorHueTransitionState.endpoint = endpoint;
- colorHueTransitionState.repeat = true;
- // hue movement can last forever. Indicate this with a remaining time of
- // maxint.
- writeRemainingTime(endpoint, MAX_INT16U_VALUE);
-
- colorSaturationTransitionState.stepsRemaining = 0;
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterMoveSaturationCallback(uint8_t moveMode,
- uint8_t rate,
- uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterMoveSaturationCallback(uint8_t moveMode, uint8_t rate, uint8_t optionsMask, uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint16_t transitionTime;
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ if (moveMode == EMBER_ZCL_SATURATION_MOVE_MODE_STOP || rate == 0)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_HSV);
+
+ // now, kick off the state machine.
+ initHueSat(endpoint);
+
+ colorHueTransitionState.stepsRemaining = 0;
+
+ colorSaturationTransitionState.initialValue = readSaturation(endpoint);
+ colorSaturationTransitionState.currentValue = readSaturation(endpoint);
+ if (moveMode == EMBER_ZCL_SATURATION_MOVE_MODE_UP)
+ {
+ colorSaturationTransitionState.finalValue = MAX_SATURATION_VALUE;
+ }
+ else
+ {
+ colorSaturationTransitionState.finalValue = MIN_SATURATION_VALUE;
+ }
+
+ transitionTime = computeTransitionTimeFromStateAndRate(&colorSaturationTransitionState, rate);
+
+ colorSaturationTransitionState.stepsRemaining = transitionTime;
+ colorSaturationTransitionState.stepsTotal = transitionTime;
+ colorSaturationTransitionState.endpoint = endpoint;
+ colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
+ colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint16_t transitionTime;
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- if (moveMode == EMBER_ZCL_SATURATION_MOVE_MODE_STOP
- || rate == 0) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
- }
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_HSV);
-
- // now, kick off the state machine.
- initHueSat(endpoint);
-
- colorHueTransitionState.stepsRemaining = 0;
-
- colorSaturationTransitionState.initialValue = readSaturation(endpoint);
- colorSaturationTransitionState.currentValue = readSaturation(endpoint);
- if (moveMode == EMBER_ZCL_SATURATION_MOVE_MODE_UP) {
- colorSaturationTransitionState.finalValue = MAX_SATURATION_VALUE;
- } else {
- colorSaturationTransitionState.finalValue = MIN_SATURATION_VALUE;
- }
-
- transitionTime =
- computeTransitionTimeFromStateAndRate(&colorSaturationTransitionState,
- rate);
-
- colorSaturationTransitionState.stepsRemaining = transitionTime;
- colorSaturationTransitionState.stepsTotal = transitionTime;
- colorSaturationTransitionState.endpoint = endpoint;
- colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
- colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterMoveToHueCallback(uint8_t hue,
- uint8_t hueMoveMode,
- uint16_t transitionTime,
- uint8_t optionsMask,
+bool emberAfColorControlClusterMoveToHueCallback(uint8_t hue, uint8_t hueMoveMode, uint16_t transitionTime, uint8_t optionsMask,
uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint8_t currentHue = readHue(endpoint);
+ uint8_t direction;
+
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
+
+ // limit checking: hue and saturation are 0..254. Spec dictates we ignore
+ // this and report a malformed packet.
+ if (hue > MAX_HUE_VALUE)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
+ return true;
+ }
+
+ // For move to hue, the move modes are different from the other move commands.
+ // Need to translate from the move to hue transitions to the internal
+ // representation.
+ switch (hueMoveMode)
+ {
+ case EMBER_ZCL_HUE_DIRECTION_SHORTEST_DISTANCE:
+ if (((uint8_t)(currentHue - hue)) > HALF_MAX_UINT8T)
+ {
+ direction = MOVE_MODE_UP;
+ }
+ else
+ {
+ direction = MOVE_MODE_DOWN;
+ }
+ break;
+ case EMBER_ZCL_HUE_DIRECTION_LONGEST_DISTANCE:
+ if (((uint8_t)(currentHue - hue)) > HALF_MAX_UINT8T)
+ {
+ direction = MOVE_MODE_DOWN;
+ }
+ else
+ {
+ direction = MOVE_MODE_UP;
+ }
+ break;
+ break;
+ case EMBER_ZCL_HUE_DIRECTION_UP:
+ direction = MOVE_MODE_UP;
+ break;
+ case EMBER_ZCL_HUE_DIRECTION_DOWN:
+ direction = MOVE_MODE_DOWN;
+ break;
+ default:
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
+ return true;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_HSV);
+
+ // now, kick off the state machine.
+ initHueSat(endpoint);
+
+ colorHueTransitionState.initialHue = readHue(endpoint);
+ colorHueTransitionState.currentHue = readHue(endpoint);
+ colorHueTransitionState.finalHue = hue;
+ colorHueTransitionState.stepsRemaining = transitionTime;
+ colorHueTransitionState.stepsTotal = transitionTime;
+ colorHueTransitionState.endpoint = endpoint;
+ colorHueTransitionState.up = (direction == MOVE_MODE_UP);
+ colorHueTransitionState.repeat = false;
+
+ colorSaturationTransitionState.stepsRemaining = 0;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint8_t currentHue = readHue(endpoint);
- uint8_t direction;
-
- if (transitionTime == 0) {
- transitionTime++;
- }
-
- // limit checking: hue and saturation are 0..254. Spec dictates we ignore
- // this and report a malformed packet.
- if (hue > MAX_HUE_VALUE) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
- return true;
- }
-
- // For move to hue, the move modes are different from the other move commands.
- // Need to translate from the move to hue transitions to the internal
- // representation.
- switch (hueMoveMode) {
- case EMBER_ZCL_HUE_DIRECTION_SHORTEST_DISTANCE:
- if ( ((uint8_t) (currentHue - hue)) > HALF_MAX_UINT8T ) {
- direction = MOVE_MODE_UP;
- } else {
- direction = MOVE_MODE_DOWN;
- }
- break;
- case EMBER_ZCL_HUE_DIRECTION_LONGEST_DISTANCE:
- if ( ((uint8_t) (currentHue - hue)) > HALF_MAX_UINT8T ) {
- direction = MOVE_MODE_DOWN;
- } else {
- direction = MOVE_MODE_UP;
- }
- break;
- break;
- case EMBER_ZCL_HUE_DIRECTION_UP:
- direction = MOVE_MODE_UP;
- break;
- case EMBER_ZCL_HUE_DIRECTION_DOWN:
- direction = MOVE_MODE_DOWN;
- break;
- default:
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
- return true;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_HSV);
-
- // now, kick off the state machine.
- initHueSat(endpoint);
-
- colorHueTransitionState.initialHue = readHue(endpoint);
- colorHueTransitionState.currentHue = readHue(endpoint);
- colorHueTransitionState.finalHue = hue;
- colorHueTransitionState.stepsRemaining = transitionTime;
- colorHueTransitionState.stepsTotal = transitionTime;
- colorHueTransitionState.endpoint = endpoint;
- colorHueTransitionState.up = (direction == MOVE_MODE_UP);
- colorHueTransitionState.repeat = false;
-
- colorSaturationTransitionState.stepsRemaining = 0;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterMoveToSaturationCallback(uint8_t saturation,
- uint16_t transitionTime,
- uint8_t optionsMask,
+bool emberAfColorControlClusterMoveToSaturationCallback(uint8_t saturation, uint16_t transitionTime, uint8_t optionsMask,
uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
+
+ // limit checking: hue and saturation are 0..254. Spec dictates we ignore
+ // this and report a malformed packet.
+ if (saturation > MAX_SATURATION_VALUE)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
+ return true;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_HSV);
+
+ // now, kick off the state machine.
+ initHueSat(endpoint);
+
+ colorHueTransitionState.stepsRemaining = 0;
+
+ colorSaturationTransitionState.initialValue = readSaturation(endpoint);
+ colorSaturationTransitionState.currentValue = readSaturation(endpoint);
+ colorSaturationTransitionState.finalValue = saturation;
+ colorSaturationTransitionState.stepsRemaining = transitionTime;
+ colorSaturationTransitionState.stepsTotal = transitionTime;
+ colorSaturationTransitionState.endpoint = endpoint;
+ colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
+ colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- if (transitionTime == 0) {
- transitionTime++;
- }
-
- // limit checking: hue and saturation are 0..254. Spec dictates we ignore
- // this and report a malformed packet.
- if (saturation > MAX_SATURATION_VALUE) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_MALFORMED_COMMAND);
- return true;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_HSV);
-
- // now, kick off the state machine.
- initHueSat(endpoint);
-
- colorHueTransitionState.stepsRemaining = 0;
-
- colorSaturationTransitionState.initialValue = readSaturation(endpoint);
- colorSaturationTransitionState.currentValue = readSaturation(endpoint);
- colorSaturationTransitionState.finalValue = saturation;
- colorSaturationTransitionState.stepsRemaining = transitionTime;
- colorSaturationTransitionState.stepsTotal = transitionTime;
- colorSaturationTransitionState.endpoint = endpoint;
- colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
- colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterStepHueCallback(uint8_t stepMode,
- uint8_t stepSize,
- uint8_t transitionTime,
- uint8_t optionsMask,
+bool emberAfColorControlClusterStepHueCallback(uint8_t stepMode, uint8_t stepSize, uint8_t transitionTime, uint8_t optionsMask,
uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint8_t currentHue = readHue(endpoint);
+
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ if (stepMode == MOVE_MODE_STOP)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_HSV);
+
+ // now, kick off the state machine.
+ initHueSat(endpoint);
+
+ colorHueTransitionState.initialHue = currentHue;
+ colorHueTransitionState.currentHue = currentHue;
+
+ if (stepMode == MOVE_MODE_UP)
+ {
+ colorHueTransitionState.finalHue = addHue(currentHue, stepSize);
+ colorHueTransitionState.up = true;
+ }
+ else
+ {
+ colorHueTransitionState.finalHue = subtractHue(currentHue, stepSize);
+ colorHueTransitionState.up = false;
+ }
+ colorHueTransitionState.stepsRemaining = transitionTime;
+ colorHueTransitionState.stepsTotal = transitionTime;
+ colorHueTransitionState.endpoint = endpoint;
+ colorHueTransitionState.repeat = false;
+
+ colorSaturationTransitionState.stepsRemaining = 0;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint8_t currentHue = readHue(endpoint);
-
- if (transitionTime == 0) {
- transitionTime++;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- if (stepMode == MOVE_MODE_STOP) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
- }
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_HSV);
-
- // now, kick off the state machine.
- initHueSat(endpoint);
-
- colorHueTransitionState.initialHue = currentHue;
- colorHueTransitionState.currentHue = currentHue;
-
- if (stepMode == MOVE_MODE_UP) {
- colorHueTransitionState.finalHue = addHue(currentHue, stepSize);
- colorHueTransitionState.up = true;
- } else {
- colorHueTransitionState.finalHue = subtractHue(currentHue, stepSize);
- colorHueTransitionState.up = false;
- }
- colorHueTransitionState.stepsRemaining = transitionTime;
- colorHueTransitionState.stepsTotal = transitionTime;
- colorHueTransitionState.endpoint = endpoint;
- colorHueTransitionState.repeat = false;
-
- colorSaturationTransitionState.stepsRemaining = 0;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterStepSaturationCallback(uint8_t stepMode,
- uint8_t stepSize,
- uint8_t transitionTime,
- uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterStepSaturationCallback(uint8_t stepMode, uint8_t stepSize, uint8_t transitionTime,
+ uint8_t optionsMask, uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint8_t currentSaturation = readSaturation(endpoint);
+
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ if (stepMode == MOVE_MODE_STOP)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_HSV);
+
+ // now, kick off the state machine.
+ initHueSat(endpoint);
+
+ colorHueTransitionState.stepsRemaining = 0;
+
+ colorSaturationTransitionState.initialValue = currentSaturation;
+ colorSaturationTransitionState.currentValue = currentSaturation;
+
+ if (stepMode == MOVE_MODE_UP)
+ {
+ colorSaturationTransitionState.finalValue = addSaturation(currentSaturation, stepSize);
+ }
+ else
+ {
+ colorSaturationTransitionState.finalValue = subtractSaturation(currentSaturation, stepSize);
+ }
+ colorSaturationTransitionState.stepsRemaining = transitionTime;
+ colorSaturationTransitionState.stepsTotal = transitionTime;
+ colorSaturationTransitionState.endpoint = endpoint;
+ colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
+ colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint8_t currentSaturation = readSaturation(endpoint);
-
- if (transitionTime == 0) {
- transitionTime++;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- if (stepMode == MOVE_MODE_STOP) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
- }
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_HSV);
-
- // now, kick off the state machine.
- initHueSat(endpoint);
-
- colorHueTransitionState.stepsRemaining = 0;
-
- colorSaturationTransitionState.initialValue = currentSaturation;
- colorSaturationTransitionState.currentValue = currentSaturation;
-
- if (stepMode == MOVE_MODE_UP) {
- colorSaturationTransitionState.finalValue = addSaturation(currentSaturation,
- stepSize);
- } else {
- colorSaturationTransitionState.finalValue =
- subtractSaturation(currentSaturation,
- stepSize);
- }
- colorSaturationTransitionState.stepsRemaining = transitionTime;
- colorSaturationTransitionState.stepsTotal = transitionTime;
- colorSaturationTransitionState.endpoint = endpoint;
- colorSaturationTransitionState.lowLimit = MIN_SATURATION_VALUE;
- colorSaturationTransitionState.highLimit = MAX_SATURATION_VALUE;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
static uint8_t addSaturation(uint8_t saturation1, uint8_t saturation2)
{
- uint16_t saturation16;
+ uint16_t saturation16;
- saturation16 = ((uint16_t) saturation1);
- saturation16 += ((uint16_t) saturation2);
+ saturation16 = ((uint16_t) saturation1);
+ saturation16 += ((uint16_t) saturation2);
- if (saturation16 > MAX_SATURATION_VALUE) {
- saturation16 = MAX_SATURATION_VALUE;
- }
+ if (saturation16 > MAX_SATURATION_VALUE)
+ {
+ saturation16 = MAX_SATURATION_VALUE;
+ }
- return ((uint8_t) saturation16);
+ return ((uint8_t) saturation16);
}
static uint8_t subtractSaturation(uint8_t saturation1, uint8_t saturation2)
{
- if (saturation2 > saturation1) {
- return 0;
- }
+ if (saturation2 > saturation1)
+ {
+ return 0;
+ }
- return saturation1 - saturation2;
+ return saturation1 - saturation2;
}
// any time we call a hue or saturation transition, we need to assume certain
@@ -819,567 +799,577 @@
// properly initialize them.
static void initHueSat(uint8_t endpoint)
{
- colorHueTransitionState.stepsRemaining = 0;
- colorHueTransitionState.currentHue = readHue(endpoint);
- colorHueTransitionState.endpoint = endpoint;
+ colorHueTransitionState.stepsRemaining = 0;
+ colorHueTransitionState.currentHue = readHue(endpoint);
+ colorHueTransitionState.endpoint = endpoint;
- colorSaturationTransitionState.stepsRemaining = 0;
- colorSaturationTransitionState.currentValue = readSaturation(endpoint);
- colorSaturationTransitionState.endpoint = endpoint;
+ colorSaturationTransitionState.stepsRemaining = 0;
+ colorSaturationTransitionState.currentValue = readSaturation(endpoint);
+ colorSaturationTransitionState.endpoint = endpoint;
}
static uint8_t readHue(uint8_t endpoint)
{
- uint8_t hue;
+ uint8_t hue;
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID,
- (uint8_t *)&hue,
- sizeof(uint8_t)));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID,
+ (uint8_t *) &hue, sizeof(uint8_t)));
- return hue;
+ return hue;
}
static uint8_t readSaturation(uint8_t endpoint)
{
- uint8_t saturation;
+ uint8_t saturation;
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
- (uint8_t *)&saturation,
- sizeof(uint8_t)));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
+ (uint8_t *) &saturation, sizeof(uint8_t)));
- return saturation;
+ return saturation;
}
-#endif // #ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_HSV
+#endif // #ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_HSV
#ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_XY
-bool emberAfColorControlClusterMoveToColorCallback(uint16_t colorX,
- uint16_t colorY,
- uint16_t transitionTime,
- uint8_t optionsMask,
+bool emberAfColorControlClusterMoveToColorCallback(uint16_t colorX, uint16_t colorY, uint16_t transitionTime, uint8_t optionsMask,
uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_CIE_XY);
+
+ // now, kick off the state machine.
+ colorXTransitionState.initialValue = readColorX(endpoint);
+ colorXTransitionState.currentValue = readColorX(endpoint);
+ colorXTransitionState.finalValue = colorX;
+ colorXTransitionState.stepsRemaining = transitionTime;
+ colorXTransitionState.stepsTotal = transitionTime;
+ colorXTransitionState.endpoint = endpoint;
+ colorXTransitionState.lowLimit = MIN_CIE_XY_VALUE;
+ colorXTransitionState.highLimit = MAX_CIE_XY_VALUE;
+
+ colorYTransitionState.initialValue = readColorY(endpoint);
+ colorYTransitionState.currentValue = readColorY(endpoint);
+ colorYTransitionState.finalValue = colorY;
+ colorYTransitionState.stepsRemaining = transitionTime;
+ colorYTransitionState.stepsTotal = transitionTime;
+ colorYTransitionState.endpoint = endpoint;
+ colorYTransitionState.lowLimit = MIN_CIE_XY_VALUE;
+ colorYTransitionState.highLimit = MAX_CIE_XY_VALUE;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- if (transitionTime == 0) {
- transitionTime++;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_CIE_XY);
-
- // now, kick off the state machine.
- colorXTransitionState.initialValue = readColorX(endpoint);
- colorXTransitionState.currentValue = readColorX(endpoint);
- colorXTransitionState.finalValue = colorX;
- colorXTransitionState.stepsRemaining = transitionTime;
- colorXTransitionState.stepsTotal = transitionTime;
- colorXTransitionState.endpoint = endpoint;
- colorXTransitionState.lowLimit = MIN_CIE_XY_VALUE;
- colorXTransitionState.highLimit = MAX_CIE_XY_VALUE;
-
- colorYTransitionState.initialValue = readColorY(endpoint);
- colorYTransitionState.currentValue = readColorY(endpoint);
- colorYTransitionState.finalValue = colorY;
- colorYTransitionState.stepsRemaining = transitionTime;
- colorYTransitionState.stepsTotal = transitionTime;
- colorYTransitionState.endpoint = endpoint;
- colorYTransitionState.lowLimit = MIN_CIE_XY_VALUE;
- colorYTransitionState.highLimit = MAX_CIE_XY_VALUE;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterMoveColorCallback(int16_t rateX,
- int16_t rateY,
- uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterMoveColorCallback(int16_t rateX, int16_t rateY, uint8_t optionsMask, uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint16_t transitionTimeX, transitionTimeY;
+ uint16_t unsignedRate;
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ if (rateX == 0 && rateY == 0)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_CIE_XY);
+
+ // now, kick off the state machine.
+ colorXTransitionState.initialValue = readColorX(endpoint);
+ colorXTransitionState.currentValue = colorXTransitionState.initialValue;
+ if (rateX > 0)
+ {
+ colorXTransitionState.finalValue = MAX_CIE_XY_VALUE;
+ unsignedRate = (uint16_t) rateX;
+ }
+ else
+ {
+ colorXTransitionState.finalValue = MIN_CIE_XY_VALUE;
+ unsignedRate = (uint16_t)(rateX * -1);
+ }
+ transitionTimeX = computeTransitionTimeFromStateAndRate(&colorXTransitionState, unsignedRate);
+ colorXTransitionState.stepsRemaining = transitionTimeX;
+ colorXTransitionState.stepsTotal = transitionTimeX;
+ colorXTransitionState.endpoint = endpoint;
+ colorXTransitionState.lowLimit = MIN_CIE_XY_VALUE;
+ colorXTransitionState.highLimit = MAX_CIE_XY_VALUE;
+
+ colorYTransitionState.initialValue = readColorY(endpoint);
+ colorYTransitionState.currentValue = colorYTransitionState.initialValue;
+ if (rateY > 0)
+ {
+ colorYTransitionState.finalValue = MAX_CIE_XY_VALUE;
+ unsignedRate = (uint16_t) rateY;
+ }
+ else
+ {
+ colorYTransitionState.finalValue = MIN_CIE_XY_VALUE;
+ unsignedRate = (uint16_t)(rateY * -1);
+ }
+ transitionTimeY = computeTransitionTimeFromStateAndRate(&colorYTransitionState, unsignedRate);
+ colorYTransitionState.stepsRemaining = transitionTimeY;
+ colorYTransitionState.stepsTotal = transitionTimeY;
+ colorYTransitionState.endpoint = endpoint;
+ colorYTransitionState.lowLimit = MIN_CIE_XY_VALUE;
+ colorYTransitionState.highLimit = MAX_CIE_XY_VALUE;
+
+ if (transitionTimeX < transitionTimeY)
+ {
+ writeRemainingTime(endpoint, transitionTimeX);
+ }
+ else
+ {
+ writeRemainingTime(endpoint, transitionTimeY);
+ }
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint16_t transitionTimeX, transitionTimeY;
- uint16_t unsignedRate;
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- if (rateX == 0 && rateY == 0) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
- }
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_CIE_XY);
-
- // now, kick off the state machine.
- colorXTransitionState.initialValue = readColorX(endpoint);
- colorXTransitionState.currentValue = colorXTransitionState.initialValue;
- if (rateX > 0) {
- colorXTransitionState.finalValue = MAX_CIE_XY_VALUE;
- unsignedRate = (uint16_t) rateX;
- } else {
- colorXTransitionState.finalValue = MIN_CIE_XY_VALUE;
- unsignedRate = (uint16_t) (rateX * -1);
- }
- transitionTimeX =
- computeTransitionTimeFromStateAndRate(&colorXTransitionState,
- unsignedRate);
- colorXTransitionState.stepsRemaining = transitionTimeX;
- colorXTransitionState.stepsTotal = transitionTimeX;
- colorXTransitionState.endpoint = endpoint;
- colorXTransitionState.lowLimit = MIN_CIE_XY_VALUE;
- colorXTransitionState.highLimit = MAX_CIE_XY_VALUE;
-
- colorYTransitionState.initialValue = readColorY(endpoint);
- colorYTransitionState.currentValue = colorYTransitionState.initialValue;
- if (rateY > 0) {
- colorYTransitionState.finalValue = MAX_CIE_XY_VALUE;
- unsignedRate = (uint16_t) rateY;
- } else {
- colorYTransitionState.finalValue = MIN_CIE_XY_VALUE;
- unsignedRate = (uint16_t) (rateY * -1);
- }
- transitionTimeY =
- computeTransitionTimeFromStateAndRate(&colorYTransitionState,
- unsignedRate);
- colorYTransitionState.stepsRemaining = transitionTimeY;
- colorYTransitionState.stepsTotal = transitionTimeY;
- colorYTransitionState.endpoint = endpoint;
- colorYTransitionState.lowLimit = MIN_CIE_XY_VALUE;
- colorYTransitionState.highLimit = MAX_CIE_XY_VALUE;
-
- if (transitionTimeX < transitionTimeY) {
- writeRemainingTime(endpoint, transitionTimeX);
- } else {
- writeRemainingTime(endpoint, transitionTimeY);
- }
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterStepColorCallback(int16_t stepX,
- int16_t stepY,
- uint16_t transitionTime,
- uint8_t optionsMask,
+bool emberAfColorControlClusterStepColorCallback(int16_t stepX, int16_t stepY, uint16_t transitionTime, uint8_t optionsMask,
uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint16_t colorX = findNewColorValueFromStep(readColorX(endpoint), stepX);
+ uint16_t colorY = findNewColorValueFromStep(readColorY(endpoint), stepY);
+
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_CIE_XY);
+
+ // now, kick off the state machine.
+ colorXTransitionState.initialValue = readColorX(endpoint);
+ colorXTransitionState.currentValue = readColorX(endpoint);
+ colorXTransitionState.finalValue = colorX;
+ colorXTransitionState.stepsRemaining = transitionTime;
+ colorXTransitionState.stepsTotal = transitionTime;
+ colorXTransitionState.endpoint = endpoint;
+ colorXTransitionState.lowLimit = MIN_CIE_XY_VALUE;
+ colorXTransitionState.highLimit = MAX_CIE_XY_VALUE;
+
+ colorYTransitionState.initialValue = readColorY(endpoint);
+ colorYTransitionState.currentValue = readColorY(endpoint);
+ colorYTransitionState.finalValue = colorY;
+ colorYTransitionState.stepsRemaining = transitionTime;
+ colorYTransitionState.stepsTotal = transitionTime;
+ colorYTransitionState.endpoint = endpoint;
+ colorYTransitionState.lowLimit = MIN_CIE_XY_VALUE;
+ colorYTransitionState.highLimit = MAX_CIE_XY_VALUE;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint16_t colorX =
- findNewColorValueFromStep(readColorX(endpoint), stepX);
- uint16_t colorY =
- findNewColorValueFromStep(readColorY(endpoint), stepY);
-
- if (transitionTime == 0) {
- transitionTime++;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_CIE_XY);
-
- // now, kick off the state machine.
- colorXTransitionState.initialValue = readColorX(endpoint);
- colorXTransitionState.currentValue = readColorX(endpoint);
- colorXTransitionState.finalValue = colorX;
- colorXTransitionState.stepsRemaining = transitionTime;
- colorXTransitionState.stepsTotal = transitionTime;
- colorXTransitionState.endpoint = endpoint;
- colorXTransitionState.lowLimit = MIN_CIE_XY_VALUE;
- colorXTransitionState.highLimit = MAX_CIE_XY_VALUE;
-
- colorYTransitionState.initialValue = readColorY(endpoint);
- colorYTransitionState.currentValue = readColorY(endpoint);
- colorYTransitionState.finalValue = colorY;
- colorYTransitionState.stepsRemaining = transitionTime;
- colorYTransitionState.stepsTotal = transitionTime;
- colorYTransitionState.endpoint = endpoint;
- colorYTransitionState.lowLimit = MIN_CIE_XY_VALUE;
- colorYTransitionState.highLimit = MAX_CIE_XY_VALUE;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
static uint16_t findNewColorValueFromStep(uint16_t oldValue, int16_t step)
{
- uint16_t newValue;
- int32_t newValueSigned;
+ uint16_t newValue;
+ int32_t newValueSigned;
- newValueSigned = ((int32_t) oldValue) + ((int32_t) step);
+ newValueSigned = ((int32_t) oldValue) + ((int32_t) step);
- if (newValueSigned < 0) {
- newValue = 0;
- } else if (newValueSigned > MAX_CIE_XY_VALUE) {
- newValue = MAX_CIE_XY_VALUE;
- } else {
- newValue = (uint16_t) newValueSigned;
- }
+ if (newValueSigned < 0)
+ {
+ newValue = 0;
+ }
+ else if (newValueSigned > MAX_CIE_XY_VALUE)
+ {
+ newValue = MAX_CIE_XY_VALUE;
+ }
+ else
+ {
+ newValue = (uint16_t) newValueSigned;
+ }
- return newValue;
+ return newValue;
}
static uint16_t readColorX(uint8_t endpoint)
{
- uint16_t colorX;
+ uint16_t colorX;
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
- (uint8_t *)&colorX,
- sizeof(uint16_t)));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
+ (uint8_t *) &colorX, sizeof(uint16_t)));
- return colorX;
+ return colorX;
}
static uint16_t readColorY(uint8_t endpoint)
{
- uint16_t colorY;
+ uint16_t colorY;
- assert(EMBER_ZCL_STATUS_SUCCESS
- == emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
- (uint8_t *)&colorY,
- sizeof(uint16_t)));
+ assert(EMBER_ZCL_STATUS_SUCCESS ==
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
+ (uint8_t *) &colorY, sizeof(uint16_t)));
- return colorY;
+ return colorY;
}
-#endif //#ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_XY
+#endif //#ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_XY
#ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_TEMP
-static void moveToColorTemp(uint8_t endpoint,
- uint16_t colorTemperature,
- uint16_t transitionTime)
+static void moveToColorTemp(uint8_t endpoint, uint16_t colorTemperature, uint16_t transitionTime)
{
- uint16_t temperatureMin = readColorTemperatureMin(endpoint);
- uint16_t temperatureMax = readColorTemperatureMax(endpoint);
+ uint16_t temperatureMin = readColorTemperatureMin(endpoint);
+ uint16_t temperatureMax = readColorTemperatureMax(endpoint);
- if (transitionTime == 0) {
- transitionTime++;
- }
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_TEMPERATURE);
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_TEMPERATURE);
- if (colorTemperature < temperatureMin) {
- colorTemperature = temperatureMin;
- }
+ if (colorTemperature < temperatureMin)
+ {
+ colorTemperature = temperatureMin;
+ }
- if (colorTemperature > temperatureMax) {
- colorTemperature = temperatureMax;
- }
+ if (colorTemperature > temperatureMax)
+ {
+ colorTemperature = temperatureMax;
+ }
- // now, kick off the state machine.
- colorTempTransitionState.initialValue = readColorTemperature(endpoint);
- colorTempTransitionState.currentValue = readColorTemperature(endpoint);
- colorTempTransitionState.finalValue = colorTemperature;
- colorTempTransitionState.stepsRemaining = transitionTime;
- colorTempTransitionState.stepsTotal = transitionTime;
- colorTempTransitionState.endpoint = endpoint;
- colorTempTransitionState.lowLimit = temperatureMin;
- colorTempTransitionState.highLimit = temperatureMax;
+ // now, kick off the state machine.
+ colorTempTransitionState.initialValue = readColorTemperature(endpoint);
+ colorTempTransitionState.currentValue = readColorTemperature(endpoint);
+ colorTempTransitionState.finalValue = colorTemperature;
+ colorTempTransitionState.stepsRemaining = transitionTime;
+ colorTempTransitionState.stepsTotal = transitionTime;
+ colorTempTransitionState.endpoint = endpoint;
+ colorTempTransitionState.lowLimit = temperatureMin;
+ colorTempTransitionState.highLimit = temperatureMax;
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
}
-bool emberAfColorControlClusterMoveToColorTemperatureCallback(uint16_t colorTemperature,
- uint16_t transitionTime,
- uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterMoveToColorTemperatureCallback(uint16_t colorTemperature, uint16_t transitionTime,
+ uint8_t optionsMask, uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ moveToColorTemp(endpoint, colorTemperature, transitionTime);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- moveToColorTemp(endpoint, colorTemperature, transitionTime);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterMoveColorTemperatureCallback(uint8_t moveMode,
- uint16_t rate,
- uint16_t colorTemperatureMinimum,
- uint16_t colorTemperatureMaximum,
- uint8_t optionsMask,
+bool emberAfColorControlClusterMoveColorTemperatureCallback(uint8_t moveMode, uint16_t rate, uint16_t colorTemperatureMinimum,
+ uint16_t colorTemperatureMaximum, uint8_t optionsMask,
uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint16_t tempPhysicalMin = readColorTemperatureMin(endpoint);
+ uint16_t tempPhysicalMax = readColorTemperatureMax(endpoint);
+ uint16_t transitionTime;
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ if (moveMode == MOVE_MODE_STOP)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ if (rate == 0)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_FIELD);
+ return true;
+ }
+
+ if (colorTemperatureMinimum < tempPhysicalMin)
+ {
+ colorTemperatureMinimum = tempPhysicalMin;
+ }
+ if (colorTemperatureMaximum > tempPhysicalMax)
+ {
+ colorTemperatureMaximum = tempPhysicalMax;
+ }
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_TEMPERATURE);
+
+ // now, kick off the state machine.
+ colorTempTransitionState.initialValue = readColorTemperature(endpoint);
+ colorTempTransitionState.currentValue = readColorTemperature(endpoint);
+ if (moveMode == MOVE_MODE_UP)
+ {
+ if (tempPhysicalMax > colorTemperatureMaximum)
+ {
+ colorTempTransitionState.finalValue = colorTemperatureMaximum;
+ }
+ else
+ {
+ colorTempTransitionState.finalValue = tempPhysicalMax;
+ }
+ }
+ else
+ {
+ if (tempPhysicalMin < colorTemperatureMinimum)
+ {
+ colorTempTransitionState.finalValue = colorTemperatureMinimum;
+ }
+ else
+ {
+ colorTempTransitionState.finalValue = tempPhysicalMin;
+ }
+ }
+ transitionTime = computeTransitionTimeFromStateAndRate(&colorTempTransitionState, rate);
+ colorTempTransitionState.stepsRemaining = transitionTime;
+ colorTempTransitionState.stepsTotal = transitionTime;
+ colorTempTransitionState.endpoint = endpoint;
+ colorTempTransitionState.lowLimit = colorTemperatureMinimum;
+ colorTempTransitionState.highLimit = colorTemperatureMaximum;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint16_t tempPhysicalMin = readColorTemperatureMin(endpoint);
- uint16_t tempPhysicalMax = readColorTemperatureMax(endpoint);
- uint16_t transitionTime;
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- if (moveMode == MOVE_MODE_STOP) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
- }
-
- if (rate == 0) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_FIELD);
- return true;
- }
-
- if (colorTemperatureMinimum < tempPhysicalMin) {
- colorTemperatureMinimum = tempPhysicalMin;
- }
- if (colorTemperatureMaximum > tempPhysicalMax) {
- colorTemperatureMaximum = tempPhysicalMax;
- }
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_TEMPERATURE);
-
- // now, kick off the state machine.
- colorTempTransitionState.initialValue = readColorTemperature(endpoint);
- colorTempTransitionState.currentValue = readColorTemperature(endpoint);
- if (moveMode == MOVE_MODE_UP) {
- if (tempPhysicalMax > colorTemperatureMaximum) {
- colorTempTransitionState.finalValue = colorTemperatureMaximum;
- } else {
- colorTempTransitionState.finalValue = tempPhysicalMax;
- }
- } else {
- if (tempPhysicalMin < colorTemperatureMinimum) {
- colorTempTransitionState.finalValue = colorTemperatureMinimum;
- } else {
- colorTempTransitionState.finalValue = tempPhysicalMin;
- }
- }
- transitionTime =
- computeTransitionTimeFromStateAndRate(&colorTempTransitionState,
- rate);
- colorTempTransitionState.stepsRemaining = transitionTime;
- colorTempTransitionState.stepsTotal = transitionTime;
- colorTempTransitionState.endpoint = endpoint;
- colorTempTransitionState.lowLimit = colorTemperatureMinimum;
- colorTempTransitionState.highLimit = colorTemperatureMaximum;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
-bool emberAfColorControlClusterStepColorTemperatureCallback(uint8_t stepMode,
- uint16_t stepSize,
- uint16_t transitionTime,
- uint16_t colorTemperatureMinimum,
- uint16_t colorTemperatureMaximum,
- uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterStepColorTemperatureCallback(uint8_t stepMode, uint16_t stepSize, uint16_t transitionTime,
+ uint16_t colorTemperatureMinimum, uint16_t colorTemperatureMaximum,
+ uint8_t optionsMask, uint8_t optionsOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
+ if (!shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ uint16_t tempPhysicalMin = readColorTemperatureMin(endpoint);
+ uint16_t tempPhysicalMax = readColorTemperatureMax(endpoint);
+
+ if (transitionTime == 0)
+ {
+ transitionTime++;
+ }
+
+ // New command. Need to stop any active transitions.
+ stopAllColorTransitions();
+
+ if (stepMode == MOVE_MODE_STOP)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+ }
+
+ if (colorTemperatureMinimum < tempPhysicalMin)
+ {
+ colorTemperatureMinimum = tempPhysicalMin;
+ }
+ if (colorTemperatureMaximum > tempPhysicalMax)
+ {
+ colorTemperatureMaximum = tempPhysicalMax;
+ }
+
+ // Handle color mode transition, if necessary.
+ handleModeSwitch(endpoint, COLOR_MODE_TEMPERATURE);
+
+ // now, kick off the state machine.
+ colorTempTransitionState.initialValue = readColorTemperature(endpoint);
+ colorTempTransitionState.currentValue = readColorTemperature(endpoint);
+ if (stepMode == MOVE_MODE_UP)
+ {
+ colorTempTransitionState.finalValue = readColorTemperature(endpoint) + stepSize;
+ }
+ else
+ {
+ colorTempTransitionState.finalValue = readColorTemperature(endpoint) - stepSize;
+ }
+ colorTempTransitionState.stepsRemaining = transitionTime;
+ colorTempTransitionState.stepsTotal = transitionTime;
+ colorTempTransitionState.endpoint = endpoint;
+ colorTempTransitionState.lowLimit = colorTemperatureMinimum;
+ colorTempTransitionState.highLimit = colorTemperatureMaximum;
+
+ writeRemainingTime(endpoint, transitionTime);
+
+ // kick off the state machine:
+ emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
+
emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
return true;
- }
-
- uint16_t tempPhysicalMin = readColorTemperatureMin(endpoint);
- uint16_t tempPhysicalMax = readColorTemperatureMax(endpoint);
-
- if (transitionTime == 0) {
- transitionTime++;
- }
-
- // New command. Need to stop any active transitions.
- stopAllColorTransitions();
-
- if (stepMode == MOVE_MODE_STOP) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
- }
-
- if (colorTemperatureMinimum < tempPhysicalMin) {
- colorTemperatureMinimum = tempPhysicalMin;
- }
- if (colorTemperatureMaximum > tempPhysicalMax) {
- colorTemperatureMaximum = tempPhysicalMax;
- }
-
- // Handle color mode transition, if necessary.
- handleModeSwitch(endpoint, COLOR_MODE_TEMPERATURE);
-
- // now, kick off the state machine.
- colorTempTransitionState.initialValue = readColorTemperature(endpoint);
- colorTempTransitionState.currentValue = readColorTemperature(endpoint);
- if (stepMode == MOVE_MODE_UP) {
- colorTempTransitionState.finalValue
- = readColorTemperature(endpoint) + stepSize;
- } else {
- colorTempTransitionState.finalValue
- = readColorTemperature(endpoint) - stepSize;
- }
- colorTempTransitionState.stepsRemaining = transitionTime;
- colorTempTransitionState.stepsTotal = transitionTime;
- colorTempTransitionState.endpoint = endpoint;
- colorTempTransitionState.lowLimit = colorTemperatureMinimum;
- colorTempTransitionState.highLimit = colorTemperatureMaximum;
-
- writeRemainingTime(endpoint, transitionTime);
-
- // kick off the state machine:
- emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
-
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
}
void emberAfPluginLevelControlCoupledColorTempChangeCallback(uint8_t endpoint)
{
- // ZCL 5.2.2.1.1 Coupling color temperature to Level Control
- //
- // If the Level Control for Lighting cluster identifier 0x0008 is supported
- // on the same endpoint as the Color Control cluster and color temperature is
- // supported, it is possible to couple changes in the current level to the
- // color temperature.
- //
- // The CoupleColorTempToLevel bit of the Options attribute of the Level
- // Control cluster indicates whether the color temperature is to be linked
- // with the CurrentLevel attribute in the Level Control cluster.
- //
- // If the CoupleColorTempToLevel bit of the Options attribute of the Level
- // Control cluster is equal to 1 and the ColorMode or EnhancedColorMode
- // attribute is set to 0x02 (color temperature) then a change in the
- // CurrentLevel attribute SHALL affect the ColorTemperatureMireds attribute.
- // This relationship is manufacturer specific, with the qualification that
- // the maximum value of the CurrentLevel attribute SHALL correspond to a
- // ColorTemperatureMired attribute value equal to the
- // CoupleColorTempToLevelMinMireds attribute. This relationship is one-way so
- // a change to the ColorTemperatureMireds attribute SHALL NOT have any effect
- // on the CurrentLevel attribute.
- //
- // In order to simulate the behavior of an incandescent bulb, a low value of
- // the CurrentLevel attribute SHALL be associated with a high value of the
- // ColorTemperatureMireds attribute (i.e., a low value of color temperature
- // in kelvins).
- //
- // If the CoupleColorTempToLevel bit of the Options attribute of the Level
- // Control cluster is equal to 0, there SHALL be no link between color
- // temperature and current level.
+ // ZCL 5.2.2.1.1 Coupling color temperature to Level Control
+ //
+ // If the Level Control for Lighting cluster identifier 0x0008 is supported
+ // on the same endpoint as the Color Control cluster and color temperature is
+ // supported, it is possible to couple changes in the current level to the
+ // color temperature.
+ //
+ // The CoupleColorTempToLevel bit of the Options attribute of the Level
+ // Control cluster indicates whether the color temperature is to be linked
+ // with the CurrentLevel attribute in the Level Control cluster.
+ //
+ // If the CoupleColorTempToLevel bit of the Options attribute of the Level
+ // Control cluster is equal to 1 and the ColorMode or EnhancedColorMode
+ // attribute is set to 0x02 (color temperature) then a change in the
+ // CurrentLevel attribute SHALL affect the ColorTemperatureMireds attribute.
+ // This relationship is manufacturer specific, with the qualification that
+ // the maximum value of the CurrentLevel attribute SHALL correspond to a
+ // ColorTemperatureMired attribute value equal to the
+ // CoupleColorTempToLevelMinMireds attribute. This relationship is one-way so
+ // a change to the ColorTemperatureMireds attribute SHALL NOT have any effect
+ // on the CurrentLevel attribute.
+ //
+ // In order to simulate the behavior of an incandescent bulb, a low value of
+ // the CurrentLevel attribute SHALL be associated with a high value of the
+ // ColorTemperatureMireds attribute (i.e., a low value of color temperature
+ // in kelvins).
+ //
+ // If the CoupleColorTempToLevel bit of the Options attribute of the Level
+ // Control cluster is equal to 0, there SHALL be no link between color
+ // temperature and current level.
- if (!emberAfContainsServer(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID)) {
- return;
- }
-
- if (readColorMode(endpoint) == COLOR_MODE_TEMPERATURE) {
- uint16_t tempCoupleMin = readColorTemperatureCoupleToLevelMin(endpoint);
- uint16_t tempPhysMax = readColorTemperatureMax(endpoint);
- uint8_t currentLevel = readLevelControlCurrentLevel(endpoint);
-
- // Scale color temp setting between the coupling min and the physical max.
- // Note that mireds varies inversely with level: low level -> high mireds.
- // Peg min/MAX level to MAX/min mireds, otherwise interpolate.
- uint16_t newColorTemp;
- if (currentLevel <= MIN_CURRENT_LEVEL) {
- newColorTemp = tempPhysMax;
- } else if (currentLevel >= MAX_CURRENT_LEVEL) {
- newColorTemp = tempCoupleMin;
- } else {
- uint32_t tempDelta = (((uint32_t)tempPhysMax - (uint32_t)tempCoupleMin)
- * currentLevel)
- / (uint32_t)(MAX_CURRENT_LEVEL - MIN_CURRENT_LEVEL + 1);
- newColorTemp = (uint16_t)((uint32_t)tempPhysMax - tempDelta);
+ if (!emberAfContainsServer(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID))
+ {
+ return;
}
- // Apply new color temp.
- moveToColorTemp(endpoint, newColorTemp, 0);
- }
+ if (readColorMode(endpoint) == COLOR_MODE_TEMPERATURE)
+ {
+ uint16_t tempCoupleMin = readColorTemperatureCoupleToLevelMin(endpoint);
+ uint16_t tempPhysMax = readColorTemperatureMax(endpoint);
+ uint8_t currentLevel = readLevelControlCurrentLevel(endpoint);
+
+ // Scale color temp setting between the coupling min and the physical max.
+ // Note that mireds varies inversely with level: low level -> high mireds.
+ // Peg min/MAX level to MAX/min mireds, otherwise interpolate.
+ uint16_t newColorTemp;
+ if (currentLevel <= MIN_CURRENT_LEVEL)
+ {
+ newColorTemp = tempPhysMax;
+ }
+ else if (currentLevel >= MAX_CURRENT_LEVEL)
+ {
+ newColorTemp = tempCoupleMin;
+ }
+ else
+ {
+ uint32_t tempDelta = (((uint32_t) tempPhysMax - (uint32_t) tempCoupleMin) * currentLevel) /
+ (uint32_t)(MAX_CURRENT_LEVEL - MIN_CURRENT_LEVEL + 1);
+ newColorTemp = (uint16_t)((uint32_t) tempPhysMax - tempDelta);
+ }
+
+ // Apply new color temp.
+ moveToColorTemp(endpoint, newColorTemp, 0);
+ }
}
#endif //#ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_TEMP
-bool emberAfColorControlClusterStopMoveStepCallback(uint8_t optionsMask,
- uint8_t optionsOverride)
+bool emberAfColorControlClusterStopMoveStepCallback(uint8_t optionsMask, uint8_t optionsOverride)
{
- // Received a stop command. This is all we need to do.
- uint8_t endpoint = emberAfCurrentEndpoint();
+ // Received a stop command. This is all we need to do.
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (shouldExecuteIfOff(endpoint, optionsMask, optionsOverride)) {
- stopAllColorTransitions();
- }
+ if (shouldExecuteIfOff(endpoint, optionsMask, optionsOverride))
+ {
+ stopAllColorTransitions();
+ }
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
// **************** transition state machines ***********
static void stopAllColorTransitions(void)
{
- emberEventControlSetInactive(COLOR_TEMP_CONTROL);
- emberEventControlSetInactive(COLOR_XY_CONTROL);
- emberEventControlSetInactive(COLOR_HSV_CONTROL);
+ emberEventControlSetInactive(COLOR_TEMP_CONTROL);
+ emberEventControlSetInactive(COLOR_XY_CONTROL);
+ emberEventControlSetInactive(COLOR_HSV_CONTROL);
}
void emberAfPluginColorControlServerStopTransition(void)
{
- stopAllColorTransitions();
+ stopAllColorTransitions();
}
// The specification says that if we are transitioning from one color mode
@@ -1388,424 +1378,433 @@
// the new mode, this must be avoided.
// I am putting in this function to compute the new attributes based on the old
// color mode.
-static void handleModeSwitch(uint8_t endpoint,
- uint8_t newColorMode)
+static void handleModeSwitch(uint8_t endpoint, uint8_t newColorMode)
{
- uint8_t oldColorMode = readColorMode(endpoint);
- uint8_t colorModeTransition;
+ uint8_t oldColorMode = readColorMode(endpoint);
+ uint8_t colorModeTransition;
- if (oldColorMode == newColorMode) {
- return;
- } else {
- writeColorMode(endpoint, newColorMode);
- }
+ if (oldColorMode == newColorMode)
+ {
+ return;
+ }
+ else
+ {
+ writeColorMode(endpoint, newColorMode);
+ }
- colorModeTransition = (newColorMode << 4) + oldColorMode;
+ colorModeTransition = (newColorMode << 4) + oldColorMode;
- // Note: It may be OK to not do anything here.
- switch (colorModeTransition) {
+ // Note: It may be OK to not do anything here.
+ switch (colorModeTransition)
+ {
case HSV_TO_CIE_XY:
- emberAfPluginColorControlServerComputePwmFromXyCallback(endpoint);
- break;
+ emberAfPluginColorControlServerComputePwmFromXyCallback(endpoint);
+ break;
case TEMPERATURE_TO_CIE_XY:
- emberAfPluginColorControlServerComputePwmFromXyCallback(endpoint);
- break;
+ emberAfPluginColorControlServerComputePwmFromXyCallback(endpoint);
+ break;
case CIE_XY_TO_HSV:
- emberAfPluginColorControlServerComputePwmFromHsvCallback(endpoint);
- break;
+ emberAfPluginColorControlServerComputePwmFromHsvCallback(endpoint);
+ break;
case TEMPERATURE_TO_HSV:
- emberAfPluginColorControlServerComputePwmFromHsvCallback(endpoint);
- break;
+ emberAfPluginColorControlServerComputePwmFromHsvCallback(endpoint);
+ break;
case HSV_TO_TEMPERATURE:
- emberAfPluginColorControlServerComputePwmFromTempCallback(endpoint);
- break;
+ emberAfPluginColorControlServerComputePwmFromTempCallback(endpoint);
+ break;
case CIE_XY_TO_TEMPERATURE:
- emberAfPluginColorControlServerComputePwmFromTempCallback(endpoint);
- break;
+ emberAfPluginColorControlServerComputePwmFromTempCallback(endpoint);
+ break;
// for the following cases, there is no transition.
case HSV_TO_HSV:
case CIE_XY_TO_CIE_XY:
case TEMPERATURE_TO_TEMPERATURE:
default:
- return;
- }
+ return;
+ }
}
static uint8_t addHue(uint8_t hue1, uint8_t hue2)
{
- uint16_t hue16;
+ uint16_t hue16;
- hue16 = ((uint16_t) hue1);
- hue16 += ((uint16_t) hue2);
+ hue16 = ((uint16_t) hue1);
+ hue16 += ((uint16_t) hue2);
- if (hue16 > MAX_HUE_VALUE) {
- hue16 -= MAX_HUE_VALUE;
- }
+ if (hue16 > MAX_HUE_VALUE)
+ {
+ hue16 -= MAX_HUE_VALUE;
+ }
- return ((uint8_t) hue16);
+ return ((uint8_t) hue16);
}
static uint8_t subtractHue(uint8_t hue1, uint8_t hue2)
{
- uint16_t hue16;
+ uint16_t hue16;
- hue16 = ((uint16_t) hue1);
- if (hue2 > hue1) {
- hue16 += MAX_HUE_VALUE;
- }
+ hue16 = ((uint16_t) hue1);
+ if (hue2 > hue1)
+ {
+ hue16 += MAX_HUE_VALUE;
+ }
- hue16 -= ((uint16_t) hue2);
+ hue16 -= ((uint16_t) hue2);
- return ((uint8_t) hue16);
+ return ((uint8_t) hue16);
}
-static bool computeNewHueValue(ColorHueTransitionState *p)
+static bool computeNewHueValue(ColorHueTransitionState * p)
{
- uint32_t newHue32;
- uint8_t newHue;
+ uint32_t newHue32;
+ uint8_t newHue;
- // exit with a false if hue is not currently moving
- if (p->stepsRemaining == 0) {
- return false;
- }
-
- (p->stepsRemaining)--;
-
- if (p->repeat == false) {
- writeRemainingTime(p->endpoint, p->stepsRemaining);
- }
-
- // are we going up or down?
- if (p->finalHue == p->currentHue) {
- // do nothing
- } else if (p->up) {
- newHue32 = (uint32_t) subtractHue(p->finalHue, p->initialHue);
- newHue32 *= ((uint32_t) (p->stepsRemaining));
- newHue32 /= ((uint32_t) (p->stepsTotal));
- p->currentHue = subtractHue((uint8_t) p->finalHue,
- (uint8_t) newHue32);
- } else {
- newHue32 = (uint32_t) subtractHue(p->initialHue, p->finalHue);
- newHue32 *= ((uint32_t) (p->stepsRemaining));
- newHue32 /= ((uint32_t) (p->stepsTotal));
-
- p->currentHue = addHue((uint8_t) p->finalHue,
- (uint8_t) newHue32);
- }
-
- if (p->stepsRemaining == 0) {
- if (p->repeat == false) {
- // we are performing a move to and not a move.
- return true;
- } else {
- // we are performing a Hue move. Need to compute the new values for the
- // next move period.
- if (p->up) {
- newHue = subtractHue(p->finalHue, p->initialHue);
- newHue = addHue(p->finalHue, newHue);
-
- p->initialHue = p->finalHue;
- p->finalHue = newHue;
- } else {
- newHue = subtractHue(p->initialHue, p->finalHue);
- newHue = subtractHue(p->finalHue, newHue);
-
- p->initialHue = p->finalHue;
- p->finalHue = newHue;
- }
- p->stepsRemaining = TRANSITION_TIME_1S;
+ // exit with a false if hue is not currently moving
+ if (p->stepsRemaining == 0)
+ {
+ return false;
}
- }
- return false;
+
+ (p->stepsRemaining)--;
+
+ if (p->repeat == false)
+ {
+ writeRemainingTime(p->endpoint, p->stepsRemaining);
+ }
+
+ // are we going up or down?
+ if (p->finalHue == p->currentHue)
+ {
+ // do nothing
+ }
+ else if (p->up)
+ {
+ newHue32 = (uint32_t) subtractHue(p->finalHue, p->initialHue);
+ newHue32 *= ((uint32_t)(p->stepsRemaining));
+ newHue32 /= ((uint32_t)(p->stepsTotal));
+ p->currentHue = subtractHue((uint8_t) p->finalHue, (uint8_t) newHue32);
+ }
+ else
+ {
+ newHue32 = (uint32_t) subtractHue(p->initialHue, p->finalHue);
+ newHue32 *= ((uint32_t)(p->stepsRemaining));
+ newHue32 /= ((uint32_t)(p->stepsTotal));
+
+ p->currentHue = addHue((uint8_t) p->finalHue, (uint8_t) newHue32);
+ }
+
+ if (p->stepsRemaining == 0)
+ {
+ if (p->repeat == false)
+ {
+ // we are performing a move to and not a move.
+ return true;
+ }
+ else
+ {
+ // we are performing a Hue move. Need to compute the new values for the
+ // next move period.
+ if (p->up)
+ {
+ newHue = subtractHue(p->finalHue, p->initialHue);
+ newHue = addHue(p->finalHue, newHue);
+
+ p->initialHue = p->finalHue;
+ p->finalHue = newHue;
+ }
+ else
+ {
+ newHue = subtractHue(p->initialHue, p->finalHue);
+ newHue = subtractHue(p->finalHue, newHue);
+
+ p->initialHue = p->finalHue;
+ p->finalHue = newHue;
+ }
+ p->stepsRemaining = TRANSITION_TIME_1S;
+ }
+ }
+ return false;
}
void emberAfPluginColorControlServerHueSatTransitionEventHandler(void)
{
- uint8_t endpoint = colorHueTransitionState.endpoint;
- boolean limitReached1, limitReached2;
+ uint8_t endpoint = colorHueTransitionState.endpoint;
+ boolean limitReached1, limitReached2;
- limitReached1 = computeNewHueValue(&colorHueTransitionState);
- limitReached2 = computeNewColor16uValue(&colorSaturationTransitionState);
+ limitReached1 = computeNewHueValue(&colorHueTransitionState);
+ limitReached2 = computeNewColor16uValue(&colorSaturationTransitionState);
- if (limitReached1 || limitReached2) {
- stopAllColorTransitions();
- } else {
- emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
- }
+ if (limitReached1 || limitReached2)
+ {
+ stopAllColorTransitions();
+ }
+ else
+ {
+ emberEventControlSetDelayMS(COLOR_HSV_CONTROL, UPDATE_TIME_MS);
+ }
- writeHue(colorHueTransitionState.endpoint,
- colorHueTransitionState.currentHue);
- writeSaturation(colorSaturationTransitionState.endpoint,
- (uint8_t) colorSaturationTransitionState.currentValue);
+ writeHue(colorHueTransitionState.endpoint, colorHueTransitionState.currentHue);
+ writeSaturation(colorSaturationTransitionState.endpoint, (uint8_t) colorSaturationTransitionState.currentValue);
- emberAfColorControlClusterPrintln("Hue %d Saturation %d endpoint %d",
- colorHueTransitionState.currentHue,
- colorSaturationTransitionState.currentValue,
- endpoint);
+ emberAfColorControlClusterPrintln("Hue %d Saturation %d endpoint %d", colorHueTransitionState.currentHue,
+ colorSaturationTransitionState.currentValue, endpoint);
- emberAfPluginColorControlServerComputePwmFromHsvCallback(endpoint);
+ emberAfPluginColorControlServerComputePwmFromHsvCallback(endpoint);
}
// Return value of true means we need to stop.
-static bool computeNewColor16uValue(Color16uTransitionState *p)
+static bool computeNewColor16uValue(Color16uTransitionState * p)
{
- uint32_t newValue32u;
+ uint32_t newValue32u;
- if (p->stepsRemaining == 0) {
+ if (p->stepsRemaining == 0)
+ {
+ return false;
+ }
+
+ (p->stepsRemaining)--;
+
+ writeRemainingTime(p->endpoint, p->stepsRemaining);
+
+ // handle sign
+ if (p->finalValue == p->currentValue)
+ {
+ // do nothing
+ }
+ else if (p->finalValue > p->initialValue)
+ {
+ newValue32u = ((uint32_t)(p->finalValue - p->initialValue));
+ newValue32u *= ((uint32_t)(p->stepsRemaining));
+ newValue32u /= ((uint32_t)(p->stepsTotal));
+ p->currentValue = p->finalValue - ((uint16_t)(newValue32u));
+ }
+ else
+ {
+ newValue32u = ((uint32_t)(p->initialValue - p->finalValue));
+ newValue32u *= ((uint32_t)(p->stepsRemaining));
+ newValue32u /= ((uint32_t)(p->stepsTotal));
+ p->currentValue = p->finalValue + ((uint16_t)(newValue32u));
+ }
+
+ if (p->stepsRemaining == 0)
+ {
+ // we have completed our move.
+ return true;
+ }
+
return false;
- }
-
- (p->stepsRemaining)--;
-
- writeRemainingTime(p->endpoint, p->stepsRemaining);
-
- // handle sign
- if (p->finalValue == p->currentValue) {
- // do nothing
- } else if (p->finalValue > p->initialValue) {
- newValue32u = ((uint32_t) (p->finalValue - p->initialValue));
- newValue32u *= ((uint32_t) (p->stepsRemaining));
- newValue32u /= ((uint32_t) (p->stepsTotal));
- p->currentValue = p->finalValue - ((uint16_t) (newValue32u));
- } else {
- newValue32u = ((uint32_t) (p->initialValue - p->finalValue));
- newValue32u *= ((uint32_t) (p->stepsRemaining));
- newValue32u /= ((uint32_t) (p->stepsTotal));
- p->currentValue = p->finalValue + ((uint16_t) (newValue32u));
- }
-
- if (p->stepsRemaining == 0) {
- // we have completed our move.
- return true;
- }
-
- return false;
}
-static uint16_t computeTransitionTimeFromStateAndRate(Color16uTransitionState *p,
- uint16_t rate)
+static uint16_t computeTransitionTimeFromStateAndRate(Color16uTransitionState * p, uint16_t rate)
{
- uint32_t transitionTime;
- uint16_t max, min;
+ uint32_t transitionTime;
+ uint16_t max, min;
- if (rate == 0) {
- return MAX_INT16U_VALUE;
- }
+ if (rate == 0)
+ {
+ return MAX_INT16U_VALUE;
+ }
- if (p->currentValue > p->finalValue) {
- max = p->currentValue;
- min = p->finalValue;
- } else {
- max = p->finalValue;
- min = p->currentValue;
- }
+ if (p->currentValue > p->finalValue)
+ {
+ max = p->currentValue;
+ min = p->finalValue;
+ }
+ else
+ {
+ max = p->finalValue;
+ min = p->currentValue;
+ }
- transitionTime = max - min;
- transitionTime *= 10;
- transitionTime /= rate;
+ transitionTime = max - min;
+ transitionTime *= 10;
+ transitionTime /= rate;
- if (transitionTime > MAX_INT16U_VALUE) {
- return MAX_INT16U_VALUE;
- }
+ if (transitionTime > MAX_INT16U_VALUE)
+ {
+ return MAX_INT16U_VALUE;
+ }
- return (uint16_t) transitionTime;
+ return (uint16_t) transitionTime;
}
void emberAfPluginColorControlServerXyTransitionEventHandler(void)
{
- uint8_t endpoint = colorXTransitionState.endpoint;
- boolean limitReachedX, limitReachedY;
+ uint8_t endpoint = colorXTransitionState.endpoint;
+ boolean limitReachedX, limitReachedY;
- // compute new values for X and Y.
- limitReachedX = computeNewColor16uValue(&colorXTransitionState);
+ // compute new values for X and Y.
+ limitReachedX = computeNewColor16uValue(&colorXTransitionState);
- limitReachedY = computeNewColor16uValue(&colorYTransitionState);
+ limitReachedY = computeNewColor16uValue(&colorYTransitionState);
- if (limitReachedX || limitReachedY) {
- stopAllColorTransitions();
- } else {
- emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
- }
+ if (limitReachedX || limitReachedY)
+ {
+ stopAllColorTransitions();
+ }
+ else
+ {
+ emberEventControlSetDelayMS(COLOR_XY_CONTROL, UPDATE_TIME_MS);
+ }
- // update the attributes
- writeColorX(colorXTransitionState.endpoint,
- colorXTransitionState.currentValue);
- writeColorY(colorXTransitionState.endpoint,
- colorYTransitionState.currentValue);
+ // update the attributes
+ writeColorX(colorXTransitionState.endpoint, colorXTransitionState.currentValue);
+ writeColorY(colorXTransitionState.endpoint, colorYTransitionState.currentValue);
- emberAfColorControlClusterPrintln("Color X %d Color Y %d",
- colorXTransitionState.currentValue,
- colorYTransitionState.currentValue);
+ emberAfColorControlClusterPrintln("Color X %d Color Y %d", colorXTransitionState.currentValue,
+ colorYTransitionState.currentValue);
- emberAfPluginColorControlServerComputePwmFromXyCallback(endpoint);
+ emberAfPluginColorControlServerComputePwmFromXyCallback(endpoint);
}
void emberAfPluginColorControlServerTempTransitionEventHandler(void)
{
- uint8_t endpoint = colorTempTransitionState.endpoint;
- boolean limitReached;
+ uint8_t endpoint = colorTempTransitionState.endpoint;
+ boolean limitReached;
- limitReached = computeNewColor16uValue(&colorTempTransitionState);
+ limitReached = computeNewColor16uValue(&colorTempTransitionState);
- if (limitReached) {
- stopAllColorTransitions();
- } else {
- emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
- }
+ if (limitReached)
+ {
+ stopAllColorTransitions();
+ }
+ else
+ {
+ emberEventControlSetDelayMS(COLOR_TEMP_CONTROL, UPDATE_TIME_MS);
+ }
- writeColorTemperature(colorTempTransitionState.endpoint,
- colorTempTransitionState.currentValue);
+ writeColorTemperature(colorTempTransitionState.endpoint, colorTempTransitionState.currentValue);
- emberAfColorControlClusterPrintln("Color Temperature %d",
- colorTempTransitionState.currentValue);
+ emberAfColorControlClusterPrintln("Color Temperature %d", colorTempTransitionState.currentValue);
- emberAfPluginColorControlServerComputePwmFromTempCallback(endpoint);
+ emberAfPluginColorControlServerComputePwmFromTempCallback(endpoint);
}
-static bool shouldExecuteIfOff(uint8_t endpoint,
- uint8_t optionMask,
- uint8_t optionOverride)
+static bool shouldExecuteIfOff(uint8_t endpoint, uint8_t optionMask, uint8_t optionOverride)
{
- // From 5.2.2.2.1.10 of ZCL7 document 14-0129-15f-zcl-ch-5-lighting.docx:
- // "Command execution SHALL NOT continue beyond the Options processing if
- // all of these criteria are true:
- // - The On/Off cluster exists on the same endpoint as this cluster.
- // - The OnOff attribute of the On/Off cluster, on this endpoint, is 0x00
- // (FALSE).
- // - The value of the ExecuteIfOff bit is 0."
+ // From 5.2.2.2.1.10 of ZCL7 document 14-0129-15f-zcl-ch-5-lighting.docx:
+ // "Command execution SHALL NOT continue beyond the Options processing if
+ // all of these criteria are true:
+ // - The On/Off cluster exists on the same endpoint as this cluster.
+ // - The OnOff attribute of the On/Off cluster, on this endpoint, is 0x00
+ // (FALSE).
+ // - The value of the ExecuteIfOff bit is 0."
- if (!emberAfContainsServer(endpoint, ZCL_ON_OFF_CLUSTER_ID)) {
- return true;
- }
+ if (!emberAfContainsServer(endpoint, ZCL_ON_OFF_CLUSTER_ID))
+ {
+ return true;
+ }
- uint8_t options;
- EmberAfStatus status = emberAfReadServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_OPTIONS_ATTRIBUTE_ID,
- &options,
- sizeof(options));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfColorControlClusterPrintln("Unable to read Options attribute: 0x%X",
- status);
- // If we can't read the attribute, then we should just assume that it has
- // its default value.
- options = 0x00;
- }
+ uint8_t options;
+ EmberAfStatus status =
+ emberAfReadServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_OPTIONS_ATTRIBUTE_ID, &options, sizeof(options));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfColorControlClusterPrintln("Unable to read Options attribute: 0x%X", status);
+ // If we can't read the attribute, then we should just assume that it has
+ // its default value.
+ options = 0x00;
+ }
- bool on;
- status = emberAfReadServerAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- (uint8_t *)&on,
- sizeof(on));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfColorControlClusterPrintln("Unable to read OnOff attribute: 0x%X",
- status);
- return true;
- }
- // The device is on - hence ExecuteIfOff does not matter
- if (on) {
- return true;
- }
- // The OptionsMask & OptionsOverride fields SHALL both be present or both
- // omitted in the command. A temporary Options bitmap SHALL be created from
- // the Options attribute, using the OptionsMask & OptionsOverride fields, if
- // present. Each bit of the temporary Options bitmap SHALL be determined as
- // follows:
- // Each bit in the Options attribute SHALL determine the corresponding bit in
- // the temporary Options bitmap, unless the OptionsMask field is present and
- // has the corresponding bit set to 1, in which case the corresponding bit in
- // the OptionsOverride field SHALL determine the corresponding bit in the
- // temporary Options bitmap.
- //The resulting temporary Options bitmap SHALL then be processed as defined
- // in section 5.2.2.2.1.10.
+ bool on;
+ status = emberAfReadServerAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, (uint8_t *) &on, sizeof(on));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfColorControlClusterPrintln("Unable to read OnOff attribute: 0x%X", status);
+ return true;
+ }
+ // The device is on - hence ExecuteIfOff does not matter
+ if (on)
+ {
+ return true;
+ }
+ // The OptionsMask & OptionsOverride fields SHALL both be present or both
+ // omitted in the command. A temporary Options bitmap SHALL be created from
+ // the Options attribute, using the OptionsMask & OptionsOverride fields, if
+ // present. Each bit of the temporary Options bitmap SHALL be determined as
+ // follows:
+ // Each bit in the Options attribute SHALL determine the corresponding bit in
+ // the temporary Options bitmap, unless the OptionsMask field is present and
+ // has the corresponding bit set to 1, in which case the corresponding bit in
+ // the OptionsOverride field SHALL determine the corresponding bit in the
+ // temporary Options bitmap.
+ // The resulting temporary Options bitmap SHALL then be processed as defined
+ // in section 5.2.2.2.1.10.
- // ---------- The following order is important in decision making -------
- // -----------more readable ----------
- //
- if (optionMask == 0xFF && optionOverride == 0xFF) {
- // 0xFF are the default values passed to the command handler when
- // the payload is not present - in that case there is use of option
- // attribute to decide execution of the command
- return READBITS(options, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF);
- }
- // ---------- The above is to distinguish if the payload is present or not
+ // ---------- The following order is important in decision making -------
+ // -----------more readable ----------
+ //
+ if (optionMask == 0xFF && optionOverride == 0xFF)
+ {
+ // 0xFF are the default values passed to the command handler when
+ // the payload is not present - in that case there is use of option
+ // attribute to decide execution of the command
+ return READBITS(options, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF);
+ }
+ // ---------- The above is to distinguish if the payload is present or not
- if (READBITS(optionMask, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF)) {
- // Mask is present and set in the command payload, this indicates
- // use the override as temporary option
- return READBITS(optionOverride, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF);
- }
- // if we are here - use the option attribute bits
- return (READBITS(options, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF));
+ if (READBITS(optionMask, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF))
+ {
+ // Mask is present and set in the command payload, this indicates
+ // use the override as temporary option
+ return READBITS(optionOverride, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF);
+ }
+ // if we are here - use the option attribute bits
+ return (READBITS(options, EMBER_ZCL_COLOR_CONTROL_OPTIONS_EXECUTE_IF_OFF));
}
void emberAfColorControlClusterServerInitCallback(uint8_t endpoint)
{
#ifdef EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_TEMP
- // 07-5123-07 (i.e. ZCL 7) 5.2.2.2.1.22 StartUpColorTemperatureMireds Attribute
- // The StartUpColorTemperatureMireds attribute SHALL define the desired startup color
- // temperature values a lamp SHAL use when it is supplied with power and this value SHALL
- // be reflected in the ColorTemperatureMireds attribute. In addition, the ColorMode and
- // EnhancedColorMode attributes SHALL be set to 0x02 (color temperature). The values of
- // the StartUpColorTemperatureMireds attribute are listed in the table below.
- // Value Action on power up
- // 0x0000-0xffef Set the ColorTemperatureMireds attribute to this value.
- // 0xffff Set the ColorTemperatureMireds attribue to its previous value.
+ // 07-5123-07 (i.e. ZCL 7) 5.2.2.2.1.22 StartUpColorTemperatureMireds Attribute
+ // The StartUpColorTemperatureMireds attribute SHALL define the desired startup color
+ // temperature values a lamp SHAL use when it is supplied with power and this value SHALL
+ // be reflected in the ColorTemperatureMireds attribute. In addition, the ColorMode and
+ // EnhancedColorMode attributes SHALL be set to 0x02 (color temperature). The values of
+ // the StartUpColorTemperatureMireds attribute are listed in the table below.
+ // Value Action on power up
+ // 0x0000-0xffef Set the ColorTemperatureMireds attribute to this value.
+ // 0xffff Set the ColorTemperatureMireds attribue to its previous value.
- // Initialize startUpColorTempMireds to "maintain previous value" value 0xFFFF
- uint16_t startUpColorTemp = 0xFFFF;
- EmberAfStatus status = emberAfReadAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_START_UP_COLOR_TEMPERATURE_MIREDS_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&startUpColorTemp,
- sizeof(startUpColorTemp),
- NULL);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- uint16_t updatedColorTemp = MAX_TEMPERATURE_VALUE;
- status = emberAfReadAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&updatedColorTemp,
- sizeof(updatedColorTemp),
- NULL);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- uint16_t tempPhysicalMin = readColorTemperatureMin(endpoint);
- uint16_t tempPhysicalMax = readColorTemperatureMax(endpoint);
- if (tempPhysicalMin <= startUpColorTemp && startUpColorTemp <= tempPhysicalMax) {
- // Apply valid startup color temp value that is within physical limits of device.
- // Otherwise, the startup value is outside the device's supported range, and the
- // existing setting of ColorTemp attribute will be left unchanged (i.e., treated as
- // if startup color temp was set to 0xFFFF).
- updatedColorTemp = startUpColorTemp;
- status = emberAfWriteAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&updatedColorTemp,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- // Set ColorMode attributes to reflect ColorTemperature.
- uint8_t updateColorMode = EMBER_ZCL_COLOR_MODE_COLOR_TEMPERATURE;
- status = emberAfWriteAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- &updateColorMode,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
- updateColorMode = EMBER_ZCL_ENHANCED_COLOR_MODE_COLOR_TEMPERATURE;
- status = emberAfWriteAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_ENHANCED_COLOR_MODE_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- &updateColorMode,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
+ // Initialize startUpColorTempMireds to "maintain previous value" value 0xFFFF
+ uint16_t startUpColorTemp = 0xFFFF;
+ EmberAfStatus status =
+ emberAfReadAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_START_UP_COLOR_TEMPERATURE_MIREDS_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) &startUpColorTemp, sizeof(startUpColorTemp), NULL);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ uint16_t updatedColorTemp = MAX_TEMPERATURE_VALUE;
+ status = emberAfReadAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) &updatedColorTemp, sizeof(updatedColorTemp), NULL);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ uint16_t tempPhysicalMin = readColorTemperatureMin(endpoint);
+ uint16_t tempPhysicalMax = readColorTemperatureMax(endpoint);
+ if (tempPhysicalMin <= startUpColorTemp && startUpColorTemp <= tempPhysicalMax)
+ {
+ // Apply valid startup color temp value that is within physical limits of device.
+ // Otherwise, the startup value is outside the device's supported range, and the
+ // existing setting of ColorTemp attribute will be left unchanged (i.e., treated as
+ // if startup color temp was set to 0xFFFF).
+ updatedColorTemp = startUpColorTemp;
+ status =
+ emberAfWriteAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) &updatedColorTemp, ZCL_INT16U_ATTRIBUTE_TYPE);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ // Set ColorMode attributes to reflect ColorTemperature.
+ uint8_t updateColorMode = EMBER_ZCL_COLOR_MODE_COLOR_TEMPERATURE;
+ status =
+ emberAfWriteAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_MODE_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, &updateColorMode, ZCL_ENUM8_ATTRIBUTE_TYPE);
+ updateColorMode = EMBER_ZCL_ENHANCED_COLOR_MODE_COLOR_TEMPERATURE;
+ status = emberAfWriteAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID,
+ ZCL_COLOR_CONTROL_ENHANCED_COLOR_MODE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ &updateColorMode, ZCL_ENUM8_ATTRIBUTE_TYPE);
+ }
+ }
}
- }
}
- }
#endif
}
diff --git a/src/app/clusters/door-lock-server/door-lock-server-cli.c b/src/app/clusters/door-lock-server/door-lock-server-cli.c
index 0b34d34..c0c5626 100644
--- a/src/app/clusters/door-lock-server/door-lock-server-cli.c
+++ b/src/app/clusters/door-lock-server/door-lock-server-cli.c
@@ -31,83 +31,81 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the Door Lock Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#include "door-lock-server.h"
#define ISO_639_1_STRING_LENGTH 3
-static const char *getLockStateName(EmberAfDoorLockState state)
+static const char * getLockStateName(EmberAfDoorLockState state)
{
- const char *stateNames[] = {
- "Not Fully Locked",
- "Locked",
- "Unlocked",
- };
- return (state < COUNTOF(stateNames) ? stateNames[state] : "?????");
+ const char * stateNames[] = {
+ "Not Fully Locked",
+ "Locked",
+ "Unlocked",
+ };
+ return (state < COUNTOF(stateNames) ? stateNames[state] : "?????");
}
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SOUND_VOLUME_ATTRIBUTE
-static const char *getSoundVolumeName(uint8_t volume)
+static const char * getSoundVolumeName(uint8_t volume)
{
- const char *soundVolumeNames[] = {
- "Silent",
- "Low",
- "High",
- };
- return (volume < COUNTOF(soundVolumeNames)
- ? soundVolumeNames[volume]
- : "?????");
+ const char * soundVolumeNames[] = {
+ "Silent",
+ "Low",
+ "High",
+ };
+ return (volume < COUNTOF(soundVolumeNames) ? soundVolumeNames[volume] : "?????");
}
#endif
// plugin door-lock-server status
void emAfPluginDoorLockServerStatusCommand(void)
{
- uint8_t state;
- EmberAfStatus status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- (uint8_t *)&state,
- sizeof(state));
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfAppPrintln("State: %s", getLockStateName(state));
- } else {
- emberAfAppPrintln("Error: cannot read attribute: 0x%X", status);
- }
+ uint8_t state;
+ EmberAfStatus status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_LOCK_STATE_ATTRIBUTE_ID, (uint8_t *) &state, sizeof(state));
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfAppPrintln("State: %s", getLockStateName(state));
+ }
+ else
+ {
+ emberAfAppPrintln("Error: cannot read attribute: 0x%X", status);
+ }
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_LANGUAGE_ATTRIBUTE
- uint8_t string[ISO_639_1_STRING_LENGTH + 1]; // + 1 for nul-terminator
- status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LANGUAGE_ATTRIBUTE_ID,
- string,
- sizeof(string));
- string[sizeof(string) - 1] = '\0';
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfAppPrintln("Language: %s", &string[1]); // skip the length byte
- } else {
- emberAfAppPrintln("Error: cannot read attribute: 0x%X", status);
- }
+ uint8_t string[ISO_639_1_STRING_LENGTH + 1]; // + 1 for nul-terminator
+ status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_LANGUAGE_ATTRIBUTE_ID, string,
+ sizeof(string));
+ string[sizeof(string) - 1] = '\0';
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfAppPrintln("Language: %s", &string[1]); // skip the length byte
+ }
+ else
+ {
+ emberAfAppPrintln("Error: cannot read attribute: 0x%X", status);
+ }
#endif
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SOUND_VOLUME_ATTRIBUTE
- uint8_t volume;
- status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_SOUND_VOLUME_ATTRIBUTE_ID,
- &volume,
- sizeof(volume));
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfAppPrintln("Volume: %s", getSoundVolumeName(volume));
- } else {
- emberAfAppPrintln("Error: cannot read attribute: 0x%X", status);
- }
+ uint8_t volume;
+ status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_SOUND_VOLUME_ATTRIBUTE_ID, &volume,
+ sizeof(volume));
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfAppPrintln("Volume: %s", getSoundVolumeName(volume));
+ }
+ else
+ {
+ emberAfAppPrintln("Error: cannot read attribute: 0x%X", status);
+ }
#endif
}
@@ -115,76 +113,67 @@
// plugin door-lock-server unlock <userId:2>
void emAfPluginDoorLockServerLockOrUnlockCommand(void)
{
- bool doLock = (emberStringCommandArgument(-1, NULL)[0] == 'l');
- uint16_t userId = (uint16_t)emberUnsignedCommandArgument(0);
- uint8_t state = (doLock
- ? EMBER_ZCL_DOOR_LOCK_STATE_LOCKED
- : EMBER_ZCL_DOOR_LOCK_STATE_UNLOCKED);
- EmberAfStatus status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- (uint8_t *)&state,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
+ bool doLock = (emberStringCommandArgument(-1, NULL)[0] == 'l');
+ uint16_t userId = (uint16_t) emberUnsignedCommandArgument(0);
+ uint8_t state = (doLock ? EMBER_ZCL_DOOR_LOCK_STATE_LOCKED : EMBER_ZCL_DOOR_LOCK_STATE_UNLOCKED);
+ EmberAfStatus status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_LOCK_STATE_ATTRIBUTE_ID, (uint8_t *) &state, ZCL_ENUM8_ATTRIBUTE_TYPE);
- const char *action = (doLock ? "lock" : "unlock");
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfAppPrintln("Failed to %s door: 0x%X", action, status);
- } else {
- emberAfAppPrintln("Door is now %sed", action);
-
- if (!emberAfPluginDoorLockServerAddLogEntry(EMBER_ZCL_DOOR_LOCK_EVENT_TYPE_OPERATION,
- EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_MANUAL,
- (doLock
- ? EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_LOCK
- : EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_UNLOCK),
- userId,
- 0,
- NULL)) { // pin...nah
- emberAfAppPrintln("Could not add log entry");
+ const char * action = (doLock ? "lock" : "unlock");
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfAppPrintln("Failed to %s door: 0x%X", action, status);
}
- }
+ else
+ {
+ emberAfAppPrintln("Door is now %sed", action);
+
+ if (!emberAfPluginDoorLockServerAddLogEntry(
+ EMBER_ZCL_DOOR_LOCK_EVENT_TYPE_OPERATION, EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_MANUAL,
+ (doLock ? EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_LOCK : EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_UNLOCK), userId,
+ 0, NULL))
+ { // pin...nah
+ emberAfAppPrintln("Could not add log entry");
+ }
+ }
}
// plugin door-lock-server open
// plugin door-lock-server close
void emAfPluginDoorLockServerOpenOrCloseCommand(void)
{
- static uint8_t eventCount = 0;
- uint8_t PIN[] = "";
- bool doOpen = (emberStringCommandArgument(-1, NULL)[0] == 'o');
- EmberAfDoorState state = (doOpen
- ? EMBER_ZCL_DOOR_STATE_OPEN
- : EMBER_ZCL_DOOR_STATE_CLOSED);
- EmberAfStatus status = emAfPluginDoorLockServerNoteDoorStateChanged(state);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfAppPrintln("Failed to %s door: 0x%X",
- (doOpen ? "open" : "close"),
- status);
- } else {
- emberAfAppPrintln("Door is now %s", (doOpen ? "open" : "closed"));
- emberAfFillCommandDoorLockClusterOperationEventNotification(EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_MANUAL,
- (doOpen
- ? EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_MANUAL_UNLOCK
- : EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_MANUAL_LOCK),
- 0 /* userId */, PIN, eventCount++ /*timestamp*/, PIN);
+ static uint8_t eventCount = 0;
+ uint8_t PIN[] = "";
+ bool doOpen = (emberStringCommandArgument(-1, NULL)[0] == 'o');
+ EmberAfDoorState state = (doOpen ? EMBER_ZCL_DOOR_STATE_OPEN : EMBER_ZCL_DOOR_STATE_CLOSED);
+ EmberAfStatus status = emAfPluginDoorLockServerNoteDoorStateChanged(state);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfAppPrintln("Failed to %s door: 0x%X", (doOpen ? "open" : "close"), status);
+ }
+ else
+ {
+ emberAfAppPrintln("Door is now %s", (doOpen ? "open" : "closed"));
+ emberAfFillCommandDoorLockClusterOperationEventNotification(EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_MANUAL,
+ (doOpen ? EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_MANUAL_UNLOCK
+ : EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_MANUAL_LOCK),
+ 0 /* userId */, PIN, eventCount++ /*timestamp*/, PIN);
- EmberApsFrame *apsFrame = emberAfGetCommandApsFrame();
- apsFrame->sourceEndpoint = 1; //emberAfCurrentEndpoint();
+ EmberApsFrame * apsFrame = emberAfGetCommandApsFrame();
+ apsFrame->sourceEndpoint = 1; // emberAfCurrentEndpoint();
- SEND_COMMAND_UNICAST_TO_BINDINGS();
- }
+ SEND_COMMAND_UNICAST_TO_BINDINGS();
+ }
}
// plugin door-lock-server apply-pin <pin:?>
// plugin door-lock-server apply-rfid <rfid:?>
void emAfPluginDoorLockServerApplyCodeCommand(void)
{
- bool isPin = (emberStringCommandArgument(-1, NULL)[6] == 'p');
- uint8_t codeLength;
- uint8_t *code = emberStringCommandArgument(0, &codeLength);
- EmberAfStatus status
- = (isPin
- ? emberAfPluginDoorLockServerApplyPin(code, codeLength)
- : emberAfPluginDoorLockServerApplyRfid(code, codeLength));
- emberAfAppPrintln("Apply %s: 0x%X", (isPin ? "PIN" : "RFID"), status);
+ bool isPin = (emberStringCommandArgument(-1, NULL)[6] == 'p');
+ uint8_t codeLength;
+ uint8_t * code = emberStringCommandArgument(0, &codeLength);
+ EmberAfStatus status =
+ (isPin ? emberAfPluginDoorLockServerApplyPin(code, codeLength) : emberAfPluginDoorLockServerApplyRfid(code, codeLength));
+ emberAfAppPrintln("Apply %s: 0x%X", (isPin ? "PIN" : "RFID"), status);
}
diff --git a/src/app/clusters/door-lock-server/door-lock-server-core.c b/src/app/clusters/door-lock-server/door-lock-server-core.c
index 02f21b1..6afc2fd 100644
--- a/src/app/clusters/door-lock-server/door-lock-server-core.c
+++ b/src/app/clusters/door-lock-server/door-lock-server-core.c
@@ -31,129 +31,105 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Routines for the Door Lock Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#include "door-lock-server.h"
static void setActuatorEnable(void)
{
- // The Door Lock cluster test spec expects this attribute set to be true by
- // default...
- bool troo = true;
- EmberAfStatus status
- = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_ACTUATOR_ENABLED_ATTRIBUTE_ID,
- (uint8_t *)&troo,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to write ActuatorEnabled attribute: 0x%X",
- status);
- }
+ // The Door Lock cluster test spec expects this attribute set to be true by
+ // default...
+ bool troo = true;
+ EmberAfStatus status =
+ emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_ACTUATOR_ENABLED_ATTRIBUTE_ID,
+ (uint8_t *) &troo, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to write ActuatorEnabled attribute: 0x%X", status);
+ }
}
static void setDoorState(void)
{
- uint8_t state = EMBER_ZCL_DOOR_STATE_ERROR_UNSPECIFIED;
- EmberAfStatus status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_DOOR_STATE_ATTRIBUTE_ID,
- (uint8_t *)&state,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to write DoorState attribute: 0x%X",
- status);
- }
+ uint8_t state = EMBER_ZCL_DOOR_STATE_ERROR_UNSPECIFIED;
+ EmberAfStatus status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_DOOR_STATE_ATTRIBUTE_ID, (uint8_t *) &state, ZCL_ENUM8_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to write DoorState attribute: 0x%X", status);
+ }
}
static void setLanguage(void)
{
- uint8_t englishString[] = { 0x02, 'e', 'n' };
- EmberAfStatus status
- = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LANGUAGE_ATTRIBUTE_ID,
- englishString,
- ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to write Language attribute: 0x%X",
- status);
- }
+ uint8_t englishString[] = { 0x02, 'e', 'n' };
+ EmberAfStatus status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_LANGUAGE_ATTRIBUTE_ID, englishString, ZCL_CHAR_STRING_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to write Language attribute: 0x%X", status);
+ }
}
void emberAfPluginDoorLockServerInitCallback(void)
{
- emAfPluginDoorLockServerInitUser();
- emAfPluginDoorLockServerInitSchedule();
+ emAfPluginDoorLockServerInitUser();
+ emAfPluginDoorLockServerInitSchedule();
- setActuatorEnable();
- setDoorState();
- setLanguage();
+ setActuatorEnable();
+ setDoorState();
+ setLanguage();
}
-void emAfPluginDoorLockServerWriteAttributes(const EmAfPluginDoorLockServerAttributeData *data,
- uint8_t dataLength,
- const char *description)
+void emAfPluginDoorLockServerWriteAttributes(const EmAfPluginDoorLockServerAttributeData * data, uint8_t dataLength,
+ const char * description)
{
- for (uint8_t i = 0; i < dataLength; i++) {
- EmberAfStatus status
- = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- data[i].id,
- (uint8_t *)&data[i].value,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to write %s attribute 0x%2X: 0x%X",
- data[i].id,
- status,
- description);
+ for (uint8_t i = 0; i < dataLength; i++)
+ {
+ EmberAfStatus status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, data[i].id,
+ (uint8_t *) &data[i].value, ZCL_INT16U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to write %s attribute 0x%2X: 0x%X", data[i].id, status, description);
+ }
}
- }
}
EmberAfStatus emAfPluginDoorLockServerNoteDoorStateChanged(EmberAfDoorState state)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
+ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_DOOR_STATE_ATTRIBUTE
- status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_DOOR_STATE_ATTRIBUTE_ID,
- (uint8_t *)&state,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- }
-#endif
-
-#if defined(ZCL_USING_DOOR_LOCK_CLUSTER_DOOR_OPEN_EVENTS_ATTRIBUTE) \
- || defined(ZCL_USING_DOOR_LOCK_CLUSTER_DOOR_CLOSED_EVENTS_ATTRIBUTE)
- if (state == EMBER_ZCL_DOOR_STATE_OPEN
- || state == EMBER_ZCL_DOOR_STATE_CLOSED) {
- EmberAfAttributeId attributeId = (state == EMBER_ZCL_DOOR_STATE_OPEN
- ? ZCL_DOOR_OPEN_EVENTS_ATTRIBUTE_ID
- : ZCL_DOOR_CLOSED_EVENTS_ATTRIBUTE_ID);
- uint32_t events;
- status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- attributeId,
- (uint8_t *)&events,
- sizeof(events));
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- events++;
- status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- attributeId,
- (uint8_t *)&events,
- ZCL_INT32U_ATTRIBUTE_TYPE);
+ status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_DOOR_STATE_ATTRIBUTE_ID,
+ (uint8_t *) &state, ZCL_ENUM8_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
}
- }
#endif
- return status;
+#if defined(ZCL_USING_DOOR_LOCK_CLUSTER_DOOR_OPEN_EVENTS_ATTRIBUTE) || \
+ defined(ZCL_USING_DOOR_LOCK_CLUSTER_DOOR_CLOSED_EVENTS_ATTRIBUTE)
+ if (state == EMBER_ZCL_DOOR_STATE_OPEN || state == EMBER_ZCL_DOOR_STATE_CLOSED)
+ {
+ EmberAfAttributeId attributeId =
+ (state == EMBER_ZCL_DOOR_STATE_OPEN ? ZCL_DOOR_OPEN_EVENTS_ATTRIBUTE_ID : ZCL_DOOR_CLOSED_EVENTS_ATTRIBUTE_ID);
+ uint32_t events;
+ status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, attributeId, (uint8_t *) &events,
+ sizeof(events));
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ events++;
+ status = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, attributeId,
+ (uint8_t *) &events, ZCL_INT32U_ATTRIBUTE_TYPE);
+ }
+ }
+#endif
+
+ return status;
}
diff --git a/src/app/clusters/door-lock-server/door-lock-server-logging.c b/src/app/clusters/door-lock-server/door-lock-server-logging.c
index 8d90d95..06e2ad1 100644
--- a/src/app/clusters/door-lock-server/door-lock-server-logging.c
+++ b/src/app/clusters/door-lock-server/door-lock-server-logging.c
@@ -31,11 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Logging routines for the Door Lock Server plugin.
+ * @brief Logging routines for the Door Lock Server
+ *plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#include "door-lock-server.h"
@@ -43,101 +44,90 @@
static EmberAfPluginDoorLockServerLogEntry entries[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_LOG_ENTRIES];
static uint8_t nextEntryId = 1;
-#define ENTRY_ID_TO_INDEX(entryId) ((entryId) - 1)
+#define ENTRY_ID_TO_INDEX(entryId) ((entryId) -1)
#define ENTRY_ID_IS_VALID(entryId) ((entryId) > 0 && (entryId) < nextEntryId)
#define MOST_RECENT_ENTRY_ID() (nextEntryId - 1)
#define LOG_IS_EMPTY() (nextEntryId == 1)
static bool loggingIsEnabled(void)
{
- // This is hardcoded to endpoint 1 because...we need to add endpoint support...
- uint8_t endpoint = 1;
- bool logging = false;
- EmberAfStatus status
- = emberAfReadServerAttribute(endpoint,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_ENABLE_LOGGING_ATTRIBUTE_ID,
- (uint8_t *)&logging,
- sizeof(logging));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Could not read EnableLogging attribute: 0x%X",
- status);
- }
- return logging;
+ // This is hardcoded to endpoint 1 because...we need to add endpoint support...
+ uint8_t endpoint = 1;
+ bool logging = false;
+ EmberAfStatus status = emberAfReadServerAttribute(endpoint, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_ENABLE_LOGGING_ATTRIBUTE_ID,
+ (uint8_t *) &logging, sizeof(logging));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Could not read EnableLogging attribute: 0x%X", status);
+ }
+ return logging;
}
-bool emberAfPluginDoorLockServerAddLogEntry(EmberAfDoorLockEventType eventType,
- EmberAfDoorLockEventSource source,
- uint8_t eventId,
- uint16_t userId,
- uint8_t pinLength,
- uint8_t *pin)
+bool emberAfPluginDoorLockServerAddLogEntry(EmberAfDoorLockEventType eventType, EmberAfDoorLockEventSource source, uint8_t eventId,
+ uint16_t userId, uint8_t pinLength, uint8_t * pin)
{
- if (!loggingIsEnabled()
- || ENTRY_ID_TO_INDEX(nextEntryId) >= COUNTOF(entries)) {
- return false;
- }
+ if (!loggingIsEnabled() || ENTRY_ID_TO_INDEX(nextEntryId) >= COUNTOF(entries))
+ {
+ return false;
+ }
- EmberAfPluginDoorLockServerLogEntry *nextEntry
- = &entries[ENTRY_ID_TO_INDEX(nextEntryId)];
- nextEntry->logEntryId = nextEntryId;
- nextEntry->timestamp = emberAfGetCurrentTimeCallback();
- nextEntry->eventType = eventType;
- nextEntry->source = source;
- nextEntry->eventId = eventId;
- nextEntry->userId = userId;
- // Truncate logged PIN if larger than log entry capacity.
- uint8_t moveLength = (pinLength > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH
- ? EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH
- : pinLength);
- nextEntry->pin[0] = moveLength;
- MEMMOVE(nextEntry->pin + 1, pin, moveLength);
+ EmberAfPluginDoorLockServerLogEntry * nextEntry = &entries[ENTRY_ID_TO_INDEX(nextEntryId)];
+ nextEntry->logEntryId = nextEntryId;
+ nextEntry->timestamp = emberAfGetCurrentTimeCallback();
+ nextEntry->eventType = eventType;
+ nextEntry->source = source;
+ nextEntry->eventId = eventId;
+ nextEntry->userId = userId;
+ // Truncate logged PIN if larger than log entry capacity.
+ uint8_t moveLength =
+ (pinLength > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH ? EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH : pinLength);
+ nextEntry->pin[0] = moveLength;
+ MEMMOVE(nextEntry->pin + 1, pin, moveLength);
- nextEntryId++;
+ nextEntryId++;
- return true;
+ return true;
}
-bool emberAfPluginDoorLockServerGetLogEntry(uint16_t *entryId,
- EmberAfPluginDoorLockServerLogEntry *entry)
+bool emberAfPluginDoorLockServerGetLogEntry(uint16_t * entryId, EmberAfPluginDoorLockServerLogEntry * entry)
{
- if (LOG_IS_EMPTY()) {
- return false;
- }
+ if (LOG_IS_EMPTY())
+ {
+ return false;
+ }
- if (!ENTRY_ID_IS_VALID(*entryId)) {
- *entryId = MOST_RECENT_ENTRY_ID();
- }
- assert(ENTRY_ID_IS_VALID(*entryId));
+ if (!ENTRY_ID_IS_VALID(*entryId))
+ {
+ *entryId = MOST_RECENT_ENTRY_ID();
+ }
+ assert(ENTRY_ID_IS_VALID(*entryId));
- *entry = entries[ENTRY_ID_TO_INDEX(*entryId)];
+ *entry = entries[ENTRY_ID_TO_INDEX(*entryId)];
- return true;
+ return true;
}
bool emberAfDoorLockClusterGetLogRecordCallback(uint16_t entryId)
{
- EmberStatus status;
- EmberAfPluginDoorLockServerLogEntry entry;
- if (LOG_IS_EMPTY() || !emberAfPluginDoorLockServerGetLogEntry(&entryId, &entry)) {
- status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send default response: 0x%X",
- status);
+ EmberStatus status;
+ EmberAfPluginDoorLockServerLogEntry entry;
+ if (LOG_IS_EMPTY() || !emberAfPluginDoorLockServerGetLogEntry(&entryId, &entry))
+ {
+ status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send default response: 0x%X", status);
+ }
}
- } else {
- emberAfFillCommandDoorLockClusterGetLogRecordResponse(entry.logEntryId,
- entry.timestamp,
- entry.eventType,
- entry.source,
- entry.eventId,
- entry.userId,
- entry.pin);
- status = emberAfSendResponse();
- if (status != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send GetLogRecordResponse: 0x%X",
- status);
+ else
+ {
+ emberAfFillCommandDoorLockClusterGetLogRecordResponse(entry.logEntryId, entry.timestamp, entry.eventType, entry.source,
+ entry.eventId, entry.userId, entry.pin);
+ status = emberAfSendResponse();
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send GetLogRecordResponse: 0x%X", status);
+ }
}
- }
- return true;
+ return true;
}
diff --git a/src/app/clusters/door-lock-server/door-lock-server-schedule.c b/src/app/clusters/door-lock-server/door-lock-server-schedule.c
index 2a7bff9..9fedcc8 100644
--- a/src/app/clusters/door-lock-server/door-lock-server-schedule.c
+++ b/src/app/clusters/door-lock-server/door-lock-server-schedule.c
@@ -31,343 +31,316 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Routines for the Door Lock Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#include "door-lock-server.h"
-static EmberAfPluginDoorLockServerWeekdayScheduleEntry weekdayScheduleTable[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE];
-static EmberAfPluginDoorLockServerYeardayScheduleEntry yeardayScheduleTable[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE];
-static EmberAfPluginDoorLockServerHolidayScheduleEntry holidayScheduleTable[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE];
+static EmberAfPluginDoorLockServerWeekdayScheduleEntry
+ weekdayScheduleTable[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE];
+static EmberAfPluginDoorLockServerYeardayScheduleEntry
+ yeardayScheduleTable[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE];
+static EmberAfPluginDoorLockServerHolidayScheduleEntry
+ holidayScheduleTable[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE];
static void printWeekdayScheduleTable(void)
{
- uint8_t i;
- emberAfDoorLockClusterPrintln("id uid dm strth strtm stph stpm");
- for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE; i++ ) {
- EmberAfDoorLockScheduleEntry *entry = &weekdayScheduleTable[i];
- if (entry->inUse) {
- emberAfDoorLockClusterPrintln("%x %2x %x %4x %4x %4x %4x",
- i,
- entry->userId,
- entry->daysMask,
- entry->startHour,
- entry->stopHour,
- entry->stopMinute);
+ uint8_t i;
+ emberAfDoorLockClusterPrintln("id uid dm strth strtm stph stpm");
+ for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE; i++)
+ {
+ EmberAfDoorLockScheduleEntry * entry = &weekdayScheduleTable[i];
+ if (entry->inUse)
+ {
+ emberAfDoorLockClusterPrintln("%x %2x %x %4x %4x %4x %4x", i, entry->userId, entry->daysMask, entry->startHour,
+ entry->stopHour, entry->stopMinute);
+ }
}
- }
}
static void clearWeekdayScheduleTable(void)
{
- for (uint8_t i = 0;
- i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE;
- i++) {
- weekdayScheduleTable[i].inUse = false;
- }
+ for (uint8_t i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE; i++)
+ {
+ weekdayScheduleTable[i].inUse = false;
+ }
}
static void clearYeardayScheduleTable(void)
{
- for (uint8_t i = 0;
- i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE;
- i++) {
- yeardayScheduleTable[i].inUse = false;
- }
+ for (uint8_t i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE; i++)
+ {
+ yeardayScheduleTable[i].inUse = false;
+ }
}
static void clearHolidayScheduleTable(void)
{
- for (uint8_t i = 0;
- i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE;
- i++) {
- holidayScheduleTable[i].inUse = false;
- }
+ for (uint8_t i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE; i++)
+ {
+ holidayScheduleTable[i].inUse = false;
+ }
}
void emAfPluginDoorLockServerInitSchedule(void)
{
- clearWeekdayScheduleTable();
- clearYeardayScheduleTable();
- clearHolidayScheduleTable();
+ clearWeekdayScheduleTable();
+ clearYeardayScheduleTable();
+ clearHolidayScheduleTable();
-#if defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_WEEKDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE) \
- || defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_YEARDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE) \
- || defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_HOLIDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE)
- const EmAfPluginDoorLockServerAttributeData data[] = {
+#if defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_WEEKDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE) || \
+ defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_YEARDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE) || \
+ defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_HOLIDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE)
+ const EmAfPluginDoorLockServerAttributeData data[] = {
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_NUM_WEEKDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE
- { ZCL_NUM_WEEKDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE_ID,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE },
+ { ZCL_NUM_WEEKDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE_ID, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE },
#endif
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_NUM_YEARDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE
- { ZCL_NUM_YEARDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE_ID,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE },
+ { ZCL_NUM_YEARDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE_ID, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE },
#endif
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_NUM_HOLIDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE
- { ZCL_NUM_HOLIDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE_ID,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE },
+ { ZCL_NUM_HOLIDAY_SCHEDULES_SUPPORTED_PER_USER_ATTRIBUTE_ID, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE },
#endif
- };
- emAfPluginDoorLockServerWriteAttributes(data, COUNTOF(data), "schedule table");
+ };
+ emAfPluginDoorLockServerWriteAttributes(data, COUNTOF(data), "schedule table");
#endif
}
-static void sendResponse(const char *responseName)
+static void sendResponse(const char * responseName)
{
- EmberStatus status = emberAfSendResponse();
- if (status != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send %s: 0x%X",
- responseName,
- status);
- }
+ EmberStatus status = emberAfSendResponse();
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send %s: 0x%X", responseName, status);
+ }
}
-bool emberAfDoorLockClusterSetWeekdayScheduleCallback(uint8_t scheduleId,
- uint16_t userId,
- uint8_t daysMask,
- uint8_t startHour,
- uint8_t startMinute,
- uint8_t stopHour,
- uint8_t stopMinute)
+bool emberAfDoorLockClusterSetWeekdayScheduleCallback(uint8_t scheduleId, uint16_t userId, uint8_t daysMask, uint8_t startHour,
+ uint8_t startMinute, uint8_t stopHour, uint8_t stopMinute)
{
- uint8_t status = 0x00;
- uint8_t userPin = 0x00;
- uint16_t rfProgrammingEventMask = 0xffff; //event sent by default
- if (!emAfPluginDoorLockServerCheckForSufficientSpace(scheduleId,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE)
- || !emAfPluginDoorLockServerCheckForSufficientSpace(userId,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE)) {
- status = 0x01;
- }
- if (!status) {
- EmberAfDoorLockScheduleEntry *entry = &weekdayScheduleTable[scheduleId];
- entry->inUse = true;
- entry->userId = userId;
- entry->daysMask = daysMask;
- entry->startHour = startHour;
- entry->startMinute = startMinute;
- entry->stopHour = stopHour;
- entry->stopMinute = stopMinute;
- emberAfDoorLockClusterPrintln("***RX SET WEEKDAY SCHEDULE***");
- printWeekdayScheduleTable();
- }
- emberAfFillCommandDoorLockClusterSetWeekdayScheduleResponse(status);
- emberAfSendResponse();
+ uint8_t status = 0x00;
+ uint8_t userPin = 0x00;
+ uint16_t rfProgrammingEventMask = 0xffff; // event sent by default
+ if (!emAfPluginDoorLockServerCheckForSufficientSpace(scheduleId,
+ EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE) ||
+ !emAfPluginDoorLockServerCheckForSufficientSpace(userId, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE))
+ {
+ status = 0x01;
+ }
+ if (!status)
+ {
+ EmberAfDoorLockScheduleEntry * entry = &weekdayScheduleTable[scheduleId];
+ entry->inUse = true;
+ entry->userId = userId;
+ entry->daysMask = daysMask;
+ entry->startHour = startHour;
+ entry->startMinute = startMinute;
+ entry->stopHour = stopHour;
+ entry->stopMinute = stopMinute;
+ emberAfDoorLockClusterPrintln("***RX SET WEEKDAY SCHEDULE***");
+ printWeekdayScheduleTable();
+ }
+ emberAfFillCommandDoorLockClusterSetWeekdayScheduleResponse(status);
+ emberAfSendResponse();
- //get bitmask so we can check if we should send event notification
- emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_RF_PROGRAMMING_EVENT_MASK_ATTRIBUTE_ID,
- (uint8_t*)&rfProgrammingEventMask,
- sizeof(rfProgrammingEventMask));
+ // get bitmask so we can check if we should send event notification
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_RF_PROGRAMMING_EVENT_MASK_ATTRIBUTE_ID,
+ (uint8_t *) &rfProgrammingEventMask, sizeof(rfProgrammingEventMask));
- if (rfProgrammingEventMask & BIT(0)) {
- emberAfFillCommandDoorLockClusterProgrammingEventNotification(0x01, 0x00, userId, &userPin, 0x00, 0x00, 0x00, &userPin);
- SEND_COMMAND_UNICAST_TO_BINDINGS();
- }
+ if (rfProgrammingEventMask & BIT(0))
+ {
+ emberAfFillCommandDoorLockClusterProgrammingEventNotification(0x01, 0x00, userId, &userPin, 0x00, 0x00, 0x00, &userPin);
+ SEND_COMMAND_UNICAST_TO_BINDINGS();
+ }
- return true;
+ return true;
}
-bool emberAfDoorLockClusterGetWeekdayScheduleCallback(uint8_t scheduleId,
- uint16_t userId)
+bool emberAfDoorLockClusterGetWeekdayScheduleCallback(uint8_t scheduleId, uint16_t userId)
{
- EmberAfStatus zclStatus
- = ((scheduleId
- > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE)
- ? EMBER_ZCL_STATUS_INVALID_FIELD
- : EMBER_ZCL_STATUS_SUCCESS);
- EmberAfDoorLockScheduleEntry *entry = &weekdayScheduleTable[0];
- if (zclStatus == EMBER_ZCL_STATUS_SUCCESS) {
- entry = &weekdayScheduleTable[scheduleId];
- zclStatus = (!entry->inUse
- ? EMBER_ZCL_STATUS_NOT_FOUND
- : (entry->userId != userId
- ? EMBER_ZCL_STATUS_NOT_FOUND
- : EMBER_ZCL_STATUS_SUCCESS));
- }
+ EmberAfStatus zclStatus =
+ ((scheduleId > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE) ? EMBER_ZCL_STATUS_INVALID_FIELD
+ : EMBER_ZCL_STATUS_SUCCESS);
+ EmberAfDoorLockScheduleEntry * entry = &weekdayScheduleTable[0];
+ if (zclStatus == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ entry = &weekdayScheduleTable[scheduleId];
+ zclStatus = (!entry->inUse ? EMBER_ZCL_STATUS_NOT_FOUND
+ : (entry->userId != userId ? EMBER_ZCL_STATUS_NOT_FOUND : EMBER_ZCL_STATUS_SUCCESS));
+ }
- emberAfFillCommandDoorLockClusterGetWeekdayScheduleResponse(scheduleId,
- userId,
- zclStatus,
- entry->daysMask,
- entry->startHour,
- entry->startMinute,
- entry->stopHour,
- entry->stopMinute);
+ emberAfFillCommandDoorLockClusterGetWeekdayScheduleResponse(scheduleId, userId, zclStatus, entry->daysMask, entry->startHour,
+ entry->startMinute, entry->stopHour, entry->stopMinute);
- sendResponse("GetWeekdayScheduleResponse");
+ sendResponse("GetWeekdayScheduleResponse");
- return true;
+ return true;
}
-bool emberAfDoorLockClusterClearWeekdayScheduleCallback(uint8_t scheduleId,
- uint16_t userId)
+bool emberAfDoorLockClusterClearWeekdayScheduleCallback(uint8_t scheduleId, uint16_t userId)
{
- EmberAfStatus zclStatus
- = ((scheduleId
- > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE)
- ? EMBER_ZCL_STATUS_INVALID_FIELD
- : EMBER_ZCL_STATUS_SUCCESS);
- if (zclStatus == EMBER_ZCL_STATUS_SUCCESS) {
- weekdayScheduleTable[scheduleId].inUse = false;
- emAfPluginDoorLockServerSetPinUserType(userId,
- EMBER_ZCL_DOOR_LOCK_USER_TYPE_UNRESTRICTED);
- }
+ EmberAfStatus zclStatus =
+ ((scheduleId > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE) ? EMBER_ZCL_STATUS_INVALID_FIELD
+ : EMBER_ZCL_STATUS_SUCCESS);
+ if (zclStatus == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ weekdayScheduleTable[scheduleId].inUse = false;
+ emAfPluginDoorLockServerSetPinUserType(userId, EMBER_ZCL_DOOR_LOCK_USER_TYPE_UNRESTRICTED);
+ }
- emberAfFillCommandDoorLockClusterClearWeekdayScheduleResponse(zclStatus);
+ emberAfFillCommandDoorLockClusterClearWeekdayScheduleResponse(zclStatus);
- sendResponse("ClearWeekdayScheduleResponse");
+ sendResponse("ClearWeekdayScheduleResponse");
- return true;
+ return true;
}
-bool emberAfDoorLockClusterSetYeardayScheduleCallback(uint8_t scheduleId,
- uint16_t userId,
- uint32_t localStartTime,
+bool emberAfDoorLockClusterSetYeardayScheduleCallback(uint8_t scheduleId, uint16_t userId, uint32_t localStartTime,
uint32_t localEndTime)
{
- uint8_t status;
- if (scheduleId
- >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE) {
- status = 0x01; // failure (per 7.3.2.17.15)
- } else {
- yeardayScheduleTable[scheduleId].userId = userId;
- yeardayScheduleTable[scheduleId].localStartTime = localStartTime;
- yeardayScheduleTable[scheduleId].localEndTime = localEndTime;
- yeardayScheduleTable[scheduleId].inUse = true;
- status = 0x00; // success (per 7.3.2.17.15)
- }
- emberAfFillCommandDoorLockClusterSetYeardayScheduleResponse(status);
-
- sendResponse("SetYeardayScheduleResponse");
-
- return true;
-}
-
-bool emberAfDoorLockClusterGetYeardayScheduleCallback(uint8_t scheduleId,
- uint16_t userId)
-{
- EmberAfPluginDoorLockServerYeardayScheduleEntry *entry
- = &yeardayScheduleTable[0];
- EmberAfStatus zclStatus;
- if (scheduleId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE
- || userId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE) {
- zclStatus = EMBER_ZCL_STATUS_INVALID_FIELD;
- } else {
- entry = &yeardayScheduleTable[scheduleId];
- if (!entry->inUse || entry->userId != userId) {
- zclStatus = EMBER_ZCL_STATUS_NOT_FOUND;
- } else {
- zclStatus = EMBER_ZCL_STATUS_SUCCESS;
+ uint8_t status;
+ if (scheduleId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE)
+ {
+ status = 0x01; // failure (per 7.3.2.17.15)
}
- }
+ else
+ {
+ yeardayScheduleTable[scheduleId].userId = userId;
+ yeardayScheduleTable[scheduleId].localStartTime = localStartTime;
+ yeardayScheduleTable[scheduleId].localEndTime = localEndTime;
+ yeardayScheduleTable[scheduleId].inUse = true;
+ status = 0x00; // success (per 7.3.2.17.15)
+ }
+ emberAfFillCommandDoorLockClusterSetYeardayScheduleResponse(status);
- emberAfFillCommandDoorLockClusterGetYeardayScheduleResponse(scheduleId,
- userId,
- zclStatus,
- entry->localStartTime,
- entry->localEndTime);
+ sendResponse("SetYeardayScheduleResponse");
- sendResponse("GetYeardayScheduleResponse");
-
- return true;
+ return true;
}
-bool emberAfDoorLockClusterClearYeardayScheduleCallback(uint8_t scheduleId,
- uint16_t userId)
+bool emberAfDoorLockClusterGetYeardayScheduleCallback(uint8_t scheduleId, uint16_t userId)
{
- uint8_t status;
- if (scheduleId
- >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE) {
- status = 0x01; // failure (per 7.3.2.17.17)
- } else {
- yeardayScheduleTable[scheduleId].inUse = false;
- emAfPluginDoorLockServerSetPinUserType(userId,
- EMBER_ZCL_DOOR_LOCK_USER_TYPE_UNRESTRICTED);
- status = 0x00; // success (per 7.3.2.17.17)
- }
- emberAfFillCommandDoorLockClusterClearYeardayScheduleResponse(status);
+ EmberAfPluginDoorLockServerYeardayScheduleEntry * entry = &yeardayScheduleTable[0];
+ EmberAfStatus zclStatus;
+ if (scheduleId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE ||
+ userId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE)
+ {
+ zclStatus = EMBER_ZCL_STATUS_INVALID_FIELD;
+ }
+ else
+ {
+ entry = &yeardayScheduleTable[scheduleId];
+ if (!entry->inUse || entry->userId != userId)
+ {
+ zclStatus = EMBER_ZCL_STATUS_NOT_FOUND;
+ }
+ else
+ {
+ zclStatus = EMBER_ZCL_STATUS_SUCCESS;
+ }
+ }
- sendResponse("ClearYeardayScheduleResponse");
+ emberAfFillCommandDoorLockClusterGetYeardayScheduleResponse(scheduleId, userId, zclStatus, entry->localStartTime,
+ entry->localEndTime);
- return true;
+ sendResponse("GetYeardayScheduleResponse");
+
+ return true;
}
-bool emberAfDoorLockClusterSetHolidayScheduleCallback(uint8_t holidayScheduleId,
- uint32_t localStartTime,
- uint32_t localEndTime,
+bool emberAfDoorLockClusterClearYeardayScheduleCallback(uint8_t scheduleId, uint16_t userId)
+{
+ uint8_t status;
+ if (scheduleId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE)
+ {
+ status = 0x01; // failure (per 7.3.2.17.17)
+ }
+ else
+ {
+ yeardayScheduleTable[scheduleId].inUse = false;
+ emAfPluginDoorLockServerSetPinUserType(userId, EMBER_ZCL_DOOR_LOCK_USER_TYPE_UNRESTRICTED);
+ status = 0x00; // success (per 7.3.2.17.17)
+ }
+ emberAfFillCommandDoorLockClusterClearYeardayScheduleResponse(status);
+
+ sendResponse("ClearYeardayScheduleResponse");
+
+ return true;
+}
+
+bool emberAfDoorLockClusterSetHolidayScheduleCallback(uint8_t holidayScheduleId, uint32_t localStartTime, uint32_t localEndTime,
uint8_t operatingModeDuringHoliday)
{
- uint8_t status;
- if (holidayScheduleId
- >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE) {
- status = 0x01; // failure (per 7.3.2.17.18)
- } else {
- holidayScheduleTable[holidayScheduleId].localStartTime
- = localStartTime;
- holidayScheduleTable[holidayScheduleId].localEndTime
- = localEndTime;
- holidayScheduleTable[holidayScheduleId].operatingModeDuringHoliday
- = operatingModeDuringHoliday;
- holidayScheduleTable[holidayScheduleId].inUse
- = true;
- status = 0x00; // success (per 7.3.2.17.18)
- }
- emberAfFillCommandDoorLockClusterSetHolidayScheduleResponse(status);
+ uint8_t status;
+ if (holidayScheduleId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE)
+ {
+ status = 0x01; // failure (per 7.3.2.17.18)
+ }
+ else
+ {
+ holidayScheduleTable[holidayScheduleId].localStartTime = localStartTime;
+ holidayScheduleTable[holidayScheduleId].localEndTime = localEndTime;
+ holidayScheduleTable[holidayScheduleId].operatingModeDuringHoliday = operatingModeDuringHoliday;
+ holidayScheduleTable[holidayScheduleId].inUse = true;
+ status = 0x00; // success (per 7.3.2.17.18)
+ }
+ emberAfFillCommandDoorLockClusterSetHolidayScheduleResponse(status);
- sendResponse("SetHolidayScheduleResponse");
+ sendResponse("SetHolidayScheduleResponse");
- return true;
+ return true;
}
bool emberAfDoorLockClusterGetHolidayScheduleCallback(uint8_t holidayScheduleId)
{
- EmberAfPluginDoorLockServerHolidayScheduleEntry *entry
- = &holidayScheduleTable[0];
- EmberAfStatus zclStatus;
- if (holidayScheduleId
- >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE) {
- zclStatus = EMBER_ZCL_STATUS_INVALID_FIELD;
- } else {
- entry = &holidayScheduleTable[holidayScheduleId];
- if (!entry->inUse) {
- zclStatus = EMBER_ZCL_STATUS_NOT_FOUND;
- } else {
- zclStatus = EMBER_ZCL_STATUS_SUCCESS;
+ EmberAfPluginDoorLockServerHolidayScheduleEntry * entry = &holidayScheduleTable[0];
+ EmberAfStatus zclStatus;
+ if (holidayScheduleId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE)
+ {
+ zclStatus = EMBER_ZCL_STATUS_INVALID_FIELD;
}
- }
+ else
+ {
+ entry = &holidayScheduleTable[holidayScheduleId];
+ if (!entry->inUse)
+ {
+ zclStatus = EMBER_ZCL_STATUS_NOT_FOUND;
+ }
+ else
+ {
+ zclStatus = EMBER_ZCL_STATUS_SUCCESS;
+ }
+ }
- emberAfFillCommandDoorLockClusterGetHolidayScheduleResponse(holidayScheduleId,
- zclStatus,
- entry->localStartTime,
- entry->localEndTime,
- entry->operatingModeDuringHoliday);
+ emberAfFillCommandDoorLockClusterGetHolidayScheduleResponse(holidayScheduleId, zclStatus, entry->localStartTime,
+ entry->localEndTime, entry->operatingModeDuringHoliday);
- sendResponse("GetHolidayScheduleResponse");
+ sendResponse("GetHolidayScheduleResponse");
- return true;
+ return true;
}
bool emberAfDoorLockClusterClearHolidayScheduleCallback(uint8_t holidayScheduleId)
{
- uint8_t status;
- if (holidayScheduleId
- >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE) {
- status = 0x01; // failure (per 7.3.2.17.20)
- } else {
- holidayScheduleTable[holidayScheduleId].inUse = false;
- status = 0x00; // success (per 7.3.2.17.20)
- }
- emberAfFillCommandDoorLockClusterClearHolidayScheduleResponse(status);
+ uint8_t status;
+ if (holidayScheduleId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_YEARDAY_SCHEDULE_TABLE_SIZE)
+ {
+ status = 0x01; // failure (per 7.3.2.17.20)
+ }
+ else
+ {
+ holidayScheduleTable[holidayScheduleId].inUse = false;
+ status = 0x00; // success (per 7.3.2.17.20)
+ }
+ emberAfFillCommandDoorLockClusterClearHolidayScheduleResponse(status);
- sendResponse("ClearYeardayScheduleResponse");
+ sendResponse("ClearYeardayScheduleResponse");
- return true;
+ return true;
}
diff --git a/src/app/clusters/door-lock-server/door-lock-server-user.c b/src/app/clusters/door-lock-server/door-lock-server-user.c
index dd8cede..5b06ac0 100644
--- a/src/app/clusters/door-lock-server/door-lock-server-user.c
+++ b/src/app/clusters/door-lock-server/door-lock-server-user.c
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Routines for the Door Lock Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "../../include/af.h"
#include "../../util/common.h"
@@ -53,11 +53,12 @@
bool emAfPluginDoorLockServerCheckForSufficientSpace(uint8_t spaceReq, uint8_t spaceAvail)
{
- if (spaceReq > spaceAvail) {
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INSUFFICIENT_SPACE);
- return false;
- }
- return true;
+ if (spaceReq > spaceAvail)
+ {
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INSUFFICIENT_SPACE);
+ return false;
+ }
+ return true;
}
// ------------------------------------------------------------------------------
@@ -66,421 +67,367 @@
static void enableSendPinOverTheAir(void)
{
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SEND_PIN_OVER_THE_AIR_ATTRIBUTE
- bool troo = true;
- EmberAfStatus status
- = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_SEND_PIN_OVER_THE_AIR_ATTRIBUTE_ID,
- (uint8_t *)&troo,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to write SendPinOverTheAir attribute: 0x%X",
- status);
- }
+ bool troo = true;
+ EmberAfStatus status =
+ emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_SEND_PIN_OVER_THE_AIR_ATTRIBUTE_ID,
+ (uint8_t *) &troo, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to write SendPinOverTheAir attribute: 0x%X", status);
+ }
#endif
}
void emAfPluginDoorLockServerInitUser(void)
{
-#if defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_TOTAL_USERS_SUPPORTED_ATTRIBUTE) \
- || defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_PIN_USERS_SUPPORTED_ATTRIBUTE) \
- || defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_RFID_USERS_SUPPORTED_ATTRIBUTE)
- const EmAfPluginDoorLockServerAttributeData data[] = {
+#if defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_TOTAL_USERS_SUPPORTED_ATTRIBUTE) || \
+ defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_PIN_USERS_SUPPORTED_ATTRIBUTE) || \
+ defined(ZCL_USING_DOOR_LOCK_CLUSTER_NUM_RFID_USERS_SUPPORTED_ATTRIBUTE)
+ const EmAfPluginDoorLockServerAttributeData data[] = {
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_NUM_TOTAL_USERS_SUPPORTED_ATTRIBUTE
- // This attribute is...confusing. Here is the description of it from
- // 7.3.2.12.2.
- // "Number of total users supported by the lock. This value is equal to the
- // higher one of [# of PIN Users Supported] and [# of RFID Users
- // Supported]"
- { ZCL_NUM_TOTAL_USERS_SUPPORTED_ATTRIBUTE_ID,
- ((EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE
- > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE)
- ? EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE
- : EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE) },
+ // This attribute is...confusing. Here is the description of it from
+ // 7.3.2.12.2.
+ // "Number of total users supported by the lock. This value is equal to the
+ // higher one of [# of PIN Users Supported] and [# of RFID Users
+ // Supported]"
+ { ZCL_NUM_TOTAL_USERS_SUPPORTED_ATTRIBUTE_ID,
+ ((EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE > EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE)
+ ? EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE
+ : EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE) },
#endif
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_NUM_PIN_USERS_SUPPORTED_ATTRIBUTE
- { ZCL_NUM_PIN_USERS_SUPPORTED_ATTRIBUTE_ID,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE },
+ { ZCL_NUM_PIN_USERS_SUPPORTED_ATTRIBUTE_ID, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE },
#endif
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_NUM_RFID_USERS_SUPPORTED_ATTRIBUTE
- { ZCL_NUM_RFID_USERS_SUPPORTED_ATTRIBUTE_ID,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE },
+ { ZCL_NUM_RFID_USERS_SUPPORTED_ATTRIBUTE_ID, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE },
#endif
- };
- emAfPluginDoorLockServerWriteAttributes(data, COUNTOF(data), "user table");
+ };
+ emAfPluginDoorLockServerWriteAttributes(data, COUNTOF(data), "user table");
#endif
- enableSendPinOverTheAir();
+ enableSendPinOverTheAir();
}
// ------------------------------------------------------------------------------
// User management
// "pin" parameter is Zigbee string, so first byte is length.
-static void printPin(uint8_t *pin)
+static void printPin(uint8_t * pin)
{
- uint8_t pinLength = emberAfStringLength(pin);
- emberAfDoorLockClusterPrint("(%x)", pinLength);
- for (uint8_t i = 0; i < pinLength; i++) {
- emberAfDoorLockClusterPrint(" %c", pin[i + 1]);
- }
+ uint8_t pinLength = emberAfStringLength(pin);
+ emberAfDoorLockClusterPrint("(%x)", pinLength);
+ for (uint8_t i = 0; i < pinLength; i++)
+ {
+ emberAfDoorLockClusterPrint(" %c", pin[i + 1]);
+ }
}
static void printUserTables(void)
{
- uint8_t i;
- emberAfDoorLockClusterPrintln("id st ty PIN");
- emberAfDoorLockClusterPrintln("PIN:");
- for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE; i++) {
- EmberAfPluginDoorLockServerUser *user = &pinUserTable[i];
- emberAfDoorLockClusterPrint("%2x %x %x ", i, user->status, user->type);
- printPin(user->code.pin);
- emberAfDoorLockClusterPrintln("");
- }
- emberAfDoorLockClusterPrintln("RFID:");
- for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE; i++) {
- EmberAfPluginDoorLockServerUser *user = &rfidUserTable[i];
- emberAfDoorLockClusterPrint("%2x %x %x ", i, user->status, user->type);
- printPin(user->code.rfid);
- emberAfDoorLockClusterPrintln("");
- }
+ uint8_t i;
+ emberAfDoorLockClusterPrintln("id st ty PIN");
+ emberAfDoorLockClusterPrintln("PIN:");
+ for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE; i++)
+ {
+ EmberAfPluginDoorLockServerUser * user = &pinUserTable[i];
+ emberAfDoorLockClusterPrint("%2x %x %x ", i, user->status, user->type);
+ printPin(user->code.pin);
+ emberAfDoorLockClusterPrintln("");
+ }
+ emberAfDoorLockClusterPrintln("RFID:");
+ for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE; i++)
+ {
+ EmberAfPluginDoorLockServerUser * user = &rfidUserTable[i];
+ emberAfDoorLockClusterPrint("%2x %x %x ", i, user->status, user->type);
+ printPin(user->code.rfid);
+ emberAfDoorLockClusterPrintln("");
+ }
}
// Returns status byte for use in SetPinResponse and SetRfidResponse commands.
-static uint8_t setUser(uint16_t userId,
- uint8_t userStatus,
- uint8_t userType,
- uint8_t *code,
- EmberAfPluginDoorLockServerUser *userTable,
- uint8_t userTableSize)
+static uint8_t setUser(uint16_t userId, uint8_t userStatus, uint8_t userType, uint8_t * code,
+ EmberAfPluginDoorLockServerUser * userTable, uint8_t userTableSize)
{
- bool success = false;
- // "code" (i.e. PIN/RFID) is stored in table entry in ZCL format (1-byte
- // length prefix). Don't allow a code with length that exceeds capacity
- // of the table entry field. Note there are potentially different max
- // lengths for PIN v. RFID.
- bool validCodeLength = false;
- if (code != NULL
- && ((userTable == pinUserTable
- && emberAfStringLength(code) <= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH)
- || (emberAfStringLength(code) <= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_RFID_LENGTH))) {
- validCodeLength = true;
- }
+ bool success = false;
+ // "code" (i.e. PIN/RFID) is stored in table entry in ZCL format (1-byte
+ // length prefix). Don't allow a code with length that exceeds capacity
+ // of the table entry field. Note there are potentially different max
+ // lengths for PIN v. RFID.
+ bool validCodeLength = false;
+ if (code != NULL &&
+ ((userTable == pinUserTable && emberAfStringLength(code) <= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH) ||
+ (emberAfStringLength(code) <= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_RFID_LENGTH)))
+ {
+ validCodeLength = true;
+ }
- if (validCodeLength && userId < userTableSize) {
- EmberAfPluginDoorLockServerUser *user = &userTable[userId];
- user->status = userStatus;
- user->type = userType;
- MEMMOVE(user->code.rfid,
- code,
- emberAfStringLength(code) + 1); // + 1 for Zigbee string length byte
+ if (validCodeLength && userId < userTableSize)
+ {
+ EmberAfPluginDoorLockServerUser * user = &userTable[userId];
+ user->status = userStatus;
+ user->type = userType;
+ MEMMOVE(user->code.rfid, code,
+ emberAfStringLength(code) + 1); // + 1 for Zigbee string length byte
- emberAfDoorLockClusterPrintln("***RX SET %s ***",
- (userTable == pinUserTable ? "PIN" : "RFID"));
- printUserTables();
+ emberAfDoorLockClusterPrintln("***RX SET %s ***", (userTable == pinUserTable ? "PIN" : "RFID"));
+ printUserTables();
- success = true;
- }
- return (success ? 0x00 : 0x01); // See 7.3.2.17.6 and 7.3.2.17.23).
+ success = true;
+ }
+ return (success ? 0x00 : 0x01); // See 7.3.2.17.6 and 7.3.2.17.23).
}
// Returns true for success, false for failure.
-static bool getUser(uint16_t userId,
- EmberAfPluginDoorLockServerUser *userTable,
- uint8_t userTableSize,
- EmberAfPluginDoorLockServerUser *returnedUser)
+static bool getUser(uint16_t userId, EmberAfPluginDoorLockServerUser * userTable, uint8_t userTableSize,
+ EmberAfPluginDoorLockServerUser * returnedUser)
{
- bool success = false;
- if (userId < userTableSize) {
- *returnedUser = userTable[userId];
- success = true;
- }
- return success;
+ bool success = false;
+ if (userId < userTableSize)
+ {
+ *returnedUser = userTable[userId];
+ success = true;
+ }
+ return success;
}
// Returns status byte for use in ClearPin and ClearRfid response commands.
-static uint8_t clearUserPinOrRfid(uint16_t userId,
- EmberAfPluginDoorLockServerUser *userTable,
- uint8_t userTableSize)
+static uint8_t clearUserPinOrRfid(uint16_t userId, EmberAfPluginDoorLockServerUser * userTable, uint8_t userTableSize)
{
- bool success = false;
- if (userId < userTableSize) {
- // Since the rfid member of the struct is a Zigbee string, setting the first
- // byte to 0 will indicate that we have a 0-length pin.
- MEMSET((userTable == pinUserTable
- ? userTable[userId].code.pin
- : userTable[userId].code.rfid),
- 0x00,
- sizeof(userTable[userId].code));
- success = true;
- }
- return (success ? 0x00 : 0x01); // See 7.3.2.17.8 and 7.3.2.17.25).
+ bool success = false;
+ if (userId < userTableSize)
+ {
+ // Since the rfid member of the struct is a Zigbee string, setting the first
+ // byte to 0 will indicate that we have a 0-length pin.
+ MEMSET((userTable == pinUserTable ? userTable[userId].code.pin : userTable[userId].code.rfid), 0x00,
+ sizeof(userTable[userId].code));
+ success = true;
+ }
+ return (success ? 0x00 : 0x01); // See 7.3.2.17.8 and 7.3.2.17.25).
}
bool emberAfDoorLockClusterGetUserTypeCallback(uint16_t userId)
{
- if (emAfPluginDoorLockServerCheckForSufficientSpace(userId,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE)) {
- EmberAfPluginDoorLockServerUser *user = &pinUserTable[userId];
- emberAfFillCommandDoorLockClusterGetUserTypeResponse(userId, user->type);
- EmberStatus status = emberAfSendResponse();
- if (status != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send GetUserTypeResponse: 0x%X",
- status);
+ if (emAfPluginDoorLockServerCheckForSufficientSpace(userId, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE))
+ {
+ EmberAfPluginDoorLockServerUser * user = &pinUserTable[userId];
+ emberAfFillCommandDoorLockClusterGetUserTypeResponse(userId, user->type);
+ EmberStatus status = emberAfSendResponse();
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send GetUserTypeResponse: 0x%X", status);
+ }
}
- }
- return true;
-}
-
-bool emberAfDoorLockClusterSetUserTypeCallback(uint16_t userId,
- uint8_t userType)
-{
- uint8_t status = (emAfPluginDoorLockServerSetPinUserType(userId, userType)
- ? 0x00 // success (per 7.3.2.17.21)
- : 0x01); // failure (per 7.3.2.17.21)
- emberAfFillCommandDoorLockClusterSetUserTypeResponse(status);
-
- EmberStatus emberStatus = emberAfSendResponse();
- if (emberStatus != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send SetUserTypeResponse: 0x%X",
- emberStatus);
- }
- return true;
-}
-
-bool emAfPluginDoorLockServerSetPinUserType(uint16_t userId,
- EmberAfDoorLockUserType type)
-{
- if (userId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE) {
- return false;
- } else {
- pinUserTable[userId].type = type;
return true;
- }
+}
+
+bool emberAfDoorLockClusterSetUserTypeCallback(uint16_t userId, uint8_t userType)
+{
+ uint8_t status = (emAfPluginDoorLockServerSetPinUserType(userId, userType) ? 0x00 // success (per 7.3.2.17.21)
+ : 0x01); // failure (per 7.3.2.17.21)
+ emberAfFillCommandDoorLockClusterSetUserTypeResponse(status);
+
+ EmberStatus emberStatus = emberAfSendResponse();
+ if (emberStatus != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send SetUserTypeResponse: 0x%X", emberStatus);
+ }
+ return true;
+}
+
+bool emAfPluginDoorLockServerSetPinUserType(uint16_t userId, EmberAfDoorLockUserType type)
+{
+ if (userId >= EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE)
+ {
+ return false;
+ }
+ else
+ {
+ pinUserTable[userId].type = type;
+ return true;
+ }
}
// ------------------------------------------------------------------------------
// PIN handling
-bool emberAfDoorLockClusterSetPinCallback(uint16_t userId,
- uint8_t userStatus,
- uint8_t userType,
- uint8_t *pin)
+bool emberAfDoorLockClusterSetPinCallback(uint16_t userId, uint8_t userStatus, uint8_t userType, uint8_t * pin)
{
- //send response
- uint8_t status = setUser(userId,
- userStatus,
- userType,
- pin,
- pinUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
- emberAfFillCommandDoorLockClusterSetPinResponse(status);
- emberAfSendResponse();
+ // send response
+ uint8_t status = setUser(userId, userStatus, userType, pin, pinUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
+ emberAfFillCommandDoorLockClusterSetPinResponse(status);
+ emberAfSendResponse();
- //get bitmask so we can check if we should send event notification
- uint16_t rfProgrammingEventMask = 0xffff; //send event by default
- emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_RF_PROGRAMMING_EVENT_MASK_ATTRIBUTE_ID,
- (uint8_t*)&rfProgrammingEventMask,
- sizeof(rfProgrammingEventMask));
- if ((rfProgrammingEventMask & BIT(2)) && !status && (pin != NULL)) {
- emberAfFillCommandDoorLockClusterProgrammingEventNotification(EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_RF,
- EMBER_ZCL_DOOR_LOCK_PROGRAMMING_EVENT_CODE_PIN_ADDED,
- userId,
- pin,
- userType,
- userStatus,
- emberAfGetCurrentTime(),
- pin);
- SEND_COMMAND_UNICAST_TO_BINDINGS();
- }
+ // get bitmask so we can check if we should send event notification
+ uint16_t rfProgrammingEventMask = 0xffff; // send event by default
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_RF_PROGRAMMING_EVENT_MASK_ATTRIBUTE_ID,
+ (uint8_t *) &rfProgrammingEventMask, sizeof(rfProgrammingEventMask));
+ if ((rfProgrammingEventMask & BIT(2)) && !status && (pin != NULL))
+ {
+ emberAfFillCommandDoorLockClusterProgrammingEventNotification(EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_RF,
+ EMBER_ZCL_DOOR_LOCK_PROGRAMMING_EVENT_CODE_PIN_ADDED, userId,
+ pin, userType, userStatus, emberAfGetCurrentTime(), pin);
+ SEND_COMMAND_UNICAST_TO_BINDINGS();
+ }
- return true;
+ return true;
}
static bool getSendPinOverTheAir(void)
{
- bool sendPinOverTheAir = true;
+ bool sendPinOverTheAir = true;
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SEND_PIN_OVER_THE_AIR_ATTRIBUTE
- EmberAfStatus status
- = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_SEND_PIN_OVER_THE_AIR_ATTRIBUTE_ID,
- (uint8_t *)&sendPinOverTheAir,
- sizeof(sendPinOverTheAir));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to read SendPinOverTheAir attribute: 0x%X",
- status);
- }
+ EmberAfStatus status =
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_SEND_PIN_OVER_THE_AIR_ATTRIBUTE_ID,
+ (uint8_t *) &sendPinOverTheAir, sizeof(sendPinOverTheAir));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to read SendPinOverTheAir attribute: 0x%X", status);
+ }
#endif
- return sendPinOverTheAir;
+ return sendPinOverTheAir;
}
bool emberAfDoorLockClusterGetPinCallback(uint16_t userId)
{
- EmberAfPluginDoorLockServerUser user;
- EmberStatus status;
- if (getUser(userId,
- pinUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE,
- &user)) {
- uint8_t fakePin = 0x00;
- emberAfFillCommandDoorLockClusterGetPinResponse(userId,
- user.status,
- user.type,
- (getSendPinOverTheAir()
- ? user.code.pin
- : &fakePin));
- status = emberAfSendResponse();
- } else {
- status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
- }
+ EmberAfPluginDoorLockServerUser user;
+ EmberStatus status;
+ if (getUser(userId, pinUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE, &user))
+ {
+ uint8_t fakePin = 0x00;
+ emberAfFillCommandDoorLockClusterGetPinResponse(userId, user.status, user.type,
+ (getSendPinOverTheAir() ? user.code.pin : &fakePin));
+ status = emberAfSendResponse();
+ }
+ else
+ {
+ status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
+ }
- if (status != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send response to GetPin: 0x%X",
- status);
- }
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send response to GetPin: 0x%X", status);
+ }
- return true;
+ return true;
}
bool emberAfDoorLockClusterClearPinCallback(uint16_t userId)
{
- uint8_t status
- = clearUserPinOrRfid(userId,
- pinUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
- emberAfFillCommandDoorLockClusterClearPinResponse(status);
+ uint8_t status = clearUserPinOrRfid(userId, pinUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
+ emberAfFillCommandDoorLockClusterClearPinResponse(status);
- EmberStatus emberStatus = emberAfSendResponse();
- if (emberStatus != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send ClearPinResponse: 0x%X",
- emberStatus);
- }
+ EmberStatus emberStatus = emberAfSendResponse();
+ if (emberStatus != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send ClearPinResponse: 0x%X", emberStatus);
+ }
- //get bitmask so we can check if we should send event notification
- uint16_t rfProgrammingEventMask = 0xffff; //event sent by default
- uint8_t userPin = 0x00; // Zero length Zigbee string
- emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_RF_PROGRAMMING_EVENT_MASK_ATTRIBUTE_ID,
- (uint8_t*)&rfProgrammingEventMask,
- sizeof(rfProgrammingEventMask));
- if ((rfProgrammingEventMask & BIT(2)) && !status) {
- emberAfFillCommandDoorLockClusterProgrammingEventNotification(0x01, 0x03, userId, &userPin, 0x00, 0x00, 0x00, &userPin);
- SEND_COMMAND_UNICAST_TO_BINDINGS();
- } else if ((rfProgrammingEventMask & BIT(0)) && status) {
- emberAfFillCommandDoorLockClusterProgrammingEventNotification(0x01, 0x00, userId, &userPin, 0x00, 0x00, 0x00, &userPin);
- SEND_COMMAND_UNICAST_TO_BINDINGS();
- }
+ // get bitmask so we can check if we should send event notification
+ uint16_t rfProgrammingEventMask = 0xffff; // event sent by default
+ uint8_t userPin = 0x00; // Zero length Zigbee string
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_RF_PROGRAMMING_EVENT_MASK_ATTRIBUTE_ID,
+ (uint8_t *) &rfProgrammingEventMask, sizeof(rfProgrammingEventMask));
+ if ((rfProgrammingEventMask & BIT(2)) && !status)
+ {
+ emberAfFillCommandDoorLockClusterProgrammingEventNotification(0x01, 0x03, userId, &userPin, 0x00, 0x00, 0x00, &userPin);
+ SEND_COMMAND_UNICAST_TO_BINDINGS();
+ }
+ else if ((rfProgrammingEventMask & BIT(0)) && status)
+ {
+ emberAfFillCommandDoorLockClusterProgrammingEventNotification(0x01, 0x00, userId, &userPin, 0x00, 0x00, 0x00, &userPin);
+ SEND_COMMAND_UNICAST_TO_BINDINGS();
+ }
- return true;
+ return true;
}
bool emberAfDoorLockClusterClearAllPinsCallback(void)
{
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE; i++) {
- clearUserPinOrRfid(i,
- pinUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
- }
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE; i++)
+ {
+ clearUserPinOrRfid(i, pinUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
+ }
- // 7.3.2.17.9 says that "0x00" indicates success.
- emberAfFillCommandDoorLockClusterClearAllPinsResponse(0x00);
- EmberStatus status = emberAfSendResponse();
- if (status != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send ClearAllPins: 0x%X", status);
- }
- return true;
+ // 7.3.2.17.9 says that "0x00" indicates success.
+ emberAfFillCommandDoorLockClusterClearAllPinsResponse(0x00);
+ EmberStatus status = emberAfSendResponse();
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send ClearAllPins: 0x%X", status);
+ }
+ return true;
}
// ------------------------------------------------------------------------------
// RFID handling
-bool emberAfDoorLockClusterSetRfidCallback(uint16_t userId,
- uint8_t userStatus,
- uint8_t userType,
- uint8_t *rfid)
+bool emberAfDoorLockClusterSetRfidCallback(uint16_t userId, uint8_t userStatus, uint8_t userType, uint8_t * rfid)
{
- uint8_t status = setUser(userId,
- userStatus,
- userType,
- rfid,
- rfidUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
- emberAfFillCommandDoorLockClusterSetRfidResponse(status);
+ uint8_t status =
+ setUser(userId, userStatus, userType, rfid, rfidUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
+ emberAfFillCommandDoorLockClusterSetRfidResponse(status);
- EmberStatus emberStatus = emberAfSendResponse();
- if (emberStatus != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send SetRfidResponse: 0x%X",
- emberStatus);
- }
- return true;
+ EmberStatus emberStatus = emberAfSendResponse();
+ if (emberStatus != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send SetRfidResponse: 0x%X", emberStatus);
+ }
+ return true;
}
bool emberAfDoorLockClusterGetRfidCallback(uint16_t userId)
{
- EmberAfPluginDoorLockServerUser user;
- EmberStatus status;
- if (getUser(userId,
- rfidUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE,
- &user)) {
- emberAfFillCommandDoorLockClusterGetRfidResponse(userId,
- user.status,
- user.type,
- user.code.pin);
- status = emberAfSendResponse();
- } else {
- status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
- }
+ EmberAfPluginDoorLockServerUser user;
+ EmberStatus status;
+ if (getUser(userId, rfidUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE, &user))
+ {
+ emberAfFillCommandDoorLockClusterGetRfidResponse(userId, user.status, user.type, user.code.pin);
+ status = emberAfSendResponse();
+ }
+ else
+ {
+ status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_INVALID_VALUE);
+ }
- if (status != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send response to GetRfid: 0x%X",
- status);
- }
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send response to GetRfid: 0x%X", status);
+ }
- return true;
+ return true;
}
bool emberAfDoorLockClusterClearRfidCallback(uint16_t userId)
{
- uint8_t status
- = clearUserPinOrRfid(userId,
- rfidUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
- emberAfFillCommandDoorLockClusterClearRfidResponse(status);
+ uint8_t status = clearUserPinOrRfid(userId, rfidUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
+ emberAfFillCommandDoorLockClusterClearRfidResponse(status);
- EmberStatus emberStatus = emberAfSendResponse();
- if (emberStatus != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send ClearRfidResponse: 0x%X",
- emberStatus);
- }
- return true;
+ EmberStatus emberStatus = emberAfSendResponse();
+ if (emberStatus != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send ClearRfidResponse: 0x%X", emberStatus);
+ }
+ return true;
}
bool emberAfDoorLockClusterClearAllRfidsCallback(void)
{
- for (uint8_t i = 0;
- i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE;
- i++) {
- clearUserPinOrRfid(i,
- rfidUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
- }
+ for (uint8_t i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE; i++)
+ {
+ clearUserPinOrRfid(i, rfidUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
+ }
- // 7.3.2.17.26 says that "0x00" indicates success.
- emberAfFillCommandDoorLockClusterClearAllRfidsResponse(0x00);
- EmberStatus status = emberAfSendResponse();
- if (status != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send ClearAllRfidsResponse: 0x%X",
- status);
- }
- return true;
+ // 7.3.2.17.26 says that "0x00" indicates success.
+ emberAfFillCommandDoorLockClusterClearAllRfidsResponse(0x00);
+ EmberStatus status = emberAfSendResponse();
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send ClearAllRfidsResponse: 0x%X", status);
+ }
+ return true;
}
// ------------------------------------------------------------------------------
@@ -488,11 +435,14 @@
static void printSuccessOrFailure(bool success)
{
- if (success) {
- emberAfDoorLockClusterPrintln("SUCCESS!");
- } else {
- emberAfDoorLockClusterPrintln("FAILURE!");
- }
+ if (success)
+ {
+ emberAfDoorLockClusterPrintln("SUCCESS!");
+ }
+ else
+ {
+ emberAfDoorLockClusterPrintln("FAILURE!");
+ }
}
/**
@@ -503,234 +453,203 @@
* Note that the "pin" parameter is a Zigbee string, so the first byte is the
* length of the remaining bytes
*/
-static bool verifyPin(uint8_t *pin, uint8_t *userId)
+static bool verifyPin(uint8_t * pin, uint8_t * userId)
{
- bool pinRequired = false;
- EmberStatus status;
- uint8_t i;
+ bool pinRequired = false;
+ EmberStatus status;
+ uint8_t i;
- status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_REQUIRE_PIN_FOR_RF_OPERATION_ATTRIBUTE_ID,
- (uint8_t *) &pinRequired,
- sizeof(pinRequired));
- if (EMBER_SUCCESS != status || !pinRequired) {
- return true;
- } else if (pin == NULL) {
+ status =
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_REQUIRE_PIN_FOR_RF_OPERATION_ATTRIBUTE_ID, (uint8_t *) &pinRequired, sizeof(pinRequired));
+ if (EMBER_SUCCESS != status || !pinRequired)
+ {
+ return true;
+ }
+ else if (pin == NULL)
+ {
+ return false;
+ }
+
+ for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE; i++)
+ {
+ EmberAfPluginDoorLockServerUser * user = &pinUserTable[i];
+ uint8_t userPinLength = emberAfStringLength(user->code.pin);
+ if (userPinLength == emberAfStringLength(pin) && 0 == MEMCOMPARE(&user->code.pin[1], &pin[1], userPinLength))
+ {
+ *userId = i;
+ return true;
+ }
+ }
+
return false;
- }
-
- for (i = 0; i < EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE; i++) {
- EmberAfPluginDoorLockServerUser *user = &pinUserTable[i];
- uint8_t userPinLength = emberAfStringLength(user->code.pin);
- if (userPinLength == emberAfStringLength(pin)
- && 0 == MEMCOMPARE(&user->code.pin[1], &pin[1], userPinLength)) {
- *userId = i;
- return true;
- }
- }
-
- return false;
}
-bool emberAfDoorLockClusterLockDoorCallback(uint8_t* PIN)
+bool emberAfDoorLockClusterLockDoorCallback(uint8_t * PIN)
{
- uint8_t userId = 0;
- bool pinVerified = verifyPin(PIN, &userId);
- bool doorLocked = false;
- uint8_t lockStateLocked = 0x01;
- uint16_t rfOperationEventMask = 0xffff; //will send events by default
+ uint8_t userId = 0;
+ bool pinVerified = verifyPin(PIN, &userId);
+ bool doorLocked = false;
+ uint8_t lockStateLocked = 0x01;
+ uint16_t rfOperationEventMask = 0xffff; // will send events by default
- emberAfDoorLockClusterPrint("LOCK DOOR ");
- printSuccessOrFailure(pinVerified);
+ emberAfDoorLockClusterPrint("LOCK DOOR ");
+ printSuccessOrFailure(pinVerified);
- if (pinVerified) {
- doorLocked =
- emberAfPluginDoorLockServerActivateDoorLockCallback(true); //lock door
- }
-
- if (doorLocked) {
- emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- &lockStateLocked,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
-
- //send response
- emberAfFillCommandDoorLockClusterLockDoorResponse(doorLocked
- ? EMBER_ZCL_STATUS_SUCCESS
- : EMBER_ZCL_STATUS_FAILURE);
- emberAfSendResponse();
-
- //check if we should send event notification
- emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_RF_OPERATION_EVENT_MASK_ATTRIBUTE_ID,
- (uint8_t*)&rfOperationEventMask,
- sizeof(rfOperationEventMask));
-
- // Possibly send operation event
- if (doorLocked) {
- if (rfOperationEventMask & BIT(1) && (PIN != NULL)) {
- emberAfFillCommandDoorLockClusterOperationEventNotification(0x01, 0x01, userId, PIN, 0x00, PIN);
+ if (pinVerified)
+ {
+ doorLocked = emberAfPluginDoorLockServerActivateDoorLockCallback(true); // lock door
}
- } else {
- if (rfOperationEventMask & BIT(3) && (PIN != NULL)) {
- emberAfFillCommandDoorLockClusterOperationEventNotification(0x01, 0x03, userId, PIN, 0x00, PIN);
+
+ if (doorLocked)
+ {
+ emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_LOCK_STATE_ATTRIBUTE_ID,
+ &lockStateLocked, ZCL_INT8U_ATTRIBUTE_TYPE);
}
- }
- SEND_COMMAND_UNICAST_TO_BINDINGS();
- return true;
-}
+ // send response
+ emberAfFillCommandDoorLockClusterLockDoorResponse(doorLocked ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE);
+ emberAfSendResponse();
-bool emberAfDoorLockClusterUnlockDoorCallback(uint8_t* pin)
-{
- uint8_t userId = 0;
- bool pinVerified = verifyPin(pin, &userId);
- bool doorUnlocked = false;
- uint8_t lockStateUnlocked = 0x02;
- uint16_t rfOperationEventMask = 0xffff; //sends event by default
- emberAfDoorLockClusterPrint("UNLOCK DOOR ");
- printSuccessOrFailure(pinVerified);
+ // check if we should send event notification
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_RF_OPERATION_EVENT_MASK_ATTRIBUTE_ID,
+ (uint8_t *) &rfOperationEventMask, sizeof(rfOperationEventMask));
- if (pinVerified) {
- doorUnlocked =
- emberAfPluginDoorLockServerActivateDoorLockCallback(false); //unlock door
- }
- if (doorUnlocked) {
- emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- &lockStateUnlocked,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
-
- emberAfFillCommandDoorLockClusterUnlockDoorResponse(doorUnlocked
- ? EMBER_ZCL_STATUS_SUCCESS
- : EMBER_ZCL_STATUS_FAILURE);
- emberAfSendResponse();
-
- //get bitmask so we can check if we should send event notification
- emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_RF_OPERATION_EVENT_MASK_ATTRIBUTE_ID,
- (uint8_t*)&rfOperationEventMask,
- sizeof(rfOperationEventMask));
-
- //send operation event
- if (doorUnlocked && (rfOperationEventMask & BIT(2)) && (pin != NULL)) {
- emberAfFillCommandDoorLockClusterOperationEventNotification(EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_RF,
- EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_UNLOCK,
- userId,
- pin,
- emberAfGetCurrentTime(),
- pin);
+ // Possibly send operation event
+ if (doorLocked)
+ {
+ if (rfOperationEventMask & BIT(1) && (PIN != NULL))
+ {
+ emberAfFillCommandDoorLockClusterOperationEventNotification(0x01, 0x01, userId, PIN, 0x00, PIN);
+ }
+ }
+ else
+ {
+ if (rfOperationEventMask & BIT(3) && (PIN != NULL))
+ {
+ emberAfFillCommandDoorLockClusterOperationEventNotification(0x01, 0x03, userId, PIN, 0x00, PIN);
+ }
+ }
SEND_COMMAND_UNICAST_TO_BINDINGS();
- }
- return true;
+ return true;
+}
+
+bool emberAfDoorLockClusterUnlockDoorCallback(uint8_t * pin)
+{
+ uint8_t userId = 0;
+ bool pinVerified = verifyPin(pin, &userId);
+ bool doorUnlocked = false;
+ uint8_t lockStateUnlocked = 0x02;
+ uint16_t rfOperationEventMask = 0xffff; // sends event by default
+ emberAfDoorLockClusterPrint("UNLOCK DOOR ");
+ printSuccessOrFailure(pinVerified);
+
+ if (pinVerified)
+ {
+ doorUnlocked = emberAfPluginDoorLockServerActivateDoorLockCallback(false); // unlock door
+ }
+ if (doorUnlocked)
+ {
+ emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_LOCK_STATE_ATTRIBUTE_ID,
+ &lockStateUnlocked, ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
+
+ emberAfFillCommandDoorLockClusterUnlockDoorResponse(doorUnlocked ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE);
+ emberAfSendResponse();
+
+ // get bitmask so we can check if we should send event notification
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_RF_OPERATION_EVENT_MASK_ATTRIBUTE_ID,
+ (uint8_t *) &rfOperationEventMask, sizeof(rfOperationEventMask));
+
+ // send operation event
+ if (doorUnlocked && (rfOperationEventMask & BIT(2)) && (pin != NULL))
+ {
+ emberAfFillCommandDoorLockClusterOperationEventNotification(EMBER_ZCL_DOOR_LOCK_EVENT_SOURCE_RF,
+ EMBER_ZCL_DOOR_LOCK_OPERATION_EVENT_CODE_UNLOCK, userId, pin,
+ emberAfGetCurrentTime(), pin);
+ SEND_COMMAND_UNICAST_TO_BINDINGS();
+ }
+
+ return true;
}
static uint8_t getWrongCodeEntryLimit()
{
- uint8_t limit = UINT8_MAX;
+ uint8_t limit = UINT8_MAX;
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_WRONG_CODE_ENTRY_LIMIT_ATTRIBUTE
- EmberAfStatus status
- = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_WRONG_CODE_ENTRY_LIMIT_ATTRIBUTE_ID,
- &limit,
- sizeof(limit));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to read WrongCodeEntryLimitAttribute: 0x%X",
- status);
- }
+ EmberAfStatus status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_WRONG_CODE_ENTRY_LIMIT_ATTRIBUTE_ID, &limit, sizeof(limit));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to read WrongCodeEntryLimitAttribute: 0x%X", status);
+ }
#endif
- return limit;
+ return limit;
}
static uint8_t getUserCodeTemporaryDisableTime()
{
- uint8_t timeS = 0; // 0 effectively turns off the temporary disable time
+ uint8_t timeS = 0; // 0 effectively turns off the temporary disable time
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_USER_CODE_TEMPORARY_DISABLE_TIME_ATTRIBUTE
- EmberAfStatus status
- = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_USER_CODE_TEMPORARY_DISABLE_TIME_ATTRIBUTE_ID,
- &timeS,
- sizeof(timeS));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to read UserCodeTemporaryDisableTime: 0x%X",
- status);
- }
+ EmberAfStatus status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_USER_CODE_TEMPORARY_DISABLE_TIME_ATTRIBUTE_ID, &timeS, sizeof(timeS));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to read UserCodeTemporaryDisableTime: 0x%X", status);
+ }
#endif
- return timeS;
+ return timeS;
}
static void startLockout()
{
- emberAfDoorLockClusterPrintln("Door lock entering lockout mode");
+ emberAfDoorLockClusterPrintln("Door lock entering lockout mode");
- uint8_t lockoutTimeS = getUserCodeTemporaryDisableTime();
- if (lockoutTimeS != 0) {
- emberEventControlSetDelayMS(emberAfPluginDoorLockServerLockoutEventControl,
- lockoutTimeS * MILLISECOND_TICKS_PER_SECOND);
- }
+ uint8_t lockoutTimeS = getUserCodeTemporaryDisableTime();
+ if (lockoutTimeS != 0)
+ {
+ emberEventControlSetDelayMS(emberAfPluginDoorLockServerLockoutEventControl, lockoutTimeS * MILLISECOND_TICKS_PER_SECOND);
+ }
}
// If code is NULL, then the door will automatically be unlocked.
-static EmberAfStatus applyCode(uint8_t *code,
- uint8_t codeLength,
- EmberAfPluginDoorLockServerUser *userTable,
+static EmberAfStatus applyCode(uint8_t * code, uint8_t codeLength, EmberAfPluginDoorLockServerUser * userTable,
uint8_t userTableLength)
{
- for (uint8_t i = 0; i < userTableLength; i++) {
- uint8_t *userCode = (userTable == pinUserTable
- ? userTable[i].code.pin
- : userTable[i].code.rfid);
- if (code == NULL
- || (emberAfStringLength(userCode) == codeLength
- && MEMCOMPARE(code, userCode + 1, codeLength) == 0)) {
- EmberAfDoorLockState state = EMBER_ZCL_DOOR_LOCK_STATE_UNLOCKED;
- return emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- (uint8_t *)&state,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
+ for (uint8_t i = 0; i < userTableLength; i++)
+ {
+ uint8_t * userCode = (userTable == pinUserTable ? userTable[i].code.pin : userTable[i].code.rfid);
+ if (code == NULL || (emberAfStringLength(userCode) == codeLength && MEMCOMPARE(code, userCode + 1, codeLength) == 0))
+ {
+ EmberAfDoorLockState state = EMBER_ZCL_DOOR_LOCK_STATE_UNLOCKED;
+ return emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_LOCK_STATE_ATTRIBUTE_ID,
+ (uint8_t *) &state, ZCL_ENUM8_ATTRIBUTE_TYPE);
+ }
}
- }
- wrongCodeEntryCount++;
- if (wrongCodeEntryCount >= getWrongCodeEntryLimit()) {
- startLockout();
- }
- return EMBER_ZCL_STATUS_FAILURE;
+ wrongCodeEntryCount++;
+ if (wrongCodeEntryCount >= getWrongCodeEntryLimit())
+ {
+ startLockout();
+ }
+ return EMBER_ZCL_STATUS_FAILURE;
}
void emberAfPluginDoorLockServerLockoutEventHandler(void)
{
- emberEventControlSetInactive(emberAfPluginDoorLockServerLockoutEventControl);
- emberAfDoorLockClusterPrintln("Door lock entering normal mode");
+ emberEventControlSetInactive(emberAfPluginDoorLockServerLockoutEventControl);
+ emberAfDoorLockClusterPrintln("Door lock entering normal mode");
}
-EmberAfStatus emberAfPluginDoorLockServerApplyRfid(uint8_t *rfid,
- uint8_t rfidLength)
+EmberAfStatus emberAfPluginDoorLockServerApplyRfid(uint8_t * rfid, uint8_t rfidLength)
{
- return applyCode(rfid,
- rfidLength,
- rfidUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
+ return applyCode(rfid, rfidLength, rfidUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_RFID_USER_TABLE_SIZE);
}
-EmberAfStatus emberAfPluginDoorLockServerApplyPin(uint8_t *pin,
- uint8_t pinLength)
+EmberAfStatus emberAfPluginDoorLockServerApplyPin(uint8_t * pin, uint8_t pinLength)
{
- return applyCode(pin,
- pinLength,
- pinUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
+ return applyCode(pin, pinLength, pinUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
}
// --------------------------------------
@@ -741,90 +660,83 @@
// attribute.
static void scheduleAutoRelock(uint32_t autoRelockTimeS)
{
- if (autoRelockTimeS == UINT32_MAX) {
- EmberAfStatus status
- = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_AUTO_RELOCK_TIME_ATTRIBUTE_ID,
- (uint8_t *)&autoRelockTimeS,
- sizeof(autoRelockTimeS));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to read AutoRelockTime attribute: 0x%X",
- status);
- return;
+ if (autoRelockTimeS == UINT32_MAX)
+ {
+ EmberAfStatus status =
+ emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_AUTO_RELOCK_TIME_ATTRIBUTE_ID,
+ (uint8_t *) &autoRelockTimeS, sizeof(autoRelockTimeS));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to read AutoRelockTime attribute: 0x%X", status);
+ return;
+ }
}
- }
- if (autoRelockTimeS == 0) {
- emberEventControlSetInactive(emberAfPluginDoorLockServerRelockEventControl);
- } else {
- emberEventControlSetDelayMS(emberAfPluginDoorLockServerRelockEventControl,
- (autoRelockTimeS
- * MILLISECOND_TICKS_PER_SECOND));
- }
+ if (autoRelockTimeS == 0)
+ {
+ emberEventControlSetInactive(emberAfPluginDoorLockServerRelockEventControl);
+ }
+ else
+ {
+ emberEventControlSetDelayMS(emberAfPluginDoorLockServerRelockEventControl,
+ (autoRelockTimeS * MILLISECOND_TICKS_PER_SECOND));
+ }
}
void emberAfPluginDoorLockServerRelockEventHandler(void)
{
- emberEventControlSetInactive(emberAfPluginDoorLockServerRelockEventControl);
+ emberEventControlSetInactive(emberAfPluginDoorLockServerRelockEventControl);
- EmberAfStatus status = applyCode(NULL,
- 0,
- pinUserTable,
- EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
- emberAfDoorLockClusterPrintln("Door automatically relocked: 0x%X", status);
+ EmberAfStatus status = applyCode(NULL, 0, pinUserTable, EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE);
+ emberAfDoorLockClusterPrintln("Door automatically relocked: 0x%X", status);
}
-void emberAfDoorLockClusterServerAttributeChangedCallback(uint8_t endpoint,
- EmberAfAttributeId attributeId)
+void emberAfDoorLockClusterServerAttributeChangedCallback(uint8_t endpoint, EmberAfAttributeId attributeId)
{
- if (endpoint == DOOR_LOCK_SERVER_ENDPOINT
- && attributeId == ZCL_LOCK_STATE_ATTRIBUTE_ID) {
- uint8_t lockState;
- EmberAfStatus status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- &lockState,
- sizeof(lockState));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to read LockState attribute: 0x%X",
- status);
- } else if (lockState == EMBER_ZCL_DOOR_LOCK_STATE_UNLOCKED) {
- scheduleAutoRelock(UINT32_MAX);
+ if (endpoint == DOOR_LOCK_SERVER_ENDPOINT && attributeId == ZCL_LOCK_STATE_ATTRIBUTE_ID)
+ {
+ uint8_t lockState;
+ EmberAfStatus status = emberAfReadServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_LOCK_STATE_ATTRIBUTE_ID, &lockState, sizeof(lockState));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to read LockState attribute: 0x%X", status);
+ }
+ else if (lockState == EMBER_ZCL_DOOR_LOCK_STATE_UNLOCKED)
+ {
+ scheduleAutoRelock(UINT32_MAX);
+ }
}
- }
}
-bool emberAfDoorLockClusterUnlockWithTimeoutCallback(uint16_t timeoutS,
- uint8_t *pin)
+bool emberAfDoorLockClusterUnlockWithTimeoutCallback(uint16_t timeoutS, uint8_t * pin)
{
- uint8_t userId;
- uint8_t status;
- if (verifyPin(pin, &userId)) {
- uint8_t lockState = EMBER_ZCL_DOOR_LOCK_STATE_LOCKED;
- EmberAfStatus readStatus
- = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- &lockState,
- ZCL_ENUM8_ATTRIBUTE_TYPE);
- if (readStatus != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to write LockState attribute: 0x%X",
- readStatus);
+ uint8_t userId;
+ uint8_t status;
+ if (verifyPin(pin, &userId))
+ {
+ uint8_t lockState = EMBER_ZCL_DOOR_LOCK_STATE_LOCKED;
+ EmberAfStatus readStatus = emberAfWriteServerAttribute(DOOR_LOCK_SERVER_ENDPOINT, ZCL_DOOR_LOCK_CLUSTER_ID,
+ ZCL_LOCK_STATE_ATTRIBUTE_ID, &lockState, ZCL_ENUM8_ATTRIBUTE_TYPE);
+ if (readStatus != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to write LockState attribute: 0x%X", readStatus);
+ }
+
+ scheduleAutoRelock(timeoutS);
+ status = 0x00; // success (per 7.3.2.17.4)
+ }
+ else
+ {
+ status = 0x01; // failure (per 7.3.2.17.4)
}
- scheduleAutoRelock(timeoutS);
- status = 0x00; // success (per 7.3.2.17.4)
- } else {
- status = 0x01; // failure (per 7.3.2.17.4)
- }
+ emberAfFillCommandDoorLockClusterUnlockWithTimeoutResponse(status);
+ EmberStatus emberStatus = emberAfSendResponse();
+ if (emberStatus != EMBER_SUCCESS)
+ {
+ emberAfDoorLockClusterPrintln("Failed to send UnlockWithTimeoutResponse: 0x%X", status);
+ }
- emberAfFillCommandDoorLockClusterUnlockWithTimeoutResponse(status);
- EmberStatus emberStatus = emberAfSendResponse();
- if (emberStatus != EMBER_SUCCESS) {
- emberAfDoorLockClusterPrintln("Failed to send UnlockWithTimeoutResponse: 0x%X",
- status);
- }
-
- return true;
+ return true;
}
diff --git a/src/app/clusters/door-lock-server/door-lock-server.h b/src/app/clusters/door-lock-server/door-lock-server.h
index e1e483f..e056ee3 100644
--- a/src/app/clusters/door-lock-server/door-lock-server.h
+++ b/src/app/clusters/door-lock-server/door-lock-server.h
@@ -31,28 +31,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief APIs and defines for the Door Lock Server plugin.
+ * @brief APIs and defines for the Door Lock Server
+ *plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// ------------------------------------------------------------------------------
// Core
#ifndef DOXYGEN_SHOULD_SKIP_THIS
-typedef struct {
- EmberAfAttributeId id;
- uint16_t value;
+typedef struct
+{
+ EmberAfAttributeId id;
+ uint16_t value;
} EmAfPluginDoorLockServerAttributeData;
// For each of the provided attribute ID/value pairs, write the attribute to the
// value on the DOOR_LOCK_SERVER_ENDPOINT. If this function encounters a failure,
// it will print something out. The description parameter is a string that
// describes the type of attributes that are being written.
-void emAfPluginDoorLockServerWriteAttributes(const EmAfPluginDoorLockServerAttributeData *data,
- uint8_t dataLength,
- const char *description);
+void emAfPluginDoorLockServerWriteAttributes(const EmAfPluginDoorLockServerAttributeData * data, uint8_t dataLength,
+ const char * description);
// This function should be called when the door state has changed. A status
// describing the success or failure of the update will be returned.
@@ -64,9 +65,9 @@
// Note: the DOOR_LOCK_USER_TABLE_SIZE symbol is respected because it
// was used originally as a configuration value for this plugin.
#ifdef DOOR_LOCK_USER_TABLE_SIZE
- #define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE DOOR_LOCK_USER_TABLE_SIZE
+#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE DOOR_LOCK_USER_TABLE_SIZE
#else
- #define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE 8
+#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_PIN_USER_TABLE_SIZE 8
#endif
// At boot, the NumberOfRFIDUsersSupported attribute will be written to this
@@ -77,9 +78,9 @@
// Note: the DOOR_LOCK_MAX_PIN_LENGTH symbol is respected because it was used
// originally as a configuration value for this plugin.
#ifdef DOOR_LOCK_MAX_PIN_LENGTH
- #define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH DOOR_LOCK_MAX_PIN_LENGTH
+#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH DOOR_LOCK_MAX_PIN_LENGTH
#else
- #define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH 8
+#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH 8
#endif
// This value should reflect the value of the MaxRFIDCodeLength attribute.
@@ -92,9 +93,9 @@
// Also note: technically, this is the _total_ number of weekday schedules that
// can be stored across all users.
#ifdef DOOR_LOCK_SCHEDULE_TABLE_SIZE
- #define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE DOOR_LOCK_SCHEDULE_TABLE_SIZE
+#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE DOOR_LOCK_SCHEDULE_TABLE_SIZE
#else
- #define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE 4
+#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_WEEKDAY_SCHEDULE_TABLE_SIZE 4
#endif
// At boot, the NumberOfYearDaySchedulesSupportedPerUser attribute will be
@@ -108,7 +109,7 @@
#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_HOLIDAY_SCHEDULE_TABLE_SIZE 8
#ifndef DOOR_LOCK_SERVER_ENDPOINT
- #define DOOR_LOCK_SERVER_ENDPOINT 1
+#define DOOR_LOCK_SERVER_ENDPOINT 1
#endif
// ------------------------------------------------------------------------------
@@ -118,40 +119,36 @@
// attribute.
#define EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_LOG_ENTRIES 16
-typedef struct {
- uint16_t logEntryId;
- uint32_t timestamp;
- EmberAfDoorLockEventType eventType;
- EmberAfDoorLockEventSource source;
+typedef struct
+{
+ uint16_t logEntryId;
+ uint32_t timestamp;
+ EmberAfDoorLockEventType eventType;
+ EmberAfDoorLockEventSource source;
- // This field is either a EmberAfDoorLockOperationEventCode or a
- // EmberAfDoorLockProgrammingEventCode.
- uint8_t eventId;
+ // This field is either a EmberAfDoorLockOperationEventCode or a
+ // EmberAfDoorLockProgrammingEventCode.
+ uint8_t eventId;
- uint16_t userId;
+ uint16_t userId;
- // This field is a ZCL string representing the PIN code (i.e., the first byte
- // of the buffer is the length of the total buffer).
- uint8_t pin[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH + 1];
+ // This field is a ZCL string representing the PIN code (i.e., the first byte
+ // of the buffer is the length of the total buffer).
+ uint8_t pin[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH + 1];
} EmberAfPluginDoorLockServerLogEntry;
// Add a log entry. Returns true iff the entry was added. Note that the eventId
// parameter should be of type EmberAfDoorLockOperationEventCode or
// EmberAfDoorLockProgrammingEventCode.
-bool emberAfPluginDoorLockServerAddLogEntry(EmberAfDoorLockEventType eventType,
- EmberAfDoorLockEventSource source,
- uint8_t eventId,
- uint16_t userId,
- uint8_t pinLength,
- uint8_t *pin);
+bool emberAfPluginDoorLockServerAddLogEntry(EmberAfDoorLockEventType eventType, EmberAfDoorLockEventSource source, uint8_t eventId,
+ uint16_t userId, uint8_t pinLength, uint8_t * pin);
// Get a log entry associated with the entry ID. If the entry ID does not exist,
// the most recent entry is returned and the entryId parameter is updated. The
// entryId is a 1-based index into an array of log entries in order to match
// GetLogRecord ZCL command. This will return true iff the entry was successfully
// returned.
-bool emberAfPluginDoorLockServerGetLogEntry(uint16_t *entryId,
- EmberAfPluginDoorLockServerLogEntry *entry);
+bool emberAfPluginDoorLockServerGetLogEntry(uint16_t * entryId, EmberAfPluginDoorLockServerLogEntry * entry);
// ------------------------------------------------------------------------------
// Users
@@ -162,27 +159,26 @@
// Set the user type associated with the provided user ID (userId) and return
// true iff successful.
-bool emAfPluginDoorLockServerSetPinUserType(uint16_t userId,
- EmberAfDoorLockUserType type);
+bool emAfPluginDoorLockServerSetPinUserType(uint16_t userId, EmberAfDoorLockUserType type);
#endif
-typedef struct {
- EmberAfDoorLockUserStatus status;
- EmberAfDoorLockUserType type;
+typedef struct
+{
+ EmberAfDoorLockUserStatus status;
+ EmberAfDoorLockUserType type;
- // This field is a Zigbee string, so the first byte is the length of the
- // remaining bytes.
- union {
- uint8_t pin[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH + 1];
- uint8_t rfid[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_RFID_LENGTH + 1];
- } code;
+ // This field is a Zigbee string, so the first byte is the length of the
+ // remaining bytes.
+ union
+ {
+ uint8_t pin[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_PIN_LENGTH + 1];
+ uint8_t rfid[EMBER_AF_PLUGIN_DOOR_LOCK_SERVER_MAX_RFID_LENGTH + 1];
+ } code;
} EmberAfPluginDoorLockServerUser;
// These functions will attempt to unlock the door with a PIN/RFID.
-EmberAfStatus emberAfPluginDoorLockServerApplyPin(uint8_t *pin,
- uint8_t pinLength);
-EmberAfStatus emberAfPluginDoorLockServerApplyRfid(uint8_t *rfid,
- uint8_t rfidLength);
+EmberAfStatus emberAfPluginDoorLockServerApplyPin(uint8_t * pin, uint8_t pinLength);
+EmberAfStatus emberAfPluginDoorLockServerApplyRfid(uint8_t * rfid, uint8_t rfidLength);
// ------------------------------------------------------------------------------
// Schedule
@@ -192,28 +188,31 @@
void emAfPluginDoorLockServerInitSchedule(void);
#endif
-typedef struct {
- uint16_t userId;
- uint8_t daysMask;
- uint8_t startHour;
- uint8_t startMinute;
- uint8_t stopHour;
- uint8_t stopMinute;
- bool inUse;
+typedef struct
+{
+ uint16_t userId;
+ uint8_t daysMask;
+ uint8_t startHour;
+ uint8_t startMinute;
+ uint8_t stopHour;
+ uint8_t stopMinute;
+ bool inUse;
} EmberAfPluginDoorLockServerWeekdayScheduleEntry;
-typedef struct {
- uint16_t userId;
- uint32_t localStartTime;
- uint32_t localEndTime;
- bool inUse;
+typedef struct
+{
+ uint16_t userId;
+ uint32_t localStartTime;
+ uint32_t localEndTime;
+ bool inUse;
} EmberAfPluginDoorLockServerYeardayScheduleEntry;
-typedef struct {
- uint32_t localStartTime;
- uint32_t localEndTime;
- EmberAfDoorLockOperatingMode operatingModeDuringHoliday;
- bool inUse;
+typedef struct
+{
+ uint32_t localStartTime;
+ uint32_t localEndTime;
+ EmberAfDoorLockOperatingMode operatingModeDuringHoliday;
+ bool inUse;
} EmberAfPluginDoorLockServerHolidayScheduleEntry;
// ------------------------------------------------------------------------------
@@ -231,7 +230,8 @@
// If the Critical Message Queue Plugin is available, use it for event notifications
#ifdef EMBER_AF_PLUGIN_CRITICAL_MESSAGE_QUEUE
#include "../critical-message-queue/critical-message-queue.h"
-#define SEND_COMMAND_UNICAST_TO_BINDINGS() emberAfSendCommandUnicastToBindingsWithCallback(emberAfPluginCriticalMessageQueueEnqueueCallback)
+#define SEND_COMMAND_UNICAST_TO_BINDINGS() \
+ emberAfSendCommandUnicastToBindingsWithCallback(emberAfPluginCriticalMessageQueueEnqueueCallback)
#else
#define SEND_COMMAND_UNICAST_TO_BINDINGS() emberAfSendCommandUnicastToBindings()
#endif
diff --git a/src/app/clusters/groups-client/groups-client.c b/src/app/clusters/groups-client/groups-client.c
index c89bec1..ef19e55 100644
--- a/src/app/clusters/groups-client/groups-client.c
+++ b/src/app/clusters/groups-client/groups-client.c
@@ -31,12 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Groups Client plugin, the client implementation of
- * the Groups cluster.
+ * @brief Routines for the Groups Client plugin, the
+ *client implementation of the Groups cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// *******************************************************************
// * groups-client.c
@@ -47,52 +47,38 @@
#include "../../include/af.h"
-bool emberAfGroupsClusterAddGroupResponseCallback(uint8_t status,
- uint16_t groupId)
+bool emberAfGroupsClusterAddGroupResponseCallback(uint8_t status, uint16_t groupId)
{
- emberAfGroupsClusterPrintln("RX: AddGroupResponse 0x%x, 0x%2x",
- status,
- groupId);
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfGroupsClusterPrintln("RX: AddGroupResponse 0x%x, 0x%2x", status, groupId);
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
-bool emberAfGroupsClusterViewGroupResponseCallback(uint8_t status,
- uint16_t groupId,
- uint8_t* groupName)
+bool emberAfGroupsClusterViewGroupResponseCallback(uint8_t status, uint16_t groupId, uint8_t * groupName)
{
- emberAfGroupsClusterPrint("RX: ViewGroupResponse 0x%x, 0x%2x, \"",
- status,
- groupId);
- emberAfGroupsClusterPrintString(groupName);
- emberAfGroupsClusterPrintln("\"");
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfGroupsClusterPrint("RX: ViewGroupResponse 0x%x, 0x%2x, \"", status, groupId);
+ emberAfGroupsClusterPrintString(groupName);
+ emberAfGroupsClusterPrintln("\"");
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
-bool emberAfGroupsClusterGetGroupMembershipResponseCallback(uint8_t capacity,
- uint8_t groupCount,
- uint8_t* groupList)
+bool emberAfGroupsClusterGetGroupMembershipResponseCallback(uint8_t capacity, uint8_t groupCount, uint8_t * groupList)
{
- uint8_t i;
- emberAfGroupsClusterPrint("RX: GetGroupMembershipResponse 0x%x, 0x%x,",
- capacity,
- groupCount);
- for (i = 0; i < groupCount; i++) {
- emberAfGroupsClusterPrint(" [0x%2x]",
- emberAfGetInt16u(groupList + (i << 1), 0, 2));
- }
- emberAfGroupsClusterPrintln("");
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ uint8_t i;
+ emberAfGroupsClusterPrint("RX: GetGroupMembershipResponse 0x%x, 0x%x,", capacity, groupCount);
+ for (i = 0; i < groupCount; i++)
+ {
+ emberAfGroupsClusterPrint(" [0x%2x]", emberAfGetInt16u(groupList + (i << 1), 0, 2));
+ }
+ emberAfGroupsClusterPrintln("");
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
-bool emberAfGroupsClusterRemoveGroupResponseCallback(uint8_t status,
- uint16_t groupId)
+bool emberAfGroupsClusterRemoveGroupResponseCallback(uint8_t status, uint16_t groupId)
{
- emberAfGroupsClusterPrintln("RX: RemoveGroupResponse 0x%x, 0x%2x",
- status,
- groupId);
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfGroupsClusterPrintln("RX: RemoveGroupResponse 0x%x, 0x%2x", status, groupId);
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
diff --git a/src/app/clusters/groups-server/groups-server-cli.c b/src/app/clusters/groups-server/groups-server-cli.c
index 19a3916..42c52e5 100644
--- a/src/app/clusters/groups-server/groups-server-cli.c
+++ b/src/app/clusters/groups-server/groups-server-cli.c
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the Groups Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
#include "app/util/serial/command-interpreter2.h"
@@ -45,31 +45,32 @@
#if !defined(EMBER_AF_GENERATE_CLI)
EmberCommandEntry emberAfPluginGroupsServerCommands[] = {
- emberCommandEntryAction("print", emAfGroupsServerCliPrint, "", "Print the state of the groups table."),
- emberCommandEntryAction("clear", emAfGroupsServerCliClear, "", "Clear the groups table on every endpoint."),
- emberCommandEntryTerminator(),
+ emberCommandEntryAction("print", emAfGroupsServerCliPrint, "", "Print the state of the groups table."),
+ emberCommandEntryAction("clear", emAfGroupsServerCliClear, "", "Clear the groups table on every endpoint."),
+ emberCommandEntryTerminator(),
};
#endif // EMBER_AF_GENERATE_CLI
// plugin groups-server print
void emAfGroupsServerCliPrint(void)
{
- EmberStatus status;
- uint8_t i;
+ EmberStatus status;
+ uint8_t i;
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- EmberBindingTableEntry entry;
- status = emberGetBinding(i, &entry);
- if ((status == EMBER_SUCCESS) && (entry.type == EMBER_MULTICAST_BINDING)) {
- emberAfCorePrintln("ep[%x] id[%2x]", entry.local,
- HIGH_LOW_TO_INT(entry.identifier[1], entry.identifier[0]));
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ EmberBindingTableEntry entry;
+ status = emberGetBinding(i, &entry);
+ if ((status == EMBER_SUCCESS) && (entry.type == EMBER_MULTICAST_BINDING))
+ {
+ emberAfCorePrintln("ep[%x] id[%2x]", entry.local, HIGH_LOW_TO_INT(entry.identifier[1], entry.identifier[0]));
+ }
}
- }
}
// plugin groups-server clear
void emAfGroupsServerCliClear(void)
{
- emberAfCorePrintln("Clearing all groups.");
- emberAfGroupsClusterClearGroupTableCallback(EMBER_BROADCAST_ENDPOINT);
+ emberAfCorePrintln("Clearing all groups.");
+ emberAfGroupsClusterClearGroupTableCallback(EMBER_BROADCAST_ENDPOINT);
}
diff --git a/src/app/clusters/groups-server/groups-server.c b/src/app/clusters/groups-server/groups-server.c
index 9f868c7..72b4dbd 100644
--- a/src/app/clusters/groups-server/groups-server.c
+++ b/src/app/clusters/groups-server/groups-server.c
@@ -31,12 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Groups Server plugin, the server implementation of
- * the Groups cluster.
+ * @brief Routines for the Groups Server plugin, the
+ *server implementation of the Groups cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// *******************************************************************
// * groups-server.c
@@ -49,27 +49,22 @@
static bool isGroupPresent(uint8_t endpoint, uint16_t groupId);
-static bool bindingGroupMatch(uint8_t endpoint,
- uint16_t groupId,
- EmberBindingTableEntry *entry);
+static bool bindingGroupMatch(uint8_t endpoint, uint16_t groupId, EmberBindingTableEntry * entry);
static uint8_t findGroupIndex(uint8_t endpoint, uint16_t groupId);
void emberAfGroupsClusterServerInitCallback(uint8_t endpoint)
{
- // The high bit of Name Support indicates whether group names are supported.
- // Group names are not supported by this plugin.
- EmberAfStatus status;
- uint8_t nameSupport = (uint8_t) emberAfPluginGroupsServerGroupNamesSupportedCallback(endpoint);
- status = emberAfWriteAttribute(endpoint,
- ZCL_GROUPS_CLUSTER_ID,
- ZCL_GROUP_NAME_SUPPORT_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&nameSupport,
- ZCL_BITMAP8_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfGroupsClusterPrintln("ERR: writing name support %x", status);
- }
+ // The high bit of Name Support indicates whether group names are supported.
+ // Group names are not supported by this plugin.
+ EmberAfStatus status;
+ uint8_t nameSupport = (uint8_t) emberAfPluginGroupsServerGroupNamesSupportedCallback(endpoint);
+ status = emberAfWriteAttribute(endpoint, ZCL_GROUPS_CLUSTER_ID, ZCL_GROUP_NAME_SUPPORT_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ (uint8_t *) &nameSupport, ZCL_BITMAP8_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfGroupsClusterPrintln("ERR: writing name support %x", status);
+ }
}
// --------------------------
@@ -80,377 +75,370 @@
// The first two bytes of the identifier is set to the groupId
// The local endpoint is set to the endpoint that is mapped to this group
// --------------------------
-static EmberAfStatus addEntryToGroupTable(uint8_t endpoint, uint16_t groupId, uint8_t *groupName)
+static EmberAfStatus addEntryToGroupTable(uint8_t endpoint, uint16_t groupId, uint8_t * groupName)
{
- uint8_t i;
+ uint8_t i;
- // Check for duplicates.
- if (isGroupPresent(endpoint, groupId)) {
- // Even if the group already exists, tell the application about the name,
- // so it can cope with renames.
- emberAfPluginGroupsServerSetGroupNameCallback(endpoint,
- groupId,
- groupName);
- return EMBER_ZCL_STATUS_DUPLICATE_EXISTS;
- }
-
- // Look for an empty binding slot.
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- EmberBindingTableEntry binding;
- if (emberGetBinding(i, &binding) == EMBER_SUCCESS
- && binding.type == EMBER_UNUSED_BINDING) {
- EmberStatus status;
- binding.type = EMBER_MULTICAST_BINDING;
- binding.identifier[0] = LOW_BYTE(groupId);
- binding.identifier[1] = HIGH_BYTE(groupId);
- binding.local = endpoint;
-
- status = emberSetBinding(i, &binding);
- if (status == EMBER_SUCCESS) {
- // Set the group name, if supported
- emberAfPluginGroupsServerSetGroupNameCallback(endpoint,
- groupId,
- groupName);
- return EMBER_ZCL_STATUS_SUCCESS;
- } else {
- emberAfGroupsClusterPrintln("ERR: Failed to create binding (0x%x)",
- status);
- }
+ // Check for duplicates.
+ if (isGroupPresent(endpoint, groupId))
+ {
+ // Even if the group already exists, tell the application about the name,
+ // so it can cope with renames.
+ emberAfPluginGroupsServerSetGroupNameCallback(endpoint, groupId, groupName);
+ return EMBER_ZCL_STATUS_DUPLICATE_EXISTS;
}
- }
- emberAfGroupsClusterPrintln("ERR: Binding table is full");
- return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
+
+ // Look for an empty binding slot.
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ EmberBindingTableEntry binding;
+ if (emberGetBinding(i, &binding) == EMBER_SUCCESS && binding.type == EMBER_UNUSED_BINDING)
+ {
+ EmberStatus status;
+ binding.type = EMBER_MULTICAST_BINDING;
+ binding.identifier[0] = LOW_BYTE(groupId);
+ binding.identifier[1] = HIGH_BYTE(groupId);
+ binding.local = endpoint;
+
+ status = emberSetBinding(i, &binding);
+ if (status == EMBER_SUCCESS)
+ {
+ // Set the group name, if supported
+ emberAfPluginGroupsServerSetGroupNameCallback(endpoint, groupId, groupName);
+ return EMBER_ZCL_STATUS_SUCCESS;
+ }
+ else
+ {
+ emberAfGroupsClusterPrintln("ERR: Failed to create binding (0x%x)", status);
+ }
+ }
+ }
+ emberAfGroupsClusterPrintln("ERR: Binding table is full");
+ return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
}
static EmberAfStatus removeEntryFromGroupTable(uint8_t endpoint, uint16_t groupId)
{
- if (isGroupPresent(endpoint, groupId)) {
- uint8_t bindingIndex = findGroupIndex(endpoint, groupId);
- EmberStatus status = emberDeleteBinding(bindingIndex);
- if (status == EMBER_SUCCESS) {
- uint8_t groupName[ZCL_GROUPS_CLUSTER_MAXIMUM_NAME_LENGTH + 1] = { 0 };
- emberAfPluginGroupsServerSetGroupNameCallback(endpoint,
- groupId,
- groupName);
- return EMBER_ZCL_STATUS_SUCCESS;
- } else {
- emberAfGroupsClusterPrintln("ERR: Failed to delete binding (0x%x)",
- status);
- return EMBER_ZCL_STATUS_FAILURE;
+ if (isGroupPresent(endpoint, groupId))
+ {
+ uint8_t bindingIndex = findGroupIndex(endpoint, groupId);
+ EmberStatus status = emberDeleteBinding(bindingIndex);
+ if (status == EMBER_SUCCESS)
+ {
+ uint8_t groupName[ZCL_GROUPS_CLUSTER_MAXIMUM_NAME_LENGTH + 1] = { 0 };
+ emberAfPluginGroupsServerSetGroupNameCallback(endpoint, groupId, groupName);
+ return EMBER_ZCL_STATUS_SUCCESS;
+ }
+ else
+ {
+ emberAfGroupsClusterPrintln("ERR: Failed to delete binding (0x%x)", status);
+ return EMBER_ZCL_STATUS_FAILURE;
+ }
}
- }
- return EMBER_ZCL_STATUS_NOT_FOUND;
+ return EMBER_ZCL_STATUS_NOT_FOUND;
}
-bool emberAfGroupsClusterAddGroupCallback(uint16_t groupId, uint8_t *groupName)
+bool emberAfGroupsClusterAddGroupCallback(uint16_t groupId, uint8_t * groupName)
{
- EmberAfStatus status;
+ EmberAfStatus status;
- emberAfGroupsClusterPrint("RX: AddGroup 0x%2x, \"", groupId);
- emberAfGroupsClusterPrintString(groupName);
- emberAfGroupsClusterPrintln("\"");
+ emberAfGroupsClusterPrint("RX: AddGroup 0x%2x, \"", groupId);
+ emberAfGroupsClusterPrintString(groupName);
+ emberAfGroupsClusterPrintln("\"");
- status = addEntryToGroupTable(emberAfCurrentEndpoint(), groupId, groupName);
+ status = addEntryToGroupTable(emberAfCurrentEndpoint(), groupId, groupName);
- // For all networks, Add Group commands are only responded to when
- // they are addressed to a single device.
- if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST
- && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY) {
+ // For all networks, Add Group commands are only responded to when
+ // they are addressed to a single device.
+ if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
+ {
+ return true;
+ }
+ emberAfFillCommandGroupsClusterAddGroupResponse(status, groupId);
+ emberAfSendResponse();
return true;
- }
- emberAfFillCommandGroupsClusterAddGroupResponse(status, groupId);
- emberAfSendResponse();
- return true;
}
bool emberAfGroupsClusterViewGroupCallback(uint16_t groupId)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
- EmberStatus sendStatus;
- uint8_t groupName[ZCL_GROUPS_CLUSTER_MAXIMUM_NAME_LENGTH + 1] = { 0 };
+ EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
+ EmberStatus sendStatus;
+ uint8_t groupName[ZCL_GROUPS_CLUSTER_MAXIMUM_NAME_LENGTH + 1] = { 0 };
- // Get the group name, if supported
- emberAfPluginGroupsServerGetGroupNameCallback(emberAfCurrentEndpoint(),
- groupId,
- groupName);
+ // Get the group name, if supported
+ emberAfPluginGroupsServerGetGroupNameCallback(emberAfCurrentEndpoint(), groupId, groupName);
- emberAfGroupsClusterPrintln("RX: ViewGroup 0x%2x", groupId);
+ emberAfGroupsClusterPrintln("RX: ViewGroup 0x%2x", groupId);
- // For all networks, View Group commands can only be addressed to a
- // single device.
- if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST
- && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY) {
+ // For all networks, View Group commands can only be addressed to a
+ // single device.
+ if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
+ {
+ return true;
+ }
+
+ if (isGroupPresent(emberAfCurrentEndpoint(), groupId))
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ }
+
+ emberAfFillCommandGroupsClusterViewGroupResponse(status, groupId, groupName);
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfGroupsClusterPrintln("Groups: failed to send %s response: 0x%x", "view_group", sendStatus);
+ }
return true;
- }
-
- if (isGroupPresent(emberAfCurrentEndpoint(), groupId)) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- }
-
- emberAfFillCommandGroupsClusterViewGroupResponse(status, groupId, groupName);
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfGroupsClusterPrintln("Groups: failed to send %s response: 0x%x",
- "view_group",
- sendStatus);
- }
- return true;
}
-bool emberAfGroupsClusterGetGroupMembershipCallback(uint8_t groupCount,
- uint8_t *groupList)
+bool emberAfGroupsClusterGetGroupMembershipCallback(uint8_t groupCount, uint8_t * groupList)
{
- EmberStatus status;
- uint8_t i, j;
- uint8_t count = 0;
- uint8_t list[EMBER_BINDING_TABLE_SIZE << 1];
- uint8_t listLen = 0;
+ EmberStatus status;
+ uint8_t i, j;
+ uint8_t count = 0;
+ uint8_t list[EMBER_BINDING_TABLE_SIZE << 1];
+ uint8_t listLen = 0;
- emberAfGroupsClusterPrint("RX: GetGroupMembership 0x%x,", groupCount);
- for (i = 0; i < groupCount; i++) {
- emberAfGroupsClusterPrint(" [0x%2x]",
- emberAfGetInt16u(groupList + (i << 1), 0, 2));
- }
- emberAfGroupsClusterPrintln("");
-
- // For all networks, Get Group Membership commands may be sent either
- // unicast or broadcast (removing the ZLL-specific limitation to unicast).
-
- // When Group Count is zero, respond with a list of all active groups.
- // Otherwise, respond with a list of matches.
- if (groupCount == 0) {
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- EmberBindingTableEntry entry;
- status = emberGetBinding(i, &entry);
- if ((status == EMBER_SUCCESS)
- && (entry.type == EMBER_MULTICAST_BINDING)
- && (entry.local == emberAfCurrentEndpoint())) {
- list[listLen] = entry.identifier[0];
- list[listLen + 1] = entry.identifier[1];
- listLen += 2;
- count++;
- }
+ emberAfGroupsClusterPrint("RX: GetGroupMembership 0x%x,", groupCount);
+ for (i = 0; i < groupCount; i++)
+ {
+ emberAfGroupsClusterPrint(" [0x%2x]", emberAfGetInt16u(groupList + (i << 1), 0, 2));
}
- } else {
- for (i = 0; i < groupCount; i++) {
- uint16_t groupId = emberAfGetInt16u(groupList + (i << 1), 0, 2);
- for (j = 0; j < EMBER_BINDING_TABLE_SIZE; j++) {
- EmberBindingTableEntry entry;
- status = emberGetBinding(j, &entry);
- if ((status == EMBER_SUCCESS)
- && (entry.type == EMBER_MULTICAST_BINDING)) {
- if (entry.local == emberAfCurrentEndpoint()
- && entry.identifier[0] == LOW_BYTE(groupId)
- && entry.identifier[1] == HIGH_BYTE(groupId)) {
- list[listLen] = entry.identifier[0];
- list[listLen + 1] = entry.identifier[1];
- listLen += 2;
- count++;
- }
+ emberAfGroupsClusterPrintln("");
+
+ // For all networks, Get Group Membership commands may be sent either
+ // unicast or broadcast (removing the ZLL-specific limitation to unicast).
+
+ // When Group Count is zero, respond with a list of all active groups.
+ // Otherwise, respond with a list of matches.
+ if (groupCount == 0)
+ {
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ EmberBindingTableEntry entry;
+ status = emberGetBinding(i, &entry);
+ if ((status == EMBER_SUCCESS) && (entry.type == EMBER_MULTICAST_BINDING) && (entry.local == emberAfCurrentEndpoint()))
+ {
+ list[listLen] = entry.identifier[0];
+ list[listLen + 1] = entry.identifier[1];
+ listLen += 2;
+ count++;
+ }
}
- }
}
- }
+ else
+ {
+ for (i = 0; i < groupCount; i++)
+ {
+ uint16_t groupId = emberAfGetInt16u(groupList + (i << 1), 0, 2);
+ for (j = 0; j < EMBER_BINDING_TABLE_SIZE; j++)
+ {
+ EmberBindingTableEntry entry;
+ status = emberGetBinding(j, &entry);
+ if ((status == EMBER_SUCCESS) && (entry.type == EMBER_MULTICAST_BINDING))
+ {
+ if (entry.local == emberAfCurrentEndpoint() && entry.identifier[0] == LOW_BYTE(groupId) &&
+ entry.identifier[1] == HIGH_BYTE(groupId))
+ {
+ list[listLen] = entry.identifier[0];
+ list[listLen + 1] = entry.identifier[1];
+ listLen += 2;
+ count++;
+ }
+ }
+ }
+ }
+ }
- // Only send a response if the Group Count was zero or if one or more active
- // groups matched. Otherwise, a Default Response is sent.
- if (groupCount == 0 || count != 0) {
- // A capacity of 0xFF means that it is unknown if any further groups may be
- // added. Each group requires a binding and, because the binding table is
- // used for other purposes besides groups, we can't be sure what the
- // capacity will be in the future.
- emberAfFillCommandGroupsClusterGetGroupMembershipResponse(0xFF, // capacity
- count,
- list,
- listLen);
- status = emberAfSendResponse();
- } else {
- status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_NOT_FOUND);
- }
- if (EMBER_SUCCESS != status) {
- emberAfGroupsClusterPrintln("Groups: failed to send %s: 0x%x",
- (groupCount == 0 || count != 0)
- ? "get_group_membership response"
- : "default_response",
- status);
- }
- return true;
+ // Only send a response if the Group Count was zero or if one or more active
+ // groups matched. Otherwise, a Default Response is sent.
+ if (groupCount == 0 || count != 0)
+ {
+ // A capacity of 0xFF means that it is unknown if any further groups may be
+ // added. Each group requires a binding and, because the binding table is
+ // used for other purposes besides groups, we can't be sure what the
+ // capacity will be in the future.
+ emberAfFillCommandGroupsClusterGetGroupMembershipResponse(0xFF, // capacity
+ count, list, listLen);
+ status = emberAfSendResponse();
+ }
+ else
+ {
+ status = emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_NOT_FOUND);
+ }
+ if (EMBER_SUCCESS != status)
+ {
+ emberAfGroupsClusterPrintln("Groups: failed to send %s: 0x%x",
+ (groupCount == 0 || count != 0) ? "get_group_membership response" : "default_response", status);
+ }
+ return true;
}
bool emberAfGroupsClusterRemoveGroupCallback(uint16_t groupId)
{
- EmberAfStatus status;
- EmberStatus sendStatus;
+ EmberAfStatus status;
+ EmberStatus sendStatus;
- emberAfGroupsClusterPrintln("RX: RemoveGroup 0x%2x", groupId);
+ emberAfGroupsClusterPrintln("RX: RemoveGroup 0x%2x", groupId);
- status = removeEntryFromGroupTable(emberAfCurrentEndpoint(),
- groupId);
+ status = removeEntryFromGroupTable(emberAfCurrentEndpoint(), groupId);
- // For all networks, Remove Group commands are only responded to when
- // they are addressed to a single device.
- if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST
- && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY) {
+ // For all networks, Remove Group commands are only responded to when
+ // they are addressed to a single device.
+ if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
+ {
+ return true;
+ }
+
+ // EMAPPFWKV2-1414: if we remove a group, we should remove any scene
+ // associated with it. ZCL6: 3.6.2.3.5: "Note that if a group is
+ // removed the scenes associated with that group SHOULD be removed."
+ emberAfScenesClusterRemoveScenesInGroupCallback(emberAfCurrentEndpoint(), groupId);
+
+ emberAfFillCommandGroupsClusterRemoveGroupResponse(status, groupId);
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfGroupsClusterPrintln("Groups: failed to send %s response: 0x%x", "remove_group", sendStatus);
+ }
return true;
- }
-
- // EMAPPFWKV2-1414: if we remove a group, we should remove any scene
- // associated with it. ZCL6: 3.6.2.3.5: "Note that if a group is
- // removed the scenes associated with that group SHOULD be removed."
- emberAfScenesClusterRemoveScenesInGroupCallback(emberAfCurrentEndpoint(),
- groupId);
-
- emberAfFillCommandGroupsClusterRemoveGroupResponse(status, groupId);
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfGroupsClusterPrintln("Groups: failed to send %s response: 0x%x",
- "remove_group",
- sendStatus);
- }
- return true;
}
bool emberAfGroupsClusterRemoveAllGroupsCallback(void)
{
- EmberStatus sendStatus;
- uint8_t i, endpoint = emberAfCurrentEndpoint();
- bool success = true;
+ EmberStatus sendStatus;
+ uint8_t i, endpoint = emberAfCurrentEndpoint();
+ bool success = true;
- emberAfGroupsClusterPrintln("RX: RemoveAllGroups");
+ emberAfGroupsClusterPrintln("RX: RemoveAllGroups");
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- EmberBindingTableEntry binding;
- if (emberGetBinding(i, &binding) == EMBER_SUCCESS) {
- if (binding.type == EMBER_MULTICAST_BINDING
- && endpoint == binding.local) {
- EmberStatus status = emberDeleteBinding(i);
- if (status != EMBER_SUCCESS) {
- success = false;
- emberAfGroupsClusterPrintln("ERR: Failed to delete binding (0x%x)",
- status);
- } else {
- uint8_t groupName[ZCL_GROUPS_CLUSTER_MAXIMUM_NAME_LENGTH + 1] = { 0 };
- uint16_t groupId = HIGH_LOW_TO_INT(binding.identifier[1],
- binding.identifier[0]);
- emberAfPluginGroupsServerSetGroupNameCallback(endpoint,
- groupId,
- groupName);
- success = true && success;
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ EmberBindingTableEntry binding;
+ if (emberGetBinding(i, &binding) == EMBER_SUCCESS)
+ {
+ if (binding.type == EMBER_MULTICAST_BINDING && endpoint == binding.local)
+ {
+ EmberStatus status = emberDeleteBinding(i);
+ if (status != EMBER_SUCCESS)
+ {
+ success = false;
+ emberAfGroupsClusterPrintln("ERR: Failed to delete binding (0x%x)", status);
+ }
+ else
+ {
+ uint8_t groupName[ZCL_GROUPS_CLUSTER_MAXIMUM_NAME_LENGTH + 1] = { 0 };
+ uint16_t groupId = HIGH_LOW_TO_INT(binding.identifier[1], binding.identifier[0]);
+ emberAfPluginGroupsServerSetGroupNameCallback(endpoint, groupId, groupName);
+ success = true && success;
- // EMAPPFWKV2-1414: if we remove a group, we should remove any scene
- // associated with it. ZCL6: 3.6.2.3.5: "Note that if a group is
- // removed the scenes associated with that group SHOULD be removed."
- emberAfScenesClusterRemoveScenesInGroupCallback(endpoint, groupId);
+ // EMAPPFWKV2-1414: if we remove a group, we should remove any scene
+ // associated with it. ZCL6: 3.6.2.3.5: "Note that if a group is
+ // removed the scenes associated with that group SHOULD be removed."
+ emberAfScenesClusterRemoveScenesInGroupCallback(endpoint, groupId);
+ }
+ }
}
- }
}
- }
- emberAfScenesClusterRemoveScenesInGroupCallback(emberAfCurrentEndpoint(),
- ZCL_SCENES_GLOBAL_SCENE_GROUP_ID);
+ emberAfScenesClusterRemoveScenesInGroupCallback(emberAfCurrentEndpoint(), ZCL_SCENES_GLOBAL_SCENE_GROUP_ID);
- sendStatus = emberAfSendImmediateDefaultResponse(success
- ? EMBER_ZCL_STATUS_SUCCESS
- : EMBER_ZCL_STATUS_FAILURE);
- if (EMBER_SUCCESS != sendStatus) {
- emberAfGroupsClusterPrintln("Groups: failed to send %s: 0x%x",
- "default_response",
- sendStatus);
- }
- return true;
+ sendStatus = emberAfSendImmediateDefaultResponse(success ? EMBER_ZCL_STATUS_SUCCESS : EMBER_ZCL_STATUS_FAILURE);
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfGroupsClusterPrintln("Groups: failed to send %s: 0x%x", "default_response", sendStatus);
+ }
+ return true;
}
-bool emberAfGroupsClusterAddGroupIfIdentifyingCallback(uint16_t groupId,
- uint8_t *groupName)
+bool emberAfGroupsClusterAddGroupIfIdentifyingCallback(uint16_t groupId, uint8_t * groupName)
{
- EmberAfStatus status;
- EmberStatus sendStatus;
+ EmberAfStatus status;
+ EmberStatus sendStatus;
- emberAfGroupsClusterPrint("RX: AddGroupIfIdentifying 0x%2x, \"", groupId);
- emberAfGroupsClusterPrintString(groupName);
- emberAfGroupsClusterPrintln("\"");
+ emberAfGroupsClusterPrint("RX: AddGroupIfIdentifying 0x%2x, \"", groupId);
+ emberAfGroupsClusterPrintString(groupName);
+ emberAfGroupsClusterPrintln("\"");
- if (!emberAfIsDeviceIdentifying(emberAfCurrentEndpoint())) {
- // If not identifying, ignore add group -> success; not a failure.
- status = EMBER_ZCL_STATUS_SUCCESS;
- } else {
- status = addEntryToGroupTable(emberAfCurrentEndpoint(),
- groupId,
- groupName);
- }
+ if (!emberAfIsDeviceIdentifying(emberAfCurrentEndpoint()))
+ {
+ // If not identifying, ignore add group -> success; not a failure.
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = addEntryToGroupTable(emberAfCurrentEndpoint(), groupId, groupName);
+ }
- sendStatus = emberAfSendImmediateDefaultResponse(status);
- if (EMBER_SUCCESS != sendStatus) {
- emberAfGroupsClusterPrintln("Groups: failed to send %s: 0x%x",
- "default_response",
- sendStatus);
- }
- return true;
+ sendStatus = emberAfSendImmediateDefaultResponse(status);
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfGroupsClusterPrintln("Groups: failed to send %s: 0x%x", "default_response", sendStatus);
+ }
+ return true;
}
-bool emberAfGroupsClusterEndpointInGroupCallback(uint8_t endpoint,
- uint16_t groupId)
+bool emberAfGroupsClusterEndpointInGroupCallback(uint8_t endpoint, uint16_t groupId)
{
- return isGroupPresent(endpoint, groupId);
+ return isGroupPresent(endpoint, groupId);
}
void emberAfGroupsClusterClearGroupTableCallback(uint8_t endpoint)
{
- uint8_t i, networkIndex = emberGetCurrentNetwork();
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- EmberBindingTableEntry binding;
- if (emberGetBinding(i, &binding) == EMBER_SUCCESS
- && binding.type == EMBER_MULTICAST_BINDING
- && (endpoint == binding.local
- || (endpoint == EMBER_BROADCAST_ENDPOINT
- && networkIndex == binding.networkIndex))) {
- EmberStatus status = emberDeleteBinding(i);
- if (status != EMBER_SUCCESS) {
- emberAfGroupsClusterPrintln("ERR: Failed to delete binding (0x%x)",
- status);
- }
+ uint8_t i, networkIndex = emberGetCurrentNetwork();
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ EmberBindingTableEntry binding;
+ if (emberGetBinding(i, &binding) == EMBER_SUCCESS && binding.type == EMBER_MULTICAST_BINDING &&
+ (endpoint == binding.local || (endpoint == EMBER_BROADCAST_ENDPOINT && networkIndex == binding.networkIndex)))
+ {
+ EmberStatus status = emberDeleteBinding(i);
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfGroupsClusterPrintln("ERR: Failed to delete binding (0x%x)", status);
+ }
+ }
}
- }
}
static bool isGroupPresent(uint8_t endpoint, uint16_t groupId)
{
- uint8_t i;
+ uint8_t i;
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- EmberBindingTableEntry binding;
- if (emberGetBinding(i, &binding) == EMBER_SUCCESS) {
- if (bindingGroupMatch(endpoint, groupId, &binding)) {
- return true;
- }
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ EmberBindingTableEntry binding;
+ if (emberGetBinding(i, &binding) == EMBER_SUCCESS)
+ {
+ if (bindingGroupMatch(endpoint, groupId, &binding))
+ {
+ return true;
+ }
+ }
}
- }
- return false;
+ return false;
}
-static bool bindingGroupMatch(uint8_t endpoint,
- uint16_t groupId,
- EmberBindingTableEntry *entry)
+static bool bindingGroupMatch(uint8_t endpoint, uint16_t groupId, EmberBindingTableEntry * entry)
{
- return (entry->type == EMBER_MULTICAST_BINDING
- && entry->identifier[0] == LOW_BYTE(groupId)
- && entry->identifier[1] == HIGH_BYTE(groupId)
- && entry->local == endpoint);
+ return (entry->type == EMBER_MULTICAST_BINDING && entry->identifier[0] == LOW_BYTE(groupId) &&
+ entry->identifier[1] == HIGH_BYTE(groupId) && entry->local == endpoint);
}
static uint8_t findGroupIndex(uint8_t endpoint, uint16_t groupId)
{
- EmberStatus status;
- uint8_t i;
+ EmberStatus status;
+ uint8_t i;
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- EmberBindingTableEntry entry;
- status = emberGetBinding(i, &entry);
- if ((status == EMBER_SUCCESS)
- && bindingGroupMatch(endpoint, groupId, &entry)) {
- return i;
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ EmberBindingTableEntry entry;
+ status = emberGetBinding(i, &entry);
+ if ((status == EMBER_SUCCESS) && bindingGroupMatch(endpoint, groupId, &entry))
+ {
+ return i;
+ }
}
- }
- return EMBER_AF_GROUP_TABLE_NULL_INDEX;
+ return EMBER_AF_GROUP_TABLE_NULL_INDEX;
}
diff --git a/src/app/clusters/ias-zone-client/ias-zone-client-cli.c b/src/app/clusters/ias-zone-client/ias-zone-client-cli.c
index 807542d..a18f084 100644
--- a/src/app/clusters/ias-zone-client/ias-zone-client-cli.c
+++ b/src/app/clusters/ias-zone-client/ias-zone-client-cli.c
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the IAS Zone Client plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#include "app/util/serial/command-interpreter2.h"
@@ -49,9 +49,10 @@
#ifndef EMBER_AF_GENERATE_CLI
EmberCommandEntry emberAfPluginIasZoneClientCommands[] = {
- emberCommandEntryAction("print-servers", emAfPluginIasZoneClientPrintServersCommand, "", "Print the known IAS Zone Servers"),
- emberCommandEntryAction("clear-all", emAfPluginIasZoneClientClearAllServersCommand, "", "Clear all known IAS Zone Servers from local device"),
- emberCommandEntryTerminator(),
+ emberCommandEntryAction("print-servers", emAfPluginIasZoneClientPrintServersCommand, "", "Print the known IAS Zone Servers"),
+ emberCommandEntryAction("clear-all", emAfPluginIasZoneClientClearAllServersCommand, "",
+ "Clear all known IAS Zone Servers from local device"),
+ emberCommandEntryTerminator(),
};
#endif // EMBER_AF_GENERATE_CLI
@@ -60,39 +61,37 @@
void emAfPluginIasZoneClientPrintServersCommand(void)
{
- uint8_t i;
- emberAfIasZoneClusterPrintln("Index IEEE EP Type Status State ID");
- emberAfIasZoneClusterPrintln("---------------------------------------------------");
- for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) {
- if (i < 10) {
- emberAfIasZoneClusterPrint(" ");
+ uint8_t i;
+ emberAfIasZoneClusterPrintln("Index IEEE EP Type Status State ID");
+ emberAfIasZoneClusterPrintln("---------------------------------------------------");
+ for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++)
+ {
+ if (i < 10)
+ {
+ emberAfIasZoneClusterPrint(" ");
+ }
+ emberAfIasZoneClusterPrint(
+ "%d (>)%X%X%X%X%X%X%X%X ", i, emberAfIasZoneClientKnownServers[i].ieeeAddress[7],
+ emberAfIasZoneClientKnownServers[i].ieeeAddress[6], emberAfIasZoneClientKnownServers[i].ieeeAddress[5],
+ emberAfIasZoneClientKnownServers[i].ieeeAddress[4], emberAfIasZoneClientKnownServers[i].ieeeAddress[3],
+ emberAfIasZoneClientKnownServers[i].ieeeAddress[2], emberAfIasZoneClientKnownServers[i].ieeeAddress[1],
+ emberAfIasZoneClientKnownServers[i].ieeeAddress[0]);
+ if (emberAfIasZoneClientKnownServers[i].endpoint < 10)
+ {
+ emberAfIasZoneClusterPrint(" ");
+ }
+ if (emberAfIasZoneClientKnownServers[i].endpoint < 100)
+ {
+ emberAfIasZoneClusterPrint(" ");
+ }
+ emberAfIasZoneClusterPrint("%d ", emberAfIasZoneClientKnownServers[i].endpoint);
+ emberAfIasZoneClusterPrintln("0x%2X 0x%2X 0x%X 0x%X", emberAfIasZoneClientKnownServers[i].zoneType,
+ emberAfIasZoneClientKnownServers[i].zoneStatus, emberAfIasZoneClientKnownServers[i].zoneState,
+ emberAfIasZoneClientKnownServers[i].zoneId);
}
- emberAfIasZoneClusterPrint("%d (>)%X%X%X%X%X%X%X%X ",
- i,
- emberAfIasZoneClientKnownServers[i].ieeeAddress[7],
- emberAfIasZoneClientKnownServers[i].ieeeAddress[6],
- emberAfIasZoneClientKnownServers[i].ieeeAddress[5],
- emberAfIasZoneClientKnownServers[i].ieeeAddress[4],
- emberAfIasZoneClientKnownServers[i].ieeeAddress[3],
- emberAfIasZoneClientKnownServers[i].ieeeAddress[2],
- emberAfIasZoneClientKnownServers[i].ieeeAddress[1],
- emberAfIasZoneClientKnownServers[i].ieeeAddress[0]);
- if (emberAfIasZoneClientKnownServers[i].endpoint < 10) {
- emberAfIasZoneClusterPrint(" ");
- }
- if (emberAfIasZoneClientKnownServers[i].endpoint < 100) {
- emberAfIasZoneClusterPrint(" ");
- }
- emberAfIasZoneClusterPrint("%d ", emberAfIasZoneClientKnownServers[i].endpoint);
- emberAfIasZoneClusterPrintln("0x%2X 0x%2X 0x%X 0x%X",
- emberAfIasZoneClientKnownServers[i].zoneType,
- emberAfIasZoneClientKnownServers[i].zoneStatus,
- emberAfIasZoneClientKnownServers[i].zoneState,
- emberAfIasZoneClientKnownServers[i].zoneId);
- }
}
void emAfPluginIasZoneClientClearAllServersCommand(void)
{
- emAfClearServers();
+ emAfClearServers();
}
diff --git a/src/app/clusters/ias-zone-client/ias-zone-client.c b/src/app/clusters/ias-zone-client/ias-zone-client.c
index 1d4b424..6ee951c 100644
--- a/src/app/clusters/ias-zone-client/ias-zone-client.c
+++ b/src/app/clusters/ias-zone-client/ias-zone-client.c
@@ -31,63 +31,73 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief *
* Client Operation:
* 1. Look for ZDO device announce notification.
* 2. Perform ZDO match descriptor on device.
- * 3. If supports IAS Zone Server, Add that server to our known list.
- * Write CIE Address.
- * 4. Read CIE address, verify it is ours. This is done mostly because
- * the test case requires it.
+ * 3. If supports IAS Zone Server, Add that server
+ *to our known list. Write CIE Address.
+ * 4. Read CIE address, verify it is ours. This is
+ *done mostly because the test case requires it.
* 5. Read the IAS Zone Server attributes.
* Record in table.
- * 6. When we get an enroll request, give them our (only) zone ID.
- * 7. When we get a notification, read their attributes.
+ * 6. When we get an enroll request, give them our
+ *(only) zone ID.
+ * 7. When we get a notification, read their
+ *attributes.
*
* Improvements that could be made:
- * Add support for multiple endpoints on server. Most often this is a
- * legacy security system retrofitted with a single ZigBee radio. Therefore
- * each sensor is on a different endpoint. Right now our client only
- * handles a single endpoint per node.
+ * Add support for multiple endpoints on server.
+ *Most often this is a legacy security system
+ *retrofitted with a single ZigBee radio. Therefore
+ * each sensor is on a different endpoint. Right
+ *now our client only handles a single endpoint per
+ *node.
*
- * Integration with Poll Control. When the device boots we should configure
- * its polling to make it possible to read/write its attributes.
+ * Integration with Poll Control. When the device
+ *boots we should configure its polling to make it
+ *possible to read/write its attributes.
*
- * Update the emberAfIasZoneClientKnownServers list when we know a server
- * un-enrolls. Right now, we don't have any way to tell when we don't need
- * to keep track of a server anymore, i.e., when it un-enrolls. Therefore,
- * we could potentially keep adding servers to our known list, and run out
- * of room to add more. Fortunately, we have two things working for us:
- * 1. Servers will most likely stay around in a network. It is unlikely
- * that an IAS Zone Client in production will have to handle 254
- * different servers.
- * 2. If a server un-enrolls and then enrolls again, it will get the same
- * Zone ID and have a spot in the list, since we store servers by
- * long address.
+ * Update the emberAfIasZoneClientKnownServers list
+ *when we know a server un-enrolls. Right now, we
+ *don't have any way to tell when we don't need to
+ *keep track of a server anymore, i.e., when it
+ *un-enrolls. Therefore, we could potentially keep
+ *adding servers to our known list, and run out of
+ *room to add more. Fortunately, we have two things
+ *working for us:
+ * 1. Servers will most likely stay around in a
+ *network. It is unlikely that an IAS Zone Client in
+ *production will have to handle 254 different
+ *servers.
+ * 2. If a server un-enrolls and then enrolls
+ *again, it will get the same Zone ID and have a spot
+ *in the list, since we store servers by long address.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-#include "af.h"
#include "ias-zone-client.h"
+#include "af.h"
//-----------------------------------------------------------------------------
// Globals
IasZoneDevice emberAfIasZoneClientKnownServers[EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES];
-typedef enum {
- IAS_ZONE_CLIENT_STATE_NONE,
- IAS_ZONE_CLIENT_STATE_DISCOVER_ENDPOINT,
- IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS,
- IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS,
- IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES,
+typedef enum
+{
+ IAS_ZONE_CLIENT_STATE_NONE,
+ IAS_ZONE_CLIENT_STATE_DISCOVER_ENDPOINT,
+ IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS,
+ IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS,
+ IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES,
} IasZoneClientState;
static IasZoneClientState iasZoneClientState = IAS_ZONE_CLIENT_STATE_NONE;
-static uint8_t currentIndex = NO_INDEX;
-static uint8_t myEndpoint = 0;
+static uint8_t currentIndex = NO_INDEX;
+static uint8_t myEndpoint = 0;
EmberEventControl emberAfPluginIasZoneClientStateMachineEventControl;
@@ -103,490 +113,493 @@
void emberAfIasZoneClusterClientInitCallback(uint8_t endpoint)
{
- emAfClearServers();
- myEndpoint = endpoint;
- iasClientLoadCommand();
+ emAfClearServers();
+ myEndpoint = endpoint;
+ iasClientLoadCommand();
}
void emAfClearServers(void)
{
- MEMSET(emberAfIasZoneClientKnownServers, 0xFF,
- sizeof(IasZoneDevice)
- * EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES);
+ MEMSET(emberAfIasZoneClientKnownServers, 0xFF, sizeof(IasZoneDevice) * EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES);
}
static void clearState(void)
{
- currentIndex = 0;
- iasZoneClientState = IAS_ZONE_CLIENT_STATE_NONE;
+ currentIndex = 0;
+ iasZoneClientState = IAS_ZONE_CLIENT_STATE_NONE;
}
static void setServerZoneStatus(uint8_t serverIndex, uint16_t zoneStatus)
{
- emberAfIasZoneClientKnownServers[serverIndex].zoneStatus = zoneStatus;
- iasClientSaveCommand();
+ emberAfIasZoneClientKnownServers[serverIndex].zoneStatus = zoneStatus;
+ iasClientSaveCommand();
}
-static void setServerIeee(uint8_t serverIndex, uint8_t* ieeeAddress)
+static void setServerIeee(uint8_t serverIndex, uint8_t * ieeeAddress)
{
- MEMCOPY(emberAfIasZoneClientKnownServers[serverIndex].ieeeAddress, ieeeAddress, EUI64_SIZE);
- iasClientSaveCommand();
+ MEMCOPY(emberAfIasZoneClientKnownServers[serverIndex].ieeeAddress, ieeeAddress, EUI64_SIZE);
+ iasClientSaveCommand();
}
static void clearServerIeee(uint8_t serverIndex)
{
- MEMSET(emberAfIasZoneClientKnownServers[serverIndex].ieeeAddress,
- 0xFF,
- sizeof(IasZoneDevice));
- iasClientSaveCommand();
+ MEMSET(emberAfIasZoneClientKnownServers[serverIndex].ieeeAddress, 0xFF, sizeof(IasZoneDevice));
+ iasClientSaveCommand();
}
static void setServerNodeId(uint8_t serverIndex, EmberNodeId nodeId)
{
- emberAfIasZoneClientKnownServers[serverIndex].nodeId = nodeId;
+ emberAfIasZoneClientKnownServers[serverIndex].nodeId = nodeId;
}
static void clearServerNodeId(uint8_t serverIndex)
{
- emberAfIasZoneClientKnownServers[serverIndex].nodeId = EMBER_NULL_NODE_ID;
+ emberAfIasZoneClientKnownServers[serverIndex].nodeId = EMBER_NULL_NODE_ID;
}
static void setServerZoneState(uint8_t serverIndex, uint8_t zoneState)
{
- emberAfIasZoneClientKnownServers[serverIndex].zoneState = zoneState;
- iasClientSaveCommand();
+ emberAfIasZoneClientKnownServers[serverIndex].zoneState = zoneState;
+ iasClientSaveCommand();
}
static void setServerEndpoint(uint8_t serverIndex, uint8_t endpoint)
{
- emberAfIasZoneClientKnownServers[serverIndex].endpoint = endpoint;
- iasClientSaveCommand();
+ emberAfIasZoneClientKnownServers[serverIndex].endpoint = endpoint;
+ iasClientSaveCommand();
}
static void setServerZoneType(uint8_t serverIndex, uint16_t zoneType)
{
- emberAfIasZoneClientKnownServers[serverIndex].zoneType = zoneType;
- iasClientSaveCommand();
+ emberAfIasZoneClientKnownServers[serverIndex].zoneType = zoneType;
+ iasClientSaveCommand();
}
static void setServerZoneId(uint8_t serverIndex, uint16_t zoneId)
{
- emberAfIasZoneClientKnownServers[serverIndex].zoneId = zoneId;
- iasClientSaveCommand();
+ emberAfIasZoneClientKnownServers[serverIndex].zoneId = zoneId;
+ iasClientSaveCommand();
}
static void setCurrentIndex(uint8_t serverIndex)
{
- currentIndex = serverIndex;
- iasClientSaveCommand();
+ currentIndex = serverIndex;
+ iasClientSaveCommand();
}
static void setIasZoneClientState(uint8_t clientState)
{
- iasZoneClientState = clientState;
- iasClientSaveCommand();
+ iasZoneClientState = clientState;
+ iasClientSaveCommand();
}
static void iasClientSaveCommand(void)
{
#if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST)
- FILE *fp;
- uint16_t i, j;
+ FILE * fp;
+ uint16_t i, j;
- // save zone server list
- fp = fopen("iaszone.txt", "w");
+ // save zone server list
+ fp = fopen("iaszone.txt", "w");
- for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) {
- if (emberAfIasZoneClientKnownServers[i].zoneId != 0xFF) {
- fprintf(fp, "%x %x %x %x %x ", emberAfIasZoneClientKnownServers[i].zoneId,
- emberAfIasZoneClientKnownServers[i].zoneStatus,
- emberAfIasZoneClientKnownServers[i].zoneState,
- emberAfIasZoneClientKnownServers[i].endpoint,
- emberAfIasZoneClientKnownServers[i].zoneType);
- for (j = 0; j < 8; j++) {
- fprintf(fp, "%x ", emberAfIasZoneClientKnownServers[i].ieeeAddress[j]);
- }
+ for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++)
+ {
+ if (emberAfIasZoneClientKnownServers[i].zoneId != 0xFF)
+ {
+ fprintf(fp, "%x %x %x %x %x ", emberAfIasZoneClientKnownServers[i].zoneId,
+ emberAfIasZoneClientKnownServers[i].zoneStatus, emberAfIasZoneClientKnownServers[i].zoneState,
+ emberAfIasZoneClientKnownServers[i].endpoint, emberAfIasZoneClientKnownServers[i].zoneType);
+ for (j = 0; j < 8; j++)
+ {
+ fprintf(fp, "%x ", emberAfIasZoneClientKnownServers[i].ieeeAddress[j]);
+ }
+ }
}
- }
- // Write something to mark the end of the file.
- fprintf(fp, "ff");
- assert(fclose(fp) == 0);
+ // Write something to mark the end of the file.
+ fprintf(fp, "ff");
+ assert(fclose(fp) == 0);
#endif //#if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST)
}
static void iasClientLoadCommand(void)
{
#if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST)
- FILE *fp;
- uint16_t i, j;
+ FILE * fp;
+ uint16_t i, j;
- unsigned int data1, data2, data3, data4, data5;
+ unsigned int data1, data2, data3, data4, data5;
- fp = fopen("iaszone.txt", "r");
+ fp = fopen("iaszone.txt", "r");
- if (!fp) {
- return;
- }
-
- for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) {
- if (feof(fp)) {
- break;
+ if (!fp)
+ {
+ return;
}
- fscanf(fp, "%x ", &data1);
- if (data1 == 0xff) {
- break;
- }
- fscanf(fp,
- "%x %x %x %x ",
- &data2,
- &data3,
- &data4,
- &data5);
- emberAfIasZoneClientKnownServers[i].zoneId = (uint8_t) data1;
- emberAfIasZoneClientKnownServers[i].zoneStatus = (uint16_t) data2;
- emberAfIasZoneClientKnownServers[i].zoneState = (uint8_t) data3;
- emberAfIasZoneClientKnownServers[i].endpoint = (uint8_t) data4;
- emberAfIasZoneClientKnownServers[i].zoneType = (uint16_t) data5;
+ for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++)
+ {
+ if (feof(fp))
+ {
+ break;
+ }
+ fscanf(fp, "%x ", &data1);
+ if (data1 == 0xff)
+ {
+ break;
+ }
+ fscanf(fp, "%x %x %x %x ", &data2, &data3, &data4, &data5);
- for (j = 0; j < 8; j++) {
- fscanf(fp, "%x ", &data1);
- emberAfIasZoneClientKnownServers[i].ieeeAddress[j] = (uint8_t) data1;
+ emberAfIasZoneClientKnownServers[i].zoneId = (uint8_t) data1;
+ emberAfIasZoneClientKnownServers[i].zoneStatus = (uint16_t) data2;
+ emberAfIasZoneClientKnownServers[i].zoneState = (uint8_t) data3;
+ emberAfIasZoneClientKnownServers[i].endpoint = (uint8_t) data4;
+ emberAfIasZoneClientKnownServers[i].zoneType = (uint16_t) data5;
+
+ for (j = 0; j < 8; j++)
+ {
+ fscanf(fp, "%x ", &data1);
+ emberAfIasZoneClientKnownServers[i].ieeeAddress[j] = (uint8_t) data1;
+ }
}
- }
- assert(fclose(fp) == 0);
+ assert(fclose(fp) == 0);
#endif // #if defined(EZSP_HOST) && !defined(EMBER_TEST) && defined(UNIX_HOST)
}
-static uint8_t findIasZoneServerByIeee(uint8_t* ieeeAddress)
+static uint8_t findIasZoneServerByIeee(uint8_t * ieeeAddress)
{
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) {
- if (0 == MEMCOMPARE(ieeeAddress,
- emberAfIasZoneClientKnownServers[i].ieeeAddress,
- EUI64_SIZE)) {
- return i;
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++)
+ {
+ if (0 == MEMCOMPARE(ieeeAddress, emberAfIasZoneClientKnownServers[i].ieeeAddress, EUI64_SIZE))
+ {
+ return i;
+ }
}
- }
- return NO_INDEX;
+ return NO_INDEX;
}
static uint8_t findIasZoneServerByNodeId(EmberNodeId nodeId)
{
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) {
- if (nodeId == emberAfIasZoneClientKnownServers[i].nodeId) {
- return i;
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++)
+ {
+ if (nodeId == emberAfIasZoneClientKnownServers[i].nodeId)
+ {
+ return i;
+ }
}
- }
- // If we didn't find the node ID in the table, see if the stack knows about
- // it.
- EmberEUI64 eui64;
- if (emberLookupEui64ByNodeId(nodeId, eui64) == EMBER_SUCCESS) {
- i = findIasZoneServerByIeee(eui64);
- if (i != NO_INDEX) {
- setServerNodeId(i, nodeId);
+ // If we didn't find the node ID in the table, see if the stack knows about
+ // it.
+ EmberEUI64 eui64;
+ if (emberLookupEui64ByNodeId(nodeId, eui64) == EMBER_SUCCESS)
+ {
+ i = findIasZoneServerByIeee(eui64);
+ if (i != NO_INDEX)
+ {
+ setServerNodeId(i, nodeId);
+ }
}
- }
- return i;
+ return i;
}
-bool emberAfIasZoneClusterZoneStatusChangeNotificationCallback(uint16_t zoneStatus,
- uint8_t extendedStatus,
- uint8_t zoneId,
+bool emberAfIasZoneClusterZoneStatusChangeNotificationCallback(uint16_t zoneStatus, uint8_t extendedStatus, uint8_t zoneId,
uint16_t delay)
{
- uint8_t serverIndex = findIasZoneServerByNodeId(emberAfCurrentCommand()->source);
- uint8_t status = EMBER_ZCL_STATUS_NOT_FOUND;
- if (serverIndex != NO_INDEX) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- setServerZoneStatus(serverIndex, zoneStatus);
+ uint8_t serverIndex = findIasZoneServerByNodeId(emberAfCurrentCommand()->source);
+ uint8_t status = EMBER_ZCL_STATUS_NOT_FOUND;
+ if (serverIndex != NO_INDEX)
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ setServerZoneStatus(serverIndex, zoneStatus);
- emberAfIasZoneClusterPrintln("Zone %d status change, 0x%2X from 0x%2X",
- zoneId,
- zoneStatus,
- emberAfCurrentCommand()->source);
+ emberAfIasZoneClusterPrintln("Zone %d status change, 0x%2X from 0x%2X", zoneId, zoneStatus,
+ emberAfCurrentCommand()->source);
- // The Test case calls for readding attributes after status change.
- // that is silly for the production device.
- // readIasZoneServerAttributes(emberAfCurrentCommand()->source);
- }
- emberAfSendDefaultResponse(emberAfCurrentCommand(), status);
- return true;
+ // The Test case calls for readding attributes after status change.
+ // that is silly for the production device.
+ // readIasZoneServerAttributes(emberAfCurrentCommand()->source);
+ }
+ emberAfSendDefaultResponse(emberAfCurrentCommand(), status);
+ return true;
}
-bool emberAfIasZoneClusterZoneEnrollRequestCallback(uint16_t zoneType,
- uint16_t manufacturerCode)
+bool emberAfIasZoneClusterZoneEnrollRequestCallback(uint16_t zoneType, uint16_t manufacturerCode)
{
- EmberAfIasEnrollResponseCode responseCode = EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_NO_ENROLL_PERMIT;
- uint8_t zoneId = UNKNOWN_ZONE_ID;
- uint8_t serverIndex = findIasZoneServerByNodeId(emberAfCurrentCommand()->source);
- EmberStatus status;
+ EmberAfIasEnrollResponseCode responseCode = EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_NO_ENROLL_PERMIT;
+ uint8_t zoneId = UNKNOWN_ZONE_ID;
+ uint8_t serverIndex = findIasZoneServerByNodeId(emberAfCurrentCommand()->source);
+ EmberStatus status;
- if (serverIndex != NO_INDEX) {
- responseCode = EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS;
- zoneId = serverIndex;
- setServerZoneId(serverIndex, zoneId);
- }
- emberAfFillCommandIasZoneClusterZoneEnrollResponse(responseCode,
- zoneId);
- // Need to send this command with our source EUI because the server will
- // check our EUI64 against his CIE Address to see if we're his CIE.
- emberAfGetCommandApsFrame()->options |= EMBER_APS_OPTION_SOURCE_EUI64;
- status = emberAfSendResponse();
- emberAfCorePrintln("Sent enroll response with responseCode: 0x%X, zoneId: 0x%X, status: 0x%X",
- responseCode,
- zoneId,
- status);
- return true;
+ if (serverIndex != NO_INDEX)
+ {
+ responseCode = EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS;
+ zoneId = serverIndex;
+ setServerZoneId(serverIndex, zoneId);
+ }
+ emberAfFillCommandIasZoneClusterZoneEnrollResponse(responseCode, zoneId);
+ // Need to send this command with our source EUI because the server will
+ // check our EUI64 against his CIE Address to see if we're his CIE.
+ emberAfGetCommandApsFrame()->options |= EMBER_APS_OPTION_SOURCE_EUI64;
+ status = emberAfSendResponse();
+ emberAfCorePrintln("Sent enroll response with responseCode: 0x%X, zoneId: 0x%X, status: 0x%X", responseCode, zoneId, status);
+ return true;
}
void emberAfPluginIasZoneClientStateMachineEventHandler(void)
{
- emberAfIasZoneClusterPrintln("IAS Zone Client Timeout waiting for message response.");
- emberEventControlSetInactive(emberAfPluginIasZoneClientStateMachineEventControl);
- clearState();
+ emberAfIasZoneClusterPrintln("IAS Zone Client Timeout waiting for message response.");
+ emberEventControlSetInactive(emberAfPluginIasZoneClientStateMachineEventControl);
+ clearState();
}
-static uint8_t addServer(EmberNodeId nodeId, uint8_t* ieeeAddress)
+static uint8_t addServer(EmberNodeId nodeId, uint8_t * ieeeAddress)
{
- uint8_t i = findIasZoneServerByIeee(ieeeAddress);
- if (i != NO_INDEX) {
- return i;
- }
-
- for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++) {
- const uint8_t unsetEui64[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
- if (0 == MEMCOMPARE(emberAfIasZoneClientKnownServers[i].ieeeAddress,
- unsetEui64,
- EUI64_SIZE)) {
- setServerIeee(i, ieeeAddress);
- setServerNodeId(i, nodeId);
- setServerEndpoint(i, UNKNOWN_ENDPOINT);
- return i;
+ uint8_t i = findIasZoneServerByIeee(ieeeAddress);
+ if (i != NO_INDEX)
+ {
+ return i;
}
- }
- return NO_INDEX;
+
+ for (i = 0; i < EMBER_AF_PLUGIN_IAS_ZONE_CLIENT_MAX_DEVICES; i++)
+ {
+ const uint8_t unsetEui64[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+ if (0 == MEMCOMPARE(emberAfIasZoneClientKnownServers[i].ieeeAddress, unsetEui64, EUI64_SIZE))
+ {
+ setServerIeee(i, ieeeAddress);
+ setServerNodeId(i, nodeId);
+ setServerEndpoint(i, UNKNOWN_ENDPOINT);
+ return i;
+ }
+ }
+ return NO_INDEX;
}
-static void removeServer(uint8_t* ieeeAddress)
+static void removeServer(uint8_t * ieeeAddress)
{
- uint8_t index = findIasZoneServerByIeee(ieeeAddress);
- clearServerIeee(index);
- clearServerNodeId(index);
+ uint8_t index = findIasZoneServerByIeee(ieeeAddress);
+ clearServerIeee(index);
+ clearServerNodeId(index);
}
static EmberStatus sendCommand(EmberNodeId destAddress)
{
- emberAfSetCommandEndpoints(myEndpoint, emberAfIasZoneClientKnownServers[currentIndex].endpoint);
- EmberStatus status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, destAddress);
- emberAfIasZoneClusterPrintln("Sent IAS Zone Client Command to 0x%2X (%d -> %d) status: 0x%X",
- destAddress,
- myEndpoint,
- emberAfIasZoneClientKnownServers[currentIndex].endpoint,
- status);
- if (status != EMBER_SUCCESS) {
- clearState();
- }
- return status;
+ emberAfSetCommandEndpoints(myEndpoint, emberAfIasZoneClientKnownServers[currentIndex].endpoint);
+ EmberStatus status = emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, destAddress);
+ emberAfIasZoneClusterPrintln("Sent IAS Zone Client Command to 0x%2X (%d -> %d) status: 0x%X", destAddress, myEndpoint,
+ emberAfIasZoneClientKnownServers[currentIndex].endpoint, status);
+ if (status != EMBER_SUCCESS)
+ {
+ clearState();
+ }
+ return status;
}
static void setCieAddress(EmberNodeId destAddress)
{
- uint8_t writeAttributes[] = {
- LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
- HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
- ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE,
- 0, 0, 0, 0, 0, 0, 0, 0, // ieee (filled in later)
- };
- emberAfGetEui64(&writeAttributes[3]);
- emberAfFillCommandGlobalClientToServerWriteAttributes(ZCL_IAS_ZONE_CLUSTER_ID,
- writeAttributes,
- sizeof(writeAttributes));
- emberAfIasZoneClusterPrintln("Writing CIE Address to IAS Zone Server");
- if (EMBER_SUCCESS == sendCommand(destAddress)) {
- setIasZoneClientState(IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS);
- }
-}
-
-static void iasZoneClientServiceDiscoveryCallback(const EmberAfServiceDiscoveryResult* result)
-{
- if (result->status == EMBER_AF_UNICAST_SERVICE_DISCOVERY_COMPLETE_WITH_RESPONSE
- && result->zdoRequestClusterId == MATCH_DESCRIPTORS_REQUEST) {
- const EmberAfEndpointList* endpointList = (const EmberAfEndpointList *)result->responseData;
- if (endpointList->count > 0) {
- setServerEndpoint(currentIndex, endpointList->list[0]);
- emberAfIasZoneClusterPrintln("Device 0x%2X supports IAS Zone Server",
- result->matchAddress);
- setCieAddress(result->matchAddress);
- return;
+ uint8_t writeAttributes[] = {
+ LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
+ HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
+ ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, // ieee (filled in later)
+ };
+ emberAfGetEui64(&writeAttributes[3]);
+ emberAfFillCommandGlobalClientToServerWriteAttributes(ZCL_IAS_ZONE_CLUSTER_ID, writeAttributes, sizeof(writeAttributes));
+ emberAfIasZoneClusterPrintln("Writing CIE Address to IAS Zone Server");
+ if (EMBER_SUCCESS == sendCommand(destAddress))
+ {
+ setIasZoneClientState(IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS);
}
- }
- clearState();
}
-static void checkForIasZoneServer(EmberNodeId emberNodeId, uint8_t* ieeeAddress)
+static void iasZoneClientServiceDiscoveryCallback(const EmberAfServiceDiscoveryResult * result)
{
- uint8_t endpointIndex = emberAfIndexFromEndpoint(myEndpoint);
- uint16_t profileId = emberAfProfileIdFromIndex(endpointIndex);
- uint8_t serverIndex = addServer(emberNodeId, ieeeAddress);
-
- if (serverIndex == NO_INDEX) {
- emberAfIasZoneClusterPrintln("Error: Could not add IAS Zone server.");
- return;
- }
-
- setCurrentIndex(serverIndex);
-
- if (emberAfIasZoneClientKnownServers[serverIndex].endpoint != UNKNOWN_ENDPOINT) {
- // If a remote endpoint that you have already seen announces itself,
- // write your IEEE in them just in case they left and are rejoining. --agkeesle
- // Bug: EMAPPFWKV2-1078
- setCieAddress(emberNodeId);
- emberAfIasZoneClusterPrintln("Node 0x%2X already known to IAS client", emberNodeId);
- return;
- }
-
- EmberStatus status = emberAfFindDevicesByProfileAndCluster(emberNodeId,
- profileId,
- ZCL_IAS_ZONE_CLUSTER_ID,
- true, // server cluster?
- iasZoneClientServiceDiscoveryCallback);
-
- if (status != EMBER_SUCCESS) {
- emberAfIasZoneClusterPrintln("Error: Failed to initiate service discovery for IAS Zone Server 0x%2X", emberNodeId);
+ if (result->status == EMBER_AF_UNICAST_SERVICE_DISCOVERY_COMPLETE_WITH_RESPONSE &&
+ result->zdoRequestClusterId == MATCH_DESCRIPTORS_REQUEST)
+ {
+ const EmberAfEndpointList * endpointList = (const EmberAfEndpointList *) result->responseData;
+ if (endpointList->count > 0)
+ {
+ setServerEndpoint(currentIndex, endpointList->list[0]);
+ emberAfIasZoneClusterPrintln("Device 0x%2X supports IAS Zone Server", result->matchAddress);
+ setCieAddress(result->matchAddress);
+ return;
+ }
+ }
clearState();
- }
}
-void emberAfPluginIasZoneClientZdoMessageReceivedCallback(EmberNodeId emberNodeId,
- EmberApsFrame* apsFrame,
- uint8_t* message,
+static void checkForIasZoneServer(EmberNodeId emberNodeId, uint8_t * ieeeAddress)
+{
+ uint8_t endpointIndex = emberAfIndexFromEndpoint(myEndpoint);
+ uint16_t profileId = emberAfProfileIdFromIndex(endpointIndex);
+ uint8_t serverIndex = addServer(emberNodeId, ieeeAddress);
+
+ if (serverIndex == NO_INDEX)
+ {
+ emberAfIasZoneClusterPrintln("Error: Could not add IAS Zone server.");
+ return;
+ }
+
+ setCurrentIndex(serverIndex);
+
+ if (emberAfIasZoneClientKnownServers[serverIndex].endpoint != UNKNOWN_ENDPOINT)
+ {
+ // If a remote endpoint that you have already seen announces itself,
+ // write your IEEE in them just in case they left and are rejoining. --agkeesle
+ // Bug: EMAPPFWKV2-1078
+ setCieAddress(emberNodeId);
+ emberAfIasZoneClusterPrintln("Node 0x%2X already known to IAS client", emberNodeId);
+ return;
+ }
+
+ EmberStatus status = emberAfFindDevicesByProfileAndCluster(emberNodeId, profileId, ZCL_IAS_ZONE_CLUSTER_ID,
+ true, // server cluster?
+ iasZoneClientServiceDiscoveryCallback);
+
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfIasZoneClusterPrintln("Error: Failed to initiate service discovery for IAS Zone Server 0x%2X", emberNodeId);
+ clearState();
+ }
+}
+
+void emberAfPluginIasZoneClientZdoMessageReceivedCallback(EmberNodeId emberNodeId, EmberApsFrame * apsFrame, uint8_t * message,
uint16_t length)
{
- emberAfIasZoneClusterPrintln("Incoming ZDO, Cluster: 0x%2X", apsFrame->clusterId);
- if (apsFrame->clusterId == END_DEVICE_ANNOUNCE) {
- checkForIasZoneServer(emberNodeId, &(message[3]));
- }
+ emberAfIasZoneClusterPrintln("Incoming ZDO, Cluster: 0x%2X", apsFrame->clusterId);
+ if (apsFrame->clusterId == END_DEVICE_ANNOUNCE)
+ {
+ checkForIasZoneServer(emberNodeId, &(message[3]));
+ }
}
void readIasZoneServerAttributes(EmberNodeId nodeId)
{
- uint8_t iasZoneAttributeIds[] = {
- LOW_BYTE(ZCL_ZONE_STATE_ATTRIBUTE_ID),
- HIGH_BYTE(ZCL_ZONE_STATE_ATTRIBUTE_ID),
+ uint8_t iasZoneAttributeIds[] = {
+ LOW_BYTE(ZCL_ZONE_STATE_ATTRIBUTE_ID), HIGH_BYTE(ZCL_ZONE_STATE_ATTRIBUTE_ID),
- LOW_BYTE(ZCL_ZONE_TYPE_ATTRIBUTE_ID),
- HIGH_BYTE(ZCL_ZONE_TYPE_ATTRIBUTE_ID),
+ LOW_BYTE(ZCL_ZONE_TYPE_ATTRIBUTE_ID), HIGH_BYTE(ZCL_ZONE_TYPE_ATTRIBUTE_ID),
- LOW_BYTE(ZCL_ZONE_STATUS_ATTRIBUTE_ID),
- HIGH_BYTE(ZCL_ZONE_STATUS_ATTRIBUTE_ID),
- };
- emberAfFillCommandGlobalClientToServerReadAttributes(ZCL_IAS_ZONE_CLUSTER_ID,
- iasZoneAttributeIds,
- sizeof(iasZoneAttributeIds));
- if (EMBER_SUCCESS == sendCommand(nodeId)) {
- setIasZoneClientState(IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES);
- }
+ LOW_BYTE(ZCL_ZONE_STATUS_ATTRIBUTE_ID), HIGH_BYTE(ZCL_ZONE_STATUS_ATTRIBUTE_ID),
+ };
+ emberAfFillCommandGlobalClientToServerReadAttributes(ZCL_IAS_ZONE_CLUSTER_ID, iasZoneAttributeIds, sizeof(iasZoneAttributeIds));
+ if (EMBER_SUCCESS == sendCommand(nodeId))
+ {
+ setIasZoneClientState(IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES);
+ }
}
void readIasZoneServerCieAddress(EmberNodeId nodeId)
{
- uint8_t iasZoneAttributeIds[] = {
- LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
- HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
- };
- emberAfFillCommandGlobalClientToServerReadAttributes(ZCL_IAS_ZONE_CLUSTER_ID,
- iasZoneAttributeIds,
- sizeof(iasZoneAttributeIds));
- if (EMBER_SUCCESS == sendCommand(nodeId)) {
- setIasZoneClientState(IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS);
- }
-}
-
-void emberAfPluginIasZoneClientWriteAttributesResponseCallback(EmberAfClusterId clusterId,
- uint8_t * buffer,
- uint16_t bufLen)
-{
- if (clusterId == ZCL_IAS_ZONE_CLUSTER_ID
- && iasZoneClientState == IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS
- && buffer[0] == EMBER_ZCL_STATUS_SUCCESS) {
- readIasZoneServerCieAddress(emberAfCurrentCommand()->source);
- return;
- }
- return;
-}
-
-void emberAfPluginIasZoneClientReadAttributesResponseCallback(EmberAfClusterId clusterId,
- uint8_t * buffer,
- uint16_t bufLen)
-{
- uint8_t zoneStatus, zoneType, zoneState;
- if (clusterId == ZCL_IAS_ZONE_CLUSTER_ID
- && (iasZoneClientState == IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES
- || iasZoneClientState == IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS)) {
- uint16_t i = 0;
- while ((i + 3) <= bufLen) { // 3 to insure we can read at least the attribute ID
- // and the status
- uint16_t attributeId = buffer[i] + (buffer[i + 1] << 8);
- uint8_t status = buffer[i + 2];
- i += 3;
- //emberAfIasZoneClusterPrintln("Parsing Attribute 0x%2X, Status: 0x%X", attributeId, status);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- if ((i + 1) > bufLen) {
- // Too short, dump the message.
- return;
- }
- i++; // skip the type of the attribute. We already know what it should be.
- switch (attributeId) {
- case ZCL_ZONE_STATUS_ATTRIBUTE_ID:
- if ((i + 2) > bufLen) {
- // Too short, dump the message.
- return;
- }
- zoneStatus = (buffer[i] + (buffer[i + 1] << 8));
- setServerZoneStatus(currentIndex, zoneStatus);
- i += 2;
- break;
- case ZCL_ZONE_TYPE_ATTRIBUTE_ID:
- if ((i + 2) > bufLen) {
- // Too short, dump the message.
- return;
- }
- zoneType = (buffer[i] + (buffer[i + 1] << 8));
- setServerZoneType(currentIndex, zoneType);
- i += 2;
- break;
- case ZCL_ZONE_STATE_ATTRIBUTE_ID:
- if ((i + 1) > bufLen) {
- // Too short, dump the message
- return;
- }
- zoneState = buffer[i];
- setServerZoneState(currentIndex, zoneState);
- i++;
- break;
- case ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID: {
- uint8_t myIeee[EUI64_SIZE];
- emberAfGetEui64(myIeee);
- if ((i + 8) > bufLen) {
- // Too short, dump the message
- } else if (0 != MEMCOMPARE(&(buffer[i]), myIeee, EUI64_SIZE)) {
- emberAfIasZoneClusterPrintln("CIE Address not set to mine, removing IAS zone server.");
- removeServer(&(buffer[i]));
- clearState();
- } else {
- readIasZoneServerAttributes(emberAfCurrentCommand()->source);
- }
- return;
- }
- }
- }
+ uint8_t iasZoneAttributeIds[] = {
+ LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
+ HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID),
+ };
+ emberAfFillCommandGlobalClientToServerReadAttributes(ZCL_IAS_ZONE_CLUSTER_ID, iasZoneAttributeIds, sizeof(iasZoneAttributeIds));
+ if (EMBER_SUCCESS == sendCommand(nodeId))
+ {
+ setIasZoneClientState(IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS);
}
- emberAfIasZoneClusterPrintln("Retrieved IAS Zone Server attributes from 0x%2X",
- emberAfCurrentCommand()->source);
- clearState();
- }
+}
+
+void emberAfPluginIasZoneClientWriteAttributesResponseCallback(EmberAfClusterId clusterId, uint8_t * buffer, uint16_t bufLen)
+{
+ if (clusterId == ZCL_IAS_ZONE_CLUSTER_ID && iasZoneClientState == IAS_ZONE_CLIENT_STATE_SET_CIE_ADDRESS &&
+ buffer[0] == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ readIasZoneServerCieAddress(emberAfCurrentCommand()->source);
+ return;
+ }
+ return;
+}
+
+void emberAfPluginIasZoneClientReadAttributesResponseCallback(EmberAfClusterId clusterId, uint8_t * buffer, uint16_t bufLen)
+{
+ uint8_t zoneStatus, zoneType, zoneState;
+ if (clusterId == ZCL_IAS_ZONE_CLUSTER_ID &&
+ (iasZoneClientState == IAS_ZONE_CLIENT_STATE_READ_ATTRIBUTES ||
+ iasZoneClientState == IAS_ZONE_CLIENT_STATE_READ_CIE_ADDRESS))
+ {
+ uint16_t i = 0;
+ while ((i + 3) <= bufLen)
+ { // 3 to insure we can read at least the attribute ID
+ // and the status
+ uint16_t attributeId = buffer[i] + (buffer[i + 1] << 8);
+ uint8_t status = buffer[i + 2];
+ i += 3;
+ // emberAfIasZoneClusterPrintln("Parsing Attribute 0x%2X, Status: 0x%X", attributeId, status);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ if ((i + 1) > bufLen)
+ {
+ // Too short, dump the message.
+ return;
+ }
+ i++; // skip the type of the attribute. We already know what it should be.
+ switch (attributeId)
+ {
+ case ZCL_ZONE_STATUS_ATTRIBUTE_ID:
+ if ((i + 2) > bufLen)
+ {
+ // Too short, dump the message.
+ return;
+ }
+ zoneStatus = (buffer[i] + (buffer[i + 1] << 8));
+ setServerZoneStatus(currentIndex, zoneStatus);
+ i += 2;
+ break;
+ case ZCL_ZONE_TYPE_ATTRIBUTE_ID:
+ if ((i + 2) > bufLen)
+ {
+ // Too short, dump the message.
+ return;
+ }
+ zoneType = (buffer[i] + (buffer[i + 1] << 8));
+ setServerZoneType(currentIndex, zoneType);
+ i += 2;
+ break;
+ case ZCL_ZONE_STATE_ATTRIBUTE_ID:
+ if ((i + 1) > bufLen)
+ {
+ // Too short, dump the message
+ return;
+ }
+ zoneState = buffer[i];
+ setServerZoneState(currentIndex, zoneState);
+ i++;
+ break;
+ case ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID: {
+ uint8_t myIeee[EUI64_SIZE];
+ emberAfGetEui64(myIeee);
+ if ((i + 8) > bufLen)
+ {
+ // Too short, dump the message
+ }
+ else if (0 != MEMCOMPARE(&(buffer[i]), myIeee, EUI64_SIZE))
+ {
+ emberAfIasZoneClusterPrintln("CIE Address not set to mine, removing IAS zone server.");
+ removeServer(&(buffer[i]));
+ clearState();
+ }
+ else
+ {
+ readIasZoneServerAttributes(emberAfCurrentCommand()->source);
+ }
+ return;
+ }
+ }
+ }
+ }
+ emberAfIasZoneClusterPrintln("Retrieved IAS Zone Server attributes from 0x%2X", emberAfCurrentCommand()->source);
+ clearState();
+ }
}
diff --git a/src/app/clusters/ias-zone-client/ias-zone-client.h b/src/app/clusters/ias-zone-client/ias-zone-client.h
index a500eea..7a14dc5 100644
--- a/src/app/clusters/ias-zone-client/ias-zone-client.h
+++ b/src/app/clusters/ias-zone-client/ias-zone-client.h
@@ -31,21 +31,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief APIs and defines for the IAS Zone Client plugin, which keeps track of
- * IAS Zone servers.
+ * @brief APIs and defines for the IAS Zone Client
+ *plugin, which keeps track of IAS Zone servers.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-typedef struct {
- EmberEUI64 ieeeAddress;
- EmberNodeId nodeId;
- uint16_t zoneType;
- uint16_t zoneStatus;
- uint8_t zoneState;
- uint8_t endpoint;
- uint8_t zoneId;
+typedef struct
+{
+ EmberEUI64 ieeeAddress;
+ EmberNodeId nodeId;
+ uint16_t zoneType;
+ uint16_t zoneStatus;
+ uint8_t zoneState;
+ uint8_t endpoint;
+ uint8_t zoneId;
} IasZoneDevice;
extern IasZoneDevice emberAfIasZoneClientKnownServers[];
@@ -57,15 +58,8 @@
void emAfClearServers(void);
-void emberAfPluginIasZoneClientZdoCallback(EmberNodeId emberNodeId,
- EmberApsFrame* apsFrame,
- uint8_t* message,
- uint16_t length);
+void emberAfPluginIasZoneClientZdoCallback(EmberNodeId emberNodeId, EmberApsFrame * apsFrame, uint8_t * message, uint16_t length);
-void emberAfPluginIasZoneClientWriteAttributesResponseCallback(EmberAfClusterId clusterId,
- uint8_t * buffer,
- uint16_t bufLen);
+void emberAfPluginIasZoneClientWriteAttributesResponseCallback(EmberAfClusterId clusterId, uint8_t * buffer, uint16_t bufLen);
-void emberAfPluginIasZoneClientReadAttributesResponseCallback(EmberAfClusterId clusterId,
- uint8_t * buffer,
- uint16_t bufLen);
+void emberAfPluginIasZoneClientReadAttributesResponseCallback(EmberAfClusterId clusterId, uint8_t * buffer, uint16_t bufLen);
diff --git a/src/app/clusters/ias-zone-server/ias-zone-server-cli.c b/src/app/clusters/ias-zone-server/ias-zone-server-cli.c
index ea2fcb6..61671e2 100644
--- a/src/app/clusters/ias-zone-server/ias-zone-server-cli.c
+++ b/src/app/clusters/ias-zone-server/ias-zone-server-cli.c
@@ -31,12 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief This is the source for the command line interface used for the ias zone
- * server plugin.
+ * @brief This is the source for the command line
+ *interface used for the ias zone server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#include "ias-zone-server.h"
@@ -46,52 +46,44 @@
#define RESERVED_END 0x7FFF
#define MANUFACTURER_SPECIFIC_START 0x8000
-#define MANUFACTURER_SPECIFIC_END 0xFFFE
+#define MANUFACTURER_SPECIFIC_END 0xFFFE
void emberAfPluginIasZoneServerInfoCommand(void);
void emberAfPluginIasZoneServerChangeStatusCommand(void);
void emberAfPluginIasZoneServerSetEnrollmentMethodCommand(void);
-static const char* infoArguments[] = {
- "endpoint",
- NULL,
+static const char * infoArguments[] = {
+ "endpoint",
+ NULL,
};
-static const char* changeStatusArguments[] = {
- "new-status",
- "time-since-occurred-seconds",
- "endpoint",
- NULL,
+static const char * changeStatusArguments[] = {
+ "new-status",
+ "time-since-occurred-seconds",
+ "endpoint",
+ NULL,
};
-static const char* setEnrollmentModeArguments[] = {
- "endpoint",
- "enrollmentMode",
- NULL,
+static const char * setEnrollmentModeArguments[] = {
+ "endpoint",
+ "enrollmentMode",
+ NULL,
};
EmberCommandEntry emberAfPluginIasZoneServerCommands[] = {
- emberCommandEntryActionWithDetails("info",
- emberAfPluginIasZoneServerInfoCommand,
- "",
- "Print IAS Zone information",
- infoArguments),
- emberCommandEntryActionWithDetails("change-status",
- emberAfPluginIasZoneServerChangeStatusCommand,
- "vu",
- "Change the current Zone Status",
- changeStatusArguments),
- emberCommandEntryActionWithDetails("set-enrollment-mode",
- emberAfPluginIasZoneServerSetEnrollmentMethodCommand,
- "uu",
- "Change the current enrollment method",
- setEnrollmentModeArguments),
- emberCommandEntryTerminator(),
+ emberCommandEntryActionWithDetails("info", emberAfPluginIasZoneServerInfoCommand, "", "Print IAS Zone information",
+ infoArguments),
+ emberCommandEntryActionWithDetails("change-status", emberAfPluginIasZoneServerChangeStatusCommand, "vu",
+ "Change the current Zone Status", changeStatusArguments),
+ emberCommandEntryActionWithDetails("set-enrollment-mode", emberAfPluginIasZoneServerSetEnrollmentMethodCommand, "uu",
+ "Change the current enrollment method", setEnrollmentModeArguments),
+ emberCommandEntryTerminator(),
};
-typedef struct {
- uint16_t zoneType;
- const char* zoneTypeString;
+typedef struct
+{
+ uint16_t zoneType;
+ const char * zoneTypeString;
} ZoneTypeToStringMap;
// These functions and variables are only used to generate strings used with
@@ -100,184 +92,155 @@
// declared but never referenced" warnings
#if defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IAS_ZONE_CLUSTER)
static ZoneTypeToStringMap zoneTypeToStringMap[] = {
- { 0x0000, "Standard CIE" },
- { 0x000d, "Motion Sensor" },
- { 0x0015, "Contact Switch" },
- { 0x0028, "Fire Sensor" },
- { 0x002a, "Water Sensor" },
- { 0x002b, "Gas Sensor" },
- { 0x002c, "Peersonal Emergency Device" },
- { 0x002d, "Vibration / Movement Sensor" },
- { 0x010f, "Remote Control" },
- { 0x0115, "Key Fob" },
- { 0x021d, "Keypad" },
- { 0x0225, "Standard Warning Device" },
- { 0xFFFF, NULL } // terminator
+ { 0x0000, "Standard CIE" },
+ { 0x000d, "Motion Sensor" },
+ { 0x0015, "Contact Switch" },
+ { 0x0028, "Fire Sensor" },
+ { 0x002a, "Water Sensor" },
+ { 0x002b, "Gas Sensor" },
+ { 0x002c, "Peersonal Emergency Device" },
+ { 0x002d, "Vibration / Movement Sensor" },
+ { 0x010f, "Remote Control" },
+ { 0x0115, "Key Fob" },
+ { 0x021d, "Keypad" },
+ { 0x0225, "Standard Warning Device" },
+ { 0xFFFF, NULL } // terminator
};
static const char manufacturerSpecificString[] = "Manufacturer Specific";
-static const char invalidZoneTypeString[] = "Invalid";
-static const char reservedString[] = "Reserved";
+static const char invalidZoneTypeString[] = "Invalid";
+static const char reservedString[] = "Reserved";
-static const char notEnrolledString[] = "NOT Enrolled";
-static const char enrolledString[] = "Enrolled";
+static const char notEnrolledString[] = "NOT Enrolled";
+static const char enrolledString[] = "Enrolled";
static const char unknownZoneStateString[] = "Unknown";
//-----------------------------------------------------------------------------
// Functions
-static const char* getZoneTypeString(uint16_t type)
+static const char * getZoneTypeString(uint16_t type)
{
- uint16_t i = 0;
- while (zoneTypeToStringMap[i].zoneTypeString != NULL) {
- if (zoneTypeToStringMap[i].zoneType == type) {
- return zoneTypeToStringMap[i].zoneTypeString;
+ uint16_t i = 0;
+ while (zoneTypeToStringMap[i].zoneTypeString != NULL)
+ {
+ if (zoneTypeToStringMap[i].zoneType == type)
+ {
+ return zoneTypeToStringMap[i].zoneTypeString;
+ }
+ i++;
}
- i++;
- }
- if (type <= RESERVED_END) {
- return reservedString;
- }
+ if (type <= RESERVED_END)
+ {
+ return reservedString;
+ }
- if (type >= MANUFACTURER_SPECIFIC_START
- && type <= MANUFACTURER_SPECIFIC_END) {
- return manufacturerSpecificString;
- }
+ if (type >= MANUFACTURER_SPECIFIC_START && type <= MANUFACTURER_SPECIFIC_END)
+ {
+ return manufacturerSpecificString;
+ }
- return invalidZoneTypeString;
+ return invalidZoneTypeString;
}
-static const char* getZoneStateString(uint8_t zoneState)
+static const char * getZoneStateString(uint8_t zoneState)
{
- switch (zoneState) {
+ switch (zoneState)
+ {
case EMBER_ZCL_IAS_ZONE_STATE_ENROLLED:
- return enrolledString;
+ return enrolledString;
case EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED:
- return notEnrolledString;
- }
- return unknownZoneStateString;
+ return notEnrolledString;
+ }
+ return unknownZoneStateString;
}
-#endif //defined(EMBER_AF_PRINT_ENABLE)
+#endif // defined(EMBER_AF_PRINT_ENABLE)
//&& defined(EMBER_AF_PRINT_IAS_ZONE_CLUSTER)
-static void getAttributes(uint8_t* returnCieAddress,
- uint16_t* returnZoneStatus,
- uint16_t* returnZoneType,
- uint8_t* returnZoneState,
- uint8_t endpoint)
+static void getAttributes(uint8_t * returnCieAddress, uint16_t * returnZoneStatus, uint16_t * returnZoneType,
+ uint8_t * returnZoneState, uint8_t endpoint)
{
- EMBER_TEST_ASSERT(endpoint != EM_AF_UNKNOWN_ENDPOINT);
+ EMBER_TEST_ASSERT(endpoint != EM_AF_UNKNOWN_ENDPOINT);
- emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID,
- returnCieAddress,
- EUI64_SIZE);
+ emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, returnCieAddress, EUI64_SIZE);
- emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_STATUS_ATTRIBUTE_ID,
- (uint8_t*)returnZoneStatus,
- 2); // uint16_t size
+ emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_STATUS_ATTRIBUTE_ID, (uint8_t *) returnZoneStatus,
+ 2); // uint16_t size
- emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_TYPE_ATTRIBUTE_ID,
- (uint8_t*)returnZoneType,
- 2); // uint16_t size
+ emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_TYPE_ATTRIBUTE_ID, (uint8_t *) returnZoneType,
+ 2); // uint16_t size
- emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_STATE_ATTRIBUTE_ID,
- (uint8_t*)returnZoneState,
- 1); // uint8_t size
+ emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_STATE_ATTRIBUTE_ID, (uint8_t *) returnZoneState,
+ 1); // uint8_t size
}
void emberAfPluginIasZoneServerInfoCommand(void)
{
- uint8_t cieAddress[EUI64_SIZE];
- uint16_t zoneStatus;
- uint16_t zoneType;
- uint8_t zoneState;
- uint8_t endpoint = (uint8_t)emberUnsignedCommandArgument(0);
+ uint8_t cieAddress[EUI64_SIZE];
+ uint16_t zoneStatus;
+ uint16_t zoneType;
+ uint8_t zoneState;
+ uint8_t endpoint = (uint8_t) emberUnsignedCommandArgument(0);
- getAttributes(cieAddress,
- &zoneStatus,
- &zoneType,
- &zoneState,
- endpoint);
- emberAfIasZoneClusterPrint("CIE Address: ");
- emberAfPrintBigEndianEui64(cieAddress);
- emberAfIasZoneClusterPrintln("");
- emberAfIasZoneClusterPrintln("Zone Type: 0x%2X (%p)",
- zoneType,
- getZoneTypeString(zoneType));
- emberAfIasZoneClusterPrintln("Zone State: 0x%X (%p)",
- zoneState,
- getZoneStateString(zoneState));
- emberAfIasZoneClusterPrintln("Zone Status: 0x%2X",
- zoneStatus);
- emberAfIasZoneClusterPrintln("Zone ID: 0x%2X",
- emberAfPluginIasZoneServerGetZoneId(endpoint));
+ getAttributes(cieAddress, &zoneStatus, &zoneType, &zoneState, endpoint);
+ emberAfIasZoneClusterPrint("CIE Address: ");
+ emberAfPrintBigEndianEui64(cieAddress);
+ emberAfIasZoneClusterPrintln("");
+ emberAfIasZoneClusterPrintln("Zone Type: 0x%2X (%p)", zoneType, getZoneTypeString(zoneType));
+ emberAfIasZoneClusterPrintln("Zone State: 0x%X (%p)", zoneState, getZoneStateString(zoneState));
+ emberAfIasZoneClusterPrintln("Zone Status: 0x%2X", zoneStatus);
+ emberAfIasZoneClusterPrintln("Zone ID: 0x%2X", emberAfPluginIasZoneServerGetZoneId(endpoint));
}
void emberAfPluginIasZoneServerChangeStatusCommand(void)
{
- uint16_t newStatus = (uint16_t)emberUnsignedCommandArgument(0);
- uint8_t timeSinceOccurredSeconds = (uint8_t)emberUnsignedCommandArgument(1);
- uint8_t endpoint = (uint8_t)emberUnsignedCommandArgument(2);
- emberAfPluginIasZoneServerUpdateZoneStatus(endpoint,
- newStatus,
- timeSinceOccurredSeconds << 2);
+ uint16_t newStatus = (uint16_t) emberUnsignedCommandArgument(0);
+ uint8_t timeSinceOccurredSeconds = (uint8_t) emberUnsignedCommandArgument(1);
+ uint8_t endpoint = (uint8_t) emberUnsignedCommandArgument(2);
+ emberAfPluginIasZoneServerUpdateZoneStatus(endpoint, newStatus, timeSinceOccurredSeconds << 2);
}
void emberAfPluginIasZoneServerSetEnrollmentMethodCommand(void)
{
- uint8_t endpoint = (uint8_t)emberUnsignedCommandArgument(0);
- uint8_t enrollmentMode = (uint8_t)emberUnsignedCommandArgument(1);
- emberAfPluginIasZoneClusterSetEnrollmentMethod(endpoint, enrollmentMode);
+ uint8_t endpoint = (uint8_t) emberUnsignedCommandArgument(0);
+ uint8_t enrollmentMode = (uint8_t) emberUnsignedCommandArgument(1);
+ emberAfPluginIasZoneClusterSetEnrollmentMethod(endpoint, enrollmentMode);
}
void emberAfPluginIasZoneServerChangeBackoffConfiguration(void)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- IasZoneStatusQueueRetryConfig retryConfig = {
- (uint8_t)emberUnsignedCommandArgument(0),
- (uint8_t)emberUnsignedCommandArgument(1),
- (uint32_t)emberUnsignedCommandArgument(2),
- (bool)emberUnsignedCommandArgument(3),
- (uint16_t)emberUnsignedCommandArgument(4)
- };
+ IasZoneStatusQueueRetryConfig retryConfig = { (uint8_t) emberUnsignedCommandArgument(0),
+ (uint8_t) emberUnsignedCommandArgument(1),
+ (uint32_t) emberUnsignedCommandArgument(2),
+ (bool) emberUnsignedCommandArgument(3),
+ (uint16_t) emberUnsignedCommandArgument(4) };
- if (EMBER_BAD_ARGUMENT
- == emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig)) {
- emberAfIasZoneClusterPrintln(
- "Parameter error! Valid parameters: %s, %s, %s %d, %s.",
- "0 < firstBackoff",
- "0 < commonRatio",
- "firstBackoff < maxBackoff <", IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC,
- "0 < maxRetryAttempts");
- }
+ if (EMBER_BAD_ARGUMENT == emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig))
+ {
+ emberAfIasZoneClusterPrintln("Parameter error! Valid parameters: %s, %s, %s %d, %s.", "0 < firstBackoff", "0 < commonRatio",
+ "firstBackoff < maxBackoff <", IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC,
+ "0 < maxRetryAttempts");
+ }
#else
- emberAfIasZoneClusterPrintln("Command error! IAS Zone Server status queue is not enabled");
+ emberAfIasZoneClusterPrintln("Command error! IAS Zone Server status queue is not enabled");
#endif
}
void emberAfPluginIasZoneServerCliPrintQueue(void)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- emberAfPluginIasZoneServerPrintQueue();
+ emberAfPluginIasZoneServerPrintQueue();
#else
- emberAfIasZoneClusterPrintln("Command error! IAS Zone Server status queue is not enabled");
+ emberAfIasZoneClusterPrintln("Command error! IAS Zone Server status queue is not enabled");
#endif
}
void emberAfPluginIasZoneServerCliPrintQueueConfig(void)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- emberAfPluginIasZoneServerPrintQueueConfig();
+ emberAfPluginIasZoneServerPrintQueueConfig();
#else
- emberAfIasZoneClusterPrintln("Command error! IAS Zone Server status queue is not enabled");
+ emberAfIasZoneClusterPrintln("Command error! IAS Zone Server status queue is not enabled");
#endif
}
diff --git a/src/app/clusters/ias-zone-server/ias-zone-server-test.c b/src/app/clusters/ias-zone-server/ias-zone-server-test.c
index c4aa14e..657a21c 100644
--- a/src/app/clusters/ias-zone-server/ias-zone-server-test.c
+++ b/src/app/clusters/ias-zone-server/ias-zone-server-test.c
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Unit tests for ias zone server plugin
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
#include "ias-zone-server.h"
@@ -47,24 +47,26 @@
#define UNDEFINED_ZONE_ID 0xFF
// These are non-public in ias-zone-server.c, so make a copy here.
-#define IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX 0x02
+#define IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX 0x02
#define ZCL_FRAME_CONTROL_IDX 0x00
#define RETRY_TEST_QUEUE_ENTRIES (3)
#define RETRY_TEST_MAKE_IT_UNLIMITED (10)
// This is non-public in ias-zone-server.c, so make a copy here.
-typedef struct {
- uint8_t endpoint;
- uint16_t status;
- uint32_t eventTimeMs;
+typedef struct
+{
+ uint8_t endpoint;
+ uint16_t status;
+ uint32_t eventTimeMs;
} IasZoneStatusQueueEntry;
// This is non-public in ias-zone-server.c, so make a copy here.
-typedef struct {
- uint8_t entriesInQueue;
- uint8_t startIdx;
- uint8_t lastIdx;
- IasZoneStatusQueueEntry buffer[EMBER_AF_PLUGIN_IAS_ZONE_SERVER_QUEUE_DEPTH];
+typedef struct
+{
+ uint8_t entriesInQueue;
+ uint8_t startIdx;
+ uint8_t lastIdx;
+ IasZoneStatusQueueEntry buffer[EMBER_AF_PLUGIN_IAS_ZONE_SERVER_QUEUE_DEPTH];
} IasZoneStatusQueue;
void emberAfPluginIasZoneServerStackStatusCallback(EmberStatus status);
@@ -74,17 +76,17 @@
EmberBindingTableEntry dummyBind;
EmberApsFrame frame;
EmberAfClusterCommand command;
-EmberAfClusterCommand *emAfCurrentCommand = &command;
+EmberAfClusterCommand * emAfCurrentCommand = &command;
EmberAfDefinedEndpoint emAfEndpoints[NUM_ENDPOINTS];
// State variables used for later expect statements
bool attributeWritten;
-bool bindSet = false;
-uint8_t CurrentCieAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-uint8_t zoneIdClearedCount = 0;
+bool bindSet = false;
+uint8_t CurrentCieAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+uint8_t zoneIdClearedCount = 0;
uint8_t cieAddressClearedCount = 0;
-uint8_t zoneTypeClearedCount = 0;
-uint8_t lastEndpointWritten = 0;
+uint8_t zoneTypeClearedCount = 0;
+uint8_t lastEndpointWritten = 0;
extern IasZoneStatusQueue messageQueue;
extern EmberEventControl emberAfPluginIasZoneServerManageQueueEventControl;
@@ -96,40 +98,35 @@
bool emberAfStartMoveCallback(void)
{
- return true;
+ return true;
}
bool emberAfContainsServer(uint8_t endpoint, EmberAfClusterId clusterId)
{
- return true;
+ return true;
}
EmberStatus emberLeaveNetwork(void)
{
- return EMBER_SUCCESS;
+ return EMBER_SUCCESS;
}
-EmberAfAttributeMetadata *emberAfLocateAttributeMetadata(uint8_t endpoint,
- EmberAfClusterId clusterId,
- EmberAfAttributeId attributeId,
- uint8_t mask,
- uint16_t manufacturerCode)
+EmberAfAttributeMetadata * emberAfLocateAttributeMetadata(uint8_t endpoint, EmberAfClusterId clusterId,
+ EmberAfAttributeId attributeId, uint8_t mask, uint16_t manufacturerCode)
{
- return NULL;
+ return NULL;
}
-void halInternalGetTokenData(void *data, uint16_t token, uint8_t index, uint8_t len)
+void halInternalGetTokenData(void * data, uint16_t token, uint8_t index, uint8_t len)
{
- return;
+ return;
}
-void halInternalSetTokenData(uint16_t token, uint8_t index, void *data, uint8_t len)
-{
-}
+void halInternalSetTokenData(uint16_t token, uint8_t index, void * data, uint8_t len) {}
uint32_t halCommonGetInt32uMillisecondTick(void)
{
- return 0;
+ return 0;
}
// -----------------------------------------------------------------------------
@@ -137,103 +134,110 @@
// how the system will work
// -----------------------------------------------------------------------------
-static const uint8_t attributeSizes[] =
-{
+static const uint8_t attributeSizes[] = {
#include "attribute-size.h"
};
uint8_t emberAfGetDataSize(uint8_t dataType)
{
- uint8_t i;
- for (i = 0; (i + 1) < sizeof(attributeSizes); i += 2) {
- if (attributeSizes[i] == dataType) {
- return attributeSizes[i + 1];
+ uint8_t i;
+ for (i = 0; (i + 1) < sizeof(attributeSizes); i += 2)
+ {
+ if (attributeSizes[i] == dataType)
+ {
+ return attributeSizes[i + 1];
+ }
}
- }
- return 0;
+ return 0;
}
-EmberStatus emberGetBinding(uint8_t idx, EmberBindingTableEntry *entry)
+EmberStatus emberGetBinding(uint8_t idx, EmberBindingTableEntry * entry)
{
- entry->type = EMBER_UNUSED_BINDING;
- bindSet = true;
+ entry->type = EMBER_UNUSED_BINDING;
+ bindSet = true;
- return EMBER_SUCCESS;
+ return EMBER_SUCCESS;
}
-EmberAfStatus emberAfReadServerAttribute(uint8_t endpoint,
- EmberAfClusterId cluster,
- EmberAfAttributeId attributeID,
- uint8_t *dataPtr,
- uint8_t readLength)
+EmberAfStatus emberAfReadServerAttribute(uint8_t endpoint, EmberAfClusterId cluster, EmberAfAttributeId attributeID,
+ uint8_t * dataPtr, uint8_t readLength)
{
- uint8_t i;
+ uint8_t i;
- if (attributeID != ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID) {
- return -1;
- }
+ if (attributeID != ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID)
+ {
+ return -1;
+ }
- for (i = 0; i < 8; i++) {
- dataPtr[i] = CurrentCieAddress[i];
- }
+ for (i = 0; i < 8; i++)
+ {
+ dataPtr[i] = CurrentCieAddress[i];
+ }
- return EMBER_SUCCESS;
+ return EMBER_SUCCESS;
}
uint8_t emberAfEndpointCount()
{
- return NUM_ENDPOINTS;
+ return NUM_ENDPOINTS;
}
uint8_t emberAfEndpointFromIndex(uint8_t idx)
{
- currentEndpoint = idx + 1;
- return currentEndpoint;
+ currentEndpoint = idx + 1;
+ return currentEndpoint;
}
-EmberAfStatus emberAfWriteServerAttribute(uint8_t endpoint,
- EmberAfClusterId cluster,
- EmberAfAttributeId attributeID,
- uint8_t *dataPtr,
- uint8_t emberSetBindingataType)
+EmberAfStatus emberAfWriteServerAttribute(uint8_t endpoint, EmberAfClusterId cluster, EmberAfAttributeId attributeID,
+ uint8_t * dataPtr, uint8_t emberSetBindingataType)
{
- uint8_t zoneId;
- uint16_t zoneType;
- uint8_t i;
- bool zeroAddress = true;
+ uint8_t zoneId;
+ uint16_t zoneType;
+ uint8_t i;
+ bool zeroAddress = true;
- lastEndpointWritten = endpoint;
+ lastEndpointWritten = endpoint;
- if (attributeID == ZCL_ZONE_ID_ATTRIBUTE_ID) {
- zoneId = *dataPtr;
- if (zoneId == UNDEFINED_ZONE_ID) {
- zoneIdClearedCount++;
- return EMBER_SUCCESS;
+ if (attributeID == ZCL_ZONE_ID_ATTRIBUTE_ID)
+ {
+ zoneId = *dataPtr;
+ if (zoneId == UNDEFINED_ZONE_ID)
+ {
+ zoneIdClearedCount++;
+ return EMBER_SUCCESS;
+ }
}
- } else if (attributeID == ZCL_ZONE_TYPE_ATTRIBUTE_ID) {
- zoneType = *(uint16_t*)dataPtr;
- if (zoneType == EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE) {
- zoneTypeClearedCount++;
+ else if (attributeID == ZCL_ZONE_TYPE_ATTRIBUTE_ID)
+ {
+ zoneType = *(uint16_t *) dataPtr;
+ if (zoneType == EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE)
+ {
+ zoneTypeClearedCount++;
+ }
}
- } else if (attributeID == ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID) {
- for (i = 0; i < 8; i++) {
- if (dataPtr[i] != 0) {
- zeroAddress = false;
- }
+ else if (attributeID == ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID)
+ {
+ for (i = 0; i < 8; i++)
+ {
+ if (dataPtr[i] != 0)
+ {
+ zeroAddress = false;
+ }
+ }
+ if (zeroAddress)
+ {
+ cieAddressClearedCount++;
+ }
}
- if (zeroAddress) {
- cieAddressClearedCount++;
- }
- }
- attributeWritten = true;
- return 0;
+ attributeWritten = true;
+ return 0;
}
-EmberStatus emberSetBinding(uint8_t index, EmberBindingTableEntry *value)
+EmberStatus emberSetBinding(uint8_t index, EmberBindingTableEntry * value)
{
- bindSet = true;
- return 0;
+ bindSet = true;
+ return 0;
}
// -----------------------------------------------------------------------------
@@ -248,37 +252,29 @@
// written to the device
static void enrollTest(void)
{
- uint8_t endpoint = 1;
- EmberAfAttributeId attributeIdCie = ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID;
- EmberAfAttributeType attributeType = 0;
- uint8_t size = EUI64_SIZE;
- uint8_t newCieAddress[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
- uint8_t i;
+ uint8_t endpoint = 1;
+ EmberAfAttributeId attributeIdCie = ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID;
+ EmberAfAttributeType attributeType = 0;
+ uint8_t size = EUI64_SIZE;
+ uint8_t newCieAddress[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+ uint8_t i;
- //bind is created
+ // bind is created
- // Verify that no extra action happens when we send an attribute other than
- // the CIE_ADDRESS_ATTRIBUTE
- emAfCurrentCommand->apsFrame = &frame;
- emAfCurrentCommand->apsFrame->sourceEndpoint = 1;
+ // Verify that no extra action happens when we send an attribute other than
+ // the CIE_ADDRESS_ATTRIBUTE
+ emAfCurrentCommand->apsFrame = &frame;
+ emAfCurrentCommand->apsFrame->sourceEndpoint = 1;
- for (i = 0; i < 8; i++) {
- CurrentCieAddress[i] = 0;
- }
- bindSet = false;
+ for (i = 0; i < 8; i++)
+ {
+ CurrentCieAddress[i] = 0;
+ }
+ bindSet = false;
- emberAfIasZoneClusterServerPreAttributeChangedCallback(
- endpoint,
- attributeIdCie,
- attributeType,
- size,
- newCieAddress);
+ emberAfIasZoneClusterServerPreAttributeChangedCallback(endpoint, attributeIdCie, attributeType, size, newCieAddress);
- expectComparisonDecimal(
- true,
- bindSet,
- "expected binding entry state",
- "observed binding entry state");
+ expectComparisonDecimal(true, bindSet, "expected binding entry state", "observed binding entry state");
}
// -----------------------------------------------------------------------------
@@ -287,49 +283,29 @@
// Verify that on network leave, attributes are reset to default values
static void leaveTest(void)
{
- currentEndpoint = 0;
- zoneIdClearedCount = 0;
- cieAddressClearedCount = 0;
- zoneTypeClearedCount = 0;
+ currentEndpoint = 0;
+ zoneIdClearedCount = 0;
+ cieAddressClearedCount = 0;
+ zoneTypeClearedCount = 0;
- // EMAPPFWKV2-1530: if we are told that are network is down, but we are
- // rejoining, then we should not unenroll.
- testFrameworkNetworkState = EMBER_JOINED_NETWORK_NO_PARENT;
- emberAfPluginIasZoneServerStackStatusCallback(EMBER_NETWORK_DOWN);
- expectComparisonDecimal(
- 0,
- zoneTypeClearedCount,
- "expected number of zone Type cleared",
- "observed number of zone Type cleared");
- expectComparisonDecimal(
- 0,
- cieAddressClearedCount,
- "expected number of CieAddr cleared",
- "observed number of CieAddr cleared");
- expectComparisonDecimal(
- 0,
- zoneIdClearedCount,
- "expected number of zone ID cleared",
- "observed number of zone ID cleared");
+ // EMAPPFWKV2-1530: if we are told that are network is down, but we are
+ // rejoining, then we should not unenroll.
+ testFrameworkNetworkState = EMBER_JOINED_NETWORK_NO_PARENT;
+ emberAfPluginIasZoneServerStackStatusCallback(EMBER_NETWORK_DOWN);
+ expectComparisonDecimal(0, zoneTypeClearedCount, "expected number of zone Type cleared",
+ "observed number of zone Type cleared");
+ expectComparisonDecimal(0, cieAddressClearedCount, "expected number of CieAddr cleared", "observed number of CieAddr cleared");
+ expectComparisonDecimal(0, zoneIdClearedCount, "expected number of zone ID cleared", "observed number of zone ID cleared");
- // If we are told that are network is really down, then we do unenroll.
- testFrameworkNetworkState = EMBER_NO_NETWORK;
- emberAfPluginIasZoneServerStackStatusCallback(EMBER_NETWORK_DOWN);
- expectComparisonDecimal(
- NUM_ENDPOINTS,
- zoneTypeClearedCount,
- "expected number of zone Type cleared",
- "observed number of zone Type cleared");
- expectComparisonDecimal(
- NUM_ENDPOINTS,
- cieAddressClearedCount,
- "expected number of CieAddr cleared",
- "observed number of CieAddr cleared");
- expectComparisonDecimal(
- NUM_ENDPOINTS,
- zoneIdClearedCount,
- "expected number of zone ID cleared",
- "observed number of zone ID cleared");
+ // If we are told that are network is really down, then we do unenroll.
+ testFrameworkNetworkState = EMBER_NO_NETWORK;
+ emberAfPluginIasZoneServerStackStatusCallback(EMBER_NETWORK_DOWN);
+ expectComparisonDecimal(NUM_ENDPOINTS, zoneTypeClearedCount, "expected number of zone Type cleared",
+ "observed number of zone Type cleared");
+ expectComparisonDecimal(NUM_ENDPOINTS, cieAddressClearedCount, "expected number of CieAddr cleared",
+ "observed number of CieAddr cleared");
+ expectComparisonDecimal(NUM_ENDPOINTS, zoneIdClearedCount, "expected number of zone ID cleared",
+ "observed number of zone ID cleared");
}
// -----------------------------------------------------------------------------
@@ -339,215 +315,199 @@
// function is called
static void updateTest(void)
{
- uint8_t testEndpoint = 0;
+ uint8_t testEndpoint = 0;
- for (testEndpoint = 0; testEndpoint < NUM_ENDPOINTS; testEndpoint++) {
- emberAfPluginIasZoneServerUpdateZoneStatus(testEndpoint, 0, 0);
- expectComparisonDecimal(
- testEndpoint,
- lastEndpointWritten,
- "expected attribute write to endpoint",
- "observed attribute write to endpoint");
- }
+ for (testEndpoint = 0; testEndpoint < NUM_ENDPOINTS; testEndpoint++)
+ {
+ emberAfPluginIasZoneServerUpdateZoneStatus(testEndpoint, 0, 0);
+ expectComparisonDecimal(testEndpoint, lastEndpointWritten, "expected attribute write to endpoint",
+ "observed attribute write to endpoint");
+ }
}
// -----------------------------------------------------------------------------
// Test case: status queue retry tests
// -----------------------------------------------------------------------------
-#define testConfigStatusQueueRetryParamsBadArgument() do { \
- EmberStatus status = emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig); \
- expectComparisonDecimal( \
- EMBER_BAD_ARGUMENT, \
- status, \
- "expected return status", \
- "observed return status"); \
-} while (0)
+#define testConfigStatusQueueRetryParamsBadArgument() \
+ do \
+ { \
+ EmberStatus status = emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig); \
+ expectComparisonDecimal(EMBER_BAD_ARGUMENT, status, "expected return status", "observed return status"); \
+ } while (0)
// Verify that status queue configuration parameter check is operating per the current
// requirements. Both parameter limits and the input parameters are tested.
-void statusQueueParameterTest(uint8_t firstBackoffTimeSec, uint8_t backoffSeqCommonRatio,
- uint32_t maxBackoffTimeSec, bool unlimitedRetries, uint8_t maxRetryAttempts)
+void statusQueueParameterTest(uint8_t firstBackoffTimeSec, uint8_t backoffSeqCommonRatio, uint32_t maxBackoffTimeSec,
+ bool unlimitedRetries, uint8_t maxRetryAttempts)
{
- // Filling up retryConfig with the input parameters of this function
- // and changing each parameters to an invalid value one by one so that
- // parameter check is tested.
- IasZoneStatusQueueRetryConfig retryConfig = {
- firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec, unlimitedRetries, maxRetryAttempts
- };
+ // Filling up retryConfig with the input parameters of this function
+ // and changing each parameters to an invalid value one by one so that
+ // parameter check is tested.
+ IasZoneStatusQueueRetryConfig retryConfig = { firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec, unlimitedRetries,
+ maxRetryAttempts };
- retryConfig.firstBackoffTimeSec = 0;
- testConfigStatusQueueRetryParamsBadArgument();
- retryConfig.firstBackoffTimeSec = firstBackoffTimeSec;
+ retryConfig.firstBackoffTimeSec = 0;
+ testConfigStatusQueueRetryParamsBadArgument();
+ retryConfig.firstBackoffTimeSec = firstBackoffTimeSec;
- retryConfig.backoffSeqCommonRatio = 0;
- testConfigStatusQueueRetryParamsBadArgument();
- retryConfig.backoffSeqCommonRatio = backoffSeqCommonRatio;
+ retryConfig.backoffSeqCommonRatio = 0;
+ testConfigStatusQueueRetryParamsBadArgument();
+ retryConfig.backoffSeqCommonRatio = backoffSeqCommonRatio;
- retryConfig.maxRetryAttempts = 0;
- testConfigStatusQueueRetryParamsBadArgument();
- retryConfig.maxRetryAttempts = maxRetryAttempts;
+ retryConfig.maxRetryAttempts = 0;
+ testConfigStatusQueueRetryParamsBadArgument();
+ retryConfig.maxRetryAttempts = maxRetryAttempts;
- retryConfig.maxBackoffTimeSec = 0;
- testConfigStatusQueueRetryParamsBadArgument();
- retryConfig.maxBackoffTimeSec = IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC + 1;
- testConfigStatusQueueRetryParamsBadArgument();
- retryConfig.maxBackoffTimeSec = maxBackoffTimeSec;
+ retryConfig.maxBackoffTimeSec = 0;
+ testConfigStatusQueueRetryParamsBadArgument();
+ retryConfig.maxBackoffTimeSec = IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC + 1;
+ testConfigStatusQueueRetryParamsBadArgument();
+ retryConfig.maxBackoffTimeSec = maxBackoffTimeSec;
}
// Helper function to test status queue retry functionality with different configuration values.
-uint32_t retryTestRunner(uint8_t firstBackoffTimeSec, uint8_t backoffSeqCommonRatio,
- uint32_t maxBackoffTimeSec, bool unlimitedRetries, uint16_t maxTestRetryAttempts)
+uint32_t retryTestRunner(uint8_t firstBackoffTimeSec, uint8_t backoffSeqCommonRatio, uint32_t maxBackoffTimeSec,
+ bool unlimitedRetries, uint16_t maxTestRetryAttempts)
{
- uint32_t retryCount;
- uint32_t expectedBackoffTimeSec = 0;
- uint8_t message[3];
- uint8_t maxRetryAttempts;
- uint8_t maxBackoffTestCount = 3;
+ uint32_t retryCount;
+ uint32_t expectedBackoffTimeSec = 0;
+ uint8_t message[3];
+ uint8_t maxRetryAttempts;
+ uint8_t maxBackoffTestCount = 3;
- // Unlimited retry is configured by setting the max retry attempts to 0xFFFF.
- if (unlimitedRetries) {
- maxRetryAttempts = 0xFF;
- } else {
- maxRetryAttempts = maxTestRetryAttempts - 1;
- }
-
- // Setup specific message parameters that are checked in
- // emberAfIasZoneClusterServerMessageSentCallback().
- // Note: these are independent of this actual test.
- message[ZCL_FRAME_CONTROL_IDX] = ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT;
- message[IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX] = ZCL_ZONE_STATUS_CHANGE_NOTIFICATION_COMMAND_ID;
-
- IasZoneStatusQueueRetryConfig retryConfig = {
- firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec,
- unlimitedRetries, maxRetryAttempts
- };
-
- // Setting up retry parameters
- emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig);
-
- // Calling message sent callback of the plugin with status parameter set to failure,
- // so that retry functionality is tested.
- expectedBackoffTimeSec = firstBackoffTimeSec;
- for (retryCount = 0; retryCount < maxTestRetryAttempts; retryCount++) {
- emberAfIasZoneClusterServerMessageSentCallback(0, 0, NULL,
- IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX, message, EMBER_DELIVERY_FAILED);
-
- // No need to test max backoff if already reached and tested for a few times.
- // This makes the test run shorter and prints less garbage (ie. unnecessary dots)
- // on the screen.
- if (maxBackoffTestCount) {
- // Testing that the backoff time is increased according to current backoff configuration.
- expectComparisonDecimal(
- expectedBackoffTimeSec * MILLISECOND_TICKS_PER_SECOND,
- emberAfPluginIasZoneServerManageQueueEventControl.timeToExecute,
- "expected back-off time in ms",
- "observed back-off time in ms");
+ // Unlimited retry is configured by setting the max retry attempts to 0xFFFF.
+ if (unlimitedRetries)
+ {
+ maxRetryAttempts = 0xFF;
+ }
+ else
+ {
+ maxRetryAttempts = maxTestRetryAttempts - 1;
}
- // Max retry attempts is reached, break here.
- if (emberAfPluginIasZoneServerManageQueueEventControl.status == EMBER_EVENT_ZERO_DELAY) {
- break;
+ // Setup specific message parameters that are checked in
+ // emberAfIasZoneClusterServerMessageSentCallback().
+ // Note: these are independent of this actual test.
+ message[ZCL_FRAME_CONTROL_IDX] = ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT;
+ message[IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX] = ZCL_ZONE_STATUS_CHANGE_NOTIFICATION_COMMAND_ID;
+
+ IasZoneStatusQueueRetryConfig retryConfig = { firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec, unlimitedRetries,
+ maxRetryAttempts };
+
+ // Setting up retry parameters
+ emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig);
+
+ // Calling message sent callback of the plugin with status parameter set to failure,
+ // so that retry functionality is tested.
+ expectedBackoffTimeSec = firstBackoffTimeSec;
+ for (retryCount = 0; retryCount < maxTestRetryAttempts; retryCount++)
+ {
+ emberAfIasZoneClusterServerMessageSentCallback(0, 0, NULL, IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX, message,
+ EMBER_DELIVERY_FAILED);
+
+ // No need to test max backoff if already reached and tested for a few times.
+ // This makes the test run shorter and prints less garbage (ie. unnecessary dots)
+ // on the screen.
+ if (maxBackoffTestCount)
+ {
+ // Testing that the backoff time is increased according to current backoff configuration.
+ expectComparisonDecimal(expectedBackoffTimeSec * MILLISECOND_TICKS_PER_SECOND,
+ emberAfPluginIasZoneServerManageQueueEventControl.timeToExecute, "expected back-off time in ms",
+ "observed back-off time in ms");
+ }
+
+ // Max retry attempts is reached, break here.
+ if (emberAfPluginIasZoneServerManageQueueEventControl.status == EMBER_EVENT_ZERO_DELAY)
+ {
+ break;
+ }
+
+ // Increase expected backoff time until it reaches max backoff time.
+ // Make sure that the current backoff time is still tested for a few
+ // times after max backoff time is reached.
+ if (expectedBackoffTimeSec * backoffSeqCommonRatio <= maxBackoffTimeSec)
+ {
+ expectedBackoffTimeSec = expectedBackoffTimeSec * backoffSeqCommonRatio;
+ }
+ else if (maxBackoffTestCount)
+ {
+ maxBackoffTestCount--;
+ }
}
- // Increase expected backoff time until it reaches max backoff time.
- // Make sure that the current backoff time is still tested for a few
- // times after max backoff time is reached.
- if (expectedBackoffTimeSec * backoffSeqCommonRatio <= maxBackoffTimeSec) {
- expectedBackoffTimeSec = expectedBackoffTimeSec * backoffSeqCommonRatio;
- } else if (maxBackoffTestCount) {
- maxBackoffTestCount--;
- }
- }
-
- return retryCount;
+ return retryCount;
}
// Verify that the status queue retry funcionality works as expected with
// different backoff parameters. Also test unlimited and limited retries.
static void retryTest(void)
{
- uint8_t firstBackoffTimeSec, backoffSeqCommonRatio;
- uint32_t retryCount, maxBackoffTimeSec, maxTestRetryAttempts;
+ uint8_t firstBackoffTimeSec, backoffSeqCommonRatio;
+ uint32_t retryCount, maxBackoffTimeSec, maxTestRetryAttempts;
- // "Loading" the status queue with some elements.
- messageQueue.entriesInQueue = RETRY_TEST_QUEUE_ENTRIES;
- messageQueue.startIdx = 0;
- messageQueue.lastIdx = RETRY_TEST_QUEUE_ENTRIES - 1;
+ // "Loading" the status queue with some elements.
+ messageQueue.entriesInQueue = RETRY_TEST_QUEUE_ENTRIES;
+ messageQueue.startIdx = 0;
+ messageQueue.lastIdx = RETRY_TEST_QUEUE_ENTRIES - 1;
- // --------------------------------------------------------------------
- // Test 1: test with minimal settings (small max retry attempts).
- // --------------------------------------------------------------------
- firstBackoffTimeSec = 2;
- backoffSeqCommonRatio = 3;
- maxBackoffTimeSec = 500;
- maxTestRetryAttempts = 11;
+ // --------------------------------------------------------------------
+ // Test 1: test with minimal settings (small max retry attempts).
+ // --------------------------------------------------------------------
+ firstBackoffTimeSec = 2;
+ backoffSeqCommonRatio = 3;
+ maxBackoffTimeSec = 500;
+ maxTestRetryAttempts = 11;
- statusQueueParameterTest(firstBackoffTimeSec, backoffSeqCommonRatio,
- maxBackoffTimeSec, false, maxTestRetryAttempts);
+ statusQueueParameterTest(firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec, false, maxTestRetryAttempts);
- retryCount = retryTestRunner(firstBackoffTimeSec, backoffSeqCommonRatio,
- maxBackoffTimeSec, false, maxTestRetryAttempts);
+ retryCount = retryTestRunner(firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec, false, maxTestRetryAttempts);
- // Testing if the number of retry attempts is what is expected.
- expectComparisonDecimal(
- retryCount,
- maxTestRetryAttempts - 1,
- "number of retry attempts at end of test",
- "expected max retry attempts");
+ // Testing if the number of retry attempts is what is expected.
+ expectComparisonDecimal(retryCount, maxTestRetryAttempts - 1, "number of retry attempts at end of test",
+ "expected max retry attempts");
- // Testing if queue element is removed after reaching max retry attempts.
- expectComparisonDecimal(
- messageQueue.entriesInQueue,
- RETRY_TEST_QUEUE_ENTRIES - 1,
- "current number of element in message queue",
- "expected number of element in message queue");
+ // Testing if queue element is removed after reaching max retry attempts.
+ expectComparisonDecimal(messageQueue.entriesInQueue, RETRY_TEST_QUEUE_ENTRIES - 1, "current number of element in message queue",
+ "expected number of element in message queue");
- // -----------------------------------------------------------
- // Test 2: test with default (legacy) settings of this plugin.
- // -----------------------------------------------------------
- firstBackoffTimeSec = 3;
- backoffSeqCommonRatio = 2;
- maxBackoffTimeSec = 12;
- // 0xFF is unlimited attempts per the requirements. Making the retry attempts
- // in this test way higher than this limit so unlimited retires can be tested.
- maxTestRetryAttempts = 3 * 0xFF;
+ // -----------------------------------------------------------
+ // Test 2: test with default (legacy) settings of this plugin.
+ // -----------------------------------------------------------
+ firstBackoffTimeSec = 3;
+ backoffSeqCommonRatio = 2;
+ maxBackoffTimeSec = 12;
+ // 0xFF is unlimited attempts per the requirements. Making the retry attempts
+ // in this test way higher than this limit so unlimited retires can be tested.
+ maxTestRetryAttempts = 3 * 0xFF;
- statusQueueParameterTest(firstBackoffTimeSec, backoffSeqCommonRatio,
- maxBackoffTimeSec, true, maxTestRetryAttempts);
+ statusQueueParameterTest(firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec, true, maxTestRetryAttempts);
- retryCount = retryTestRunner(firstBackoffTimeSec, backoffSeqCommonRatio,
- maxBackoffTimeSec, true, maxTestRetryAttempts);
+ retryCount = retryTestRunner(firstBackoffTimeSec, backoffSeqCommonRatio, maxBackoffTimeSec, true, maxTestRetryAttempts);
- // Testing if the number of retry attempts equals to what is expected.
- expectComparisonDecimal(
- retryCount,
- maxTestRetryAttempts,
- "number of retry attempts at end of test",
- "expected retry attempts (ie. unlimited)");
+ // Testing if the number of retry attempts equals to what is expected.
+ expectComparisonDecimal(retryCount, maxTestRetryAttempts, "number of retry attempts at end of test",
+ "expected retry attempts (ie. unlimited)");
- // Testing if queue element was not cleared (ie. same as after the previous test),
- // since this is an unlimited retry test.
- expectComparisonDecimal(
- messageQueue.entriesInQueue,
- RETRY_TEST_QUEUE_ENTRIES - 1,
- "current number of element in message queue",
- "expected number of element in message queue");
+ // Testing if queue element was not cleared (ie. same as after the previous test),
+ // since this is an unlimited retry test.
+ expectComparisonDecimal(messageQueue.entriesInQueue, RETRY_TEST_QUEUE_ENTRIES - 1, "current number of element in message queue",
+ "expected number of element in message queue");
}
-int main(int argc, char* argv[])
+int main(int argc, char * argv[])
{
- const TestCase tests[] = {
- { "attribute-response", enrollTest },
- { "leave-test", leaveTest },
- { "update-test", updateTest },
- { "retry-test", retryTest },
- { NULL },
- };
+ const TestCase tests[] = {
+ { "attribute-response", enrollTest },
+ { "leave-test", leaveTest },
+ { "update-test", updateTest },
+ { "retry-test", retryTest },
+ { NULL },
+ };
- // This test only runs correctly with network 0.
- // Ideally we should look into this.
- emberSetCurrentNetwork(0);
+ // This test only runs correctly with network 0.
+ // Ideally we should look into this.
+ emberSetCurrentNetwork(0);
- return parseCommandLineAndExecuteTest(argc, argv, "IAS Zone Server", tests);
+ return parseCommandLineAndExecuteTest(argc, argv, "IAS Zone Server", tests);
}
diff --git a/src/app/clusters/ias-zone-server/ias-zone-server-test.h b/src/app/clusters/ias-zone-server/ias-zone-server-test.h
index b7cef67..a2ac744 100644
--- a/src/app/clusters/ias-zone-server/ias-zone-server-test.h
+++ b/src/app/clusters/ias-zone-server/ias-zone-server-test.h
@@ -31,11 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Include file for ias zone server's unit tests
+ * @brief Include file for ias zone server's unit
+ *tests
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#ifndef SILABS_IAS_ZONE_SERVER_TEST_H
#define SILABS_IAS_ZONE_SERVER_TEST_H
@@ -54,8 +55,8 @@
#endif
-#define TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD 0
-#define TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD_SIZE 1
+#define TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD 0
+#define TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD_SIZE 1
#undef EMBER_BINDING_TABLE_SIZE
#define EMBER_BINDING_TABLE_SIZE 12
diff --git a/src/app/clusters/ias-zone-server/ias-zone-server-tokens.h b/src/app/clusters/ias-zone-server/ias-zone-server-tokens.h
index c70e18a..58edc49 100644
--- a/src/app/clusters/ias-zone-server/ias-zone-server-tokens.h
+++ b/src/app/clusters/ias-zone-server/ias-zone-server-tokens.h
@@ -31,24 +31,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Tokens for the IAS Zone Server plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
/**
* Custom Application Tokens
*/
-#define CREATOR_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD (0x0020)
+#define CREATOR_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD (0x0020)
#define NVM3KEY_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD (NVM3KEY_DOMAIN_USER | 0x0020)
#ifdef DEFINETYPES
// Include or define any typedef for tokens here
-#endif // DEFINETYPES
+#endif // DEFINETYPES
#ifdef DEFINETOKENS
// Define the actual token storage information here
DEFINE_BASIC_TOKEN(PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD, uint8_t, 0xFF)
-#endif // DEFINETOKENS
+#endif // DEFINETOKENS
diff --git a/src/app/clusters/ias-zone-server/ias-zone-server.c b/src/app/clusters/ias-zone-server/ias-zone-server.c
index 2dcb63c..a52b9b0 100644
--- a/src/app/clusters/ias-zone-server/ias-zone-server.c
+++ b/src/app/clusters/ias-zone-server/ias-zone-server.c
@@ -31,14 +31,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief This is the source for the plugin used to add an IAS Zone cluster server
- * to a project. This source handles zone enrollment and storing of
- * attributes from a CIE device, and provides an API for different plugins to
- * post updated zone status values.
+ * @brief This is the source for the plugin used to
+ *add an IAS Zone cluster server to a project. This
+ *source handles zone enrollment and storing of
+ * attributes from a CIE device, and provides an API
+ *for different plugins to post updated zone status
+ *values.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// *****************************************************************************
// * ias-zone-server.c
@@ -48,8 +50,8 @@
// * Copyright 2015 Silicon Laboratories, Inc. *80*
// *****************************************************************************
-#include "app/framework/include/af.h"
#include "ias-zone-server.h"
+#include "app/framework/include/af.h"
#include "hal/micro/token.h"
#ifdef EMBER_SCRIPTED_TEST
@@ -58,32 +60,34 @@
#define UNDEFINED_ZONE_ID 0xFF
#define DELAY_TIMER_MS (1 * MILLISECOND_TICKS_PER_SECOND)
-#define IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX 0x02
+#define IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX 0x02
#define ZCL_FRAME_CONTROL_IDX 0x00
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- #if defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER)
- #define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER_QUEUE_SIZE
- #else
- #define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_IAS_ZONE_SERVER_QUEUE_DEPTH
- #endif
+#if defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER)
+#define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER_QUEUE_SIZE
#else
- #define NUM_QUEUE_ENTRIES 0
+#define NUM_QUEUE_ENTRIES EMBER_AF_PLUGIN_IAS_ZONE_SERVER_QUEUE_DEPTH
+#endif
+#else
+#define NUM_QUEUE_ENTRIES 0
#endif
-#define DEFAULT_ENROLLMENT_METHOD EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST
+#define DEFAULT_ENROLLMENT_METHOD EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST
-typedef struct {
- uint8_t endpoint;
- uint16_t status;
- uint32_t eventTimeMs;
+typedef struct
+{
+ uint8_t endpoint;
+ uint16_t status;
+ uint32_t eventTimeMs;
} IasZoneStatusQueueEntry;
-typedef struct {
- uint8_t entriesInQueue;
- uint8_t startIdx;
- uint8_t lastIdx;
- IasZoneStatusQueueEntry buffer[NUM_QUEUE_ENTRIES];
+typedef struct
+{
+ uint8_t entriesInQueue;
+ uint8_t startIdx;
+ uint8_t lastIdx;
+ IasZoneStatusQueueEntry buffer[NUM_QUEUE_ENTRIES];
} IasZoneStatusQueue;
//-----------------------------------------------------------------------------
@@ -96,33 +100,32 @@
IasZoneStatusQueue messageQueue;
// Status queue retry parameters
-typedef struct {
- IasZoneStatusQueueRetryConfig config;
- uint32_t currentBackoffTimeSec;
- uint8_t currentRetryCount;
+typedef struct
+{
+ IasZoneStatusQueueRetryConfig config;
+ uint32_t currentBackoffTimeSec;
+ uint8_t currentRetryCount;
} IasZoneStatusQueueRetryParameters;
// Set up status queue retry parameters.
IasZoneStatusQueueRetryParameters queueRetryParams = {
- .config = {
- .firstBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC,
- .backoffSeqCommonRatio = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO,
- .maxBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC,
+ .config = { .firstBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC,
+ .backoffSeqCommonRatio = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO,
+ .maxBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC,
#ifdef EMBER_AF_PLUGIN_IAS_ZONE_SERVER_UNLIMITED_RETRIES
- .unlimitedRetries = true,
+ .unlimitedRetries = true,
#else
- .unlimitedRetries = false,
+ .unlimitedRetries = false,
#endif
- .maxRetryAttempts = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS
- },
- .currentBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC,
- .currentRetryCount = 0,
+ .maxRetryAttempts = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS },
+ .currentBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC,
+ .currentRetryCount = 0,
};
static void resetCurrentQueueRetryParams(void)
{
- queueRetryParams.currentRetryCount = 0;
- queueRetryParams.currentBackoffTimeSec = queueRetryParams.config.firstBackoffTimeSec;
+ queueRetryParams.currentRetryCount = 0;
+ queueRetryParams.currentBackoffTimeSec = queueRetryParams.config.firstBackoffTimeSec;
}
#endif // EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE
@@ -134,12 +137,10 @@
static bool areZoneServerAttributesTokenized(uint8_t endpoint);
static boolean isValidEnrollmentMode(EmberAfIasZoneEnrollmentMode method);
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
-static uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry *entry);
-static void bufferInit(IasZoneStatusQueue *ring);
-static int16_t copyToBuffer(IasZoneStatusQueue *ring,
- const IasZoneStatusQueueEntry *entry);
-static int16_t popFromBuffer(IasZoneStatusQueue *ring,
- IasZoneStatusQueueEntry *entry);
+static uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry * entry);
+static void bufferInit(IasZoneStatusQueue * ring);
+static int16_t copyToBuffer(IasZoneStatusQueue * ring, const IasZoneStatusQueueEntry * entry);
+static int16_t popFromBuffer(IasZoneStatusQueue * ring, IasZoneStatusQueueEntry * entry);
#endif
//-----------------------------------------------------------------------------
@@ -147,434 +148,410 @@
static EmberStatus sendToClient(uint8_t endpoint)
{
- EmberStatus status;
+ EmberStatus status;
- // If the device is not a network, there is no one to send to, so do nothing
- if (emberAfNetworkState() != EMBER_JOINED_NETWORK) {
- return EMBER_NETWORK_DOWN;
- }
+ // If the device is not a network, there is no one to send to, so do nothing
+ if (emberAfNetworkState() != EMBER_JOINED_NETWORK)
+ {
+ return EMBER_NETWORK_DOWN;
+ }
- // Remote endpoint need not be set, since it will be provided by the call to
- // emberAfSendCommandUnicastToBindings()
- emberAfSetCommandEndpoints(endpoint, 0);
+ // Remote endpoint need not be set, since it will be provided by the call to
+ // emberAfSendCommandUnicastToBindings()
+ emberAfSetCommandEndpoints(endpoint, 0);
- // A binding table entry is created on Zone Enrollment for each endpoint, so
- // a simple call to SendCommandUnicastToBinding will handle determining the
- // destination endpoint, address, etc for us.
- status = emberAfSendCommandUnicastToBindings();
+ // A binding table entry is created on Zone Enrollment for each endpoint, so
+ // a simple call to SendCommandUnicastToBinding will handle determining the
+ // destination endpoint, address, etc for us.
+ status = emberAfSendCommandUnicastToBindings();
- if (EMBER_SUCCESS != status) {
+ if (EMBER_SUCCESS != status)
+ {
+ return status;
+ }
+
return status;
- }
-
- return status;
}
static void enrollWithClient(uint8_t endpoint)
{
- EmberStatus status;
- emberAfFillCommandIasZoneClusterZoneEnrollRequest(
- EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE,
- EMBER_AF_MANUFACTURER_CODE);
- status = sendToClient(endpoint);
- if (status == EMBER_SUCCESS) {
- emberAfIasZoneClusterPrintln("Sent enroll request to IAS Zone client.");
- } else {
- emberAfIasZoneClusterPrintln("Error sending enroll request: 0x%x\n",
- status);
- }
+ EmberStatus status;
+ emberAfFillCommandIasZoneClusterZoneEnrollRequest(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE, EMBER_AF_MANUFACTURER_CODE);
+ status = sendToClient(endpoint);
+ if (status == EMBER_SUCCESS)
+ {
+ emberAfIasZoneClusterPrintln("Sent enroll request to IAS Zone client.");
+ }
+ else
+ {
+ emberAfIasZoneClusterPrintln("Error sending enroll request: 0x%x\n", status);
+ }
}
-EmberAfStatus emberAfIasZoneClusterServerPreAttributeChangedCallback(
- uint8_t endpoint,
- EmberAfAttributeId attributeId,
- EmberAfAttributeType attributeType,
- uint8_t size,
- uint8_t *value)
+EmberAfStatus emberAfIasZoneClusterServerPreAttributeChangedCallback(uint8_t endpoint, EmberAfAttributeId attributeId,
+ EmberAfAttributeType attributeType, uint8_t size,
+ uint8_t * value)
{
- uint8_t i;
- bool zeroAddress;
- EmberBindingTableEntry bindingEntry;
- EmberBindingTableEntry currentBind;
- EmberEUI64 destEUI;
- uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ uint8_t i;
+ bool zeroAddress;
+ EmberBindingTableEntry bindingEntry;
+ EmberBindingTableEntry currentBind;
+ EmberEUI64 destEUI;
+ uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- // If this is not a CIE Address write, the CIE address has already been
- // written, or the IAS Zone server is already enrolled, do nothing.
- if (attributeId != ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID
- || emberAfCurrentCommand() == NULL) {
+ // If this is not a CIE Address write, the CIE address has already been
+ // written, or the IAS Zone server is already enrolled, do nothing.
+ if (attributeId != ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID || emberAfCurrentCommand() == NULL)
+ {
+ return EMBER_ZCL_STATUS_SUCCESS;
+ }
+
+ MEMCOPY(destEUI, value, EUI64_SIZE);
+
+ // Create the binding table entry
+
+ // This code assumes that the endpoint and device that is setting the CIE
+ // address is the CIE device itself, and as such the remote endpoint to bind
+ // to is the endpoint that generated the attribute change. This
+ // assumption is made based on analysis of the behavior of CIE devices
+ // currently existing in the field.
+ bindingEntry.type = EMBER_UNICAST_BINDING;
+ bindingEntry.local = endpoint;
+ bindingEntry.clusterId = ZCL_IAS_ZONE_CLUSTER_ID;
+ bindingEntry.remote = emberAfCurrentCommand()->apsFrame->sourceEndpoint;
+ MEMCOPY(bindingEntry.identifier, destEUI, EUI64_SIZE);
+
+ // Cycle through the binding table until we find a valid entry that is not
+ // being used, then use the created entry to make the bind.
+ for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++)
+ {
+ if (emberGetBinding(i, ¤tBind) != EMBER_SUCCESS)
+ {
+ // break out of the loop to ensure that an error message still prints
+ break;
+ }
+ if (currentBind.type != EMBER_UNUSED_BINDING)
+ {
+ // If the binding table entry created based on the response already exists
+ // do nothing.
+ if ((currentBind.local == bindingEntry.local) && (currentBind.clusterId == bindingEntry.clusterId) &&
+ (currentBind.remote == bindingEntry.remote) && (currentBind.type == bindingEntry.type))
+ {
+ break;
+ }
+ // If this spot in the binding table already exists, move on to the next
+ continue;
+ }
+ else
+ {
+ emberSetBinding(i, &bindingEntry);
+ break;
+ }
+ }
+
+ zeroAddress = true;
+ emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, (uint8_t *) ieeeAddress, 8);
+ for (i = 0; i < 8; i++)
+ {
+ if (ieeeAddress[i] != 0)
+ {
+ zeroAddress = false;
+ }
+ }
+ emberAfAppPrint("\nzero address: %d\n", zeroAddress);
+
+ if ((zeroAddress == true) && (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST))
+ {
+ // Only send the enrollment request if the mode is AUTO-ENROLL-REQUEST.
+ // We need to delay to get around a bug where we can't send a command
+ // at this point because then the Write Attributes response will not
+ // be sent. But we also delay to give the client time to configure us.
+ emberAfIasZoneClusterPrintln("Sending enrollment after %d ms", DELAY_TIMER_MS);
+ emberAfScheduleServerTickExtended(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, DELAY_TIMER_MS, EMBER_AF_SHORT_POLL,
+ EMBER_AF_STAY_AWAKE);
+ }
+
return EMBER_ZCL_STATUS_SUCCESS;
- }
-
- MEMCOPY(destEUI, value, EUI64_SIZE);
-
- // Create the binding table entry
-
- // This code assumes that the endpoint and device that is setting the CIE
- // address is the CIE device itself, and as such the remote endpoint to bind
- // to is the endpoint that generated the attribute change. This
- // assumption is made based on analysis of the behavior of CIE devices
- // currently existing in the field.
- bindingEntry.type = EMBER_UNICAST_BINDING;
- bindingEntry.local = endpoint;
- bindingEntry.clusterId = ZCL_IAS_ZONE_CLUSTER_ID;
- bindingEntry.remote = emberAfCurrentCommand()->apsFrame->sourceEndpoint;
- MEMCOPY(bindingEntry.identifier, destEUI, EUI64_SIZE);
-
- // Cycle through the binding table until we find a valid entry that is not
- // being used, then use the created entry to make the bind.
- for (i = 0; i < EMBER_BINDING_TABLE_SIZE; i++) {
- if (emberGetBinding(i, ¤tBind) != EMBER_SUCCESS) {
- //break out of the loop to ensure that an error message still prints
- break;
- }
- if (currentBind.type != EMBER_UNUSED_BINDING) {
- // If the binding table entry created based on the response already exists
- // do nothing.
- if ((currentBind.local == bindingEntry.local)
- && (currentBind.clusterId == bindingEntry.clusterId)
- && (currentBind.remote == bindingEntry.remote)
- && (currentBind.type == bindingEntry.type)) {
- break;
- }
- // If this spot in the binding table already exists, move on to the next
- continue;
- } else {
- emberSetBinding(i, &bindingEntry);
- break;
- }
- }
-
- zeroAddress = true;
- emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID,
- (uint8_t*)ieeeAddress,
- 8);
- for (i = 0; i < 8; i++) {
- if (ieeeAddress[i] != 0) {
- zeroAddress = false;
- }
- }
- emberAfAppPrint("\nzero address: %d\n", zeroAddress);
-
- if ((zeroAddress == true) && (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST)) {
- // Only send the enrollment request if the mode is AUTO-ENROLL-REQUEST.
- // We need to delay to get around a bug where we can't send a command
- // at this point because then the Write Attributes response will not
- // be sent. But we also delay to give the client time to configure us.
- emberAfIasZoneClusterPrintln("Sending enrollment after %d ms",
- DELAY_TIMER_MS);
- emberAfScheduleServerTickExtended(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- DELAY_TIMER_MS,
- EMBER_AF_SHORT_POLL,
- EMBER_AF_STAY_AWAKE);
- }
-
- return EMBER_ZCL_STATUS_SUCCESS;
}
-EmberAfStatus emberAfPluginIasZoneClusterSetEnrollmentMethod(uint8_t endpoint,
- EmberAfIasZoneEnrollmentMode method)
+EmberAfStatus emberAfPluginIasZoneClusterSetEnrollmentMethod(uint8_t endpoint, EmberAfIasZoneEnrollmentMode method)
{
- EmberAfStatus status;
+ EmberAfStatus status;
- if (emberAfIasZoneClusterAmIEnrolled(endpoint)) {
- emberAfIasZoneClusterPrintln("Error: Already enrolled");
- status = EMBER_ZCL_STATUS_NOT_AUTHORIZED;
- } else if (!isValidEnrollmentMode(method)) {
- emberAfIasZoneClusterPrintln("Invalid IAS Zone Server Enrollment Mode: %d", method);
- status = EMBER_ZCL_STATUS_INVALID_VALUE;
- } else {
- enrollmentMethod = method;
+ if (emberAfIasZoneClusterAmIEnrolled(endpoint))
+ {
+ emberAfIasZoneClusterPrintln("Error: Already enrolled");
+ status = EMBER_ZCL_STATUS_NOT_AUTHORIZED;
+ }
+ else if (!isValidEnrollmentMode(method))
+ {
+ emberAfIasZoneClusterPrintln("Invalid IAS Zone Server Enrollment Mode: %d", method);
+ status = EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
+ else
+ {
+ enrollmentMethod = method;
#ifndef EZSP_HOST
- halCommonSetToken(TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD, &enrollmentMethod);
+ halCommonSetToken(TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD, &enrollmentMethod);
#endif
- emberAfIasZoneClusterPrintln("IAS Zone Server Enrollment Mode: %d", method);
- status = EMBER_ZCL_STATUS_SUCCESS;
- }
- return status;
+ emberAfIasZoneClusterPrintln("IAS Zone Server Enrollment Mode: %d", method);
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ }
+ return status;
}
static boolean isValidEnrollmentMode(EmberAfIasZoneEnrollmentMode method)
{
- return ((method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR)
- || (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_AUTO_ENROLLMENT_RESPONSE)
- || (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST));
+ return ((method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR) ||
+ (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_AUTO_ENROLLMENT_RESPONSE) ||
+ (method == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST));
}
bool emberAfIasZoneClusterAmIEnrolled(uint8_t endpoint)
{
- EmberAfIasZoneState zoneState = 0; // Clear this out completely.
- EmberAfStatus status;
- status = emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_STATE_ATTRIBUTE_ID,
- (unsigned char*)&zoneState,
- 1); // uint8_t size
+ EmberAfIasZoneState zoneState = 0; // Clear this out completely.
+ EmberAfStatus status;
+ status =
+ emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_STATE_ATTRIBUTE_ID, (unsigned char *) &zoneState,
+ 1); // uint8_t size
- return (status == EMBER_ZCL_STATUS_SUCCESS
- && zoneState == EMBER_ZCL_IAS_ZONE_STATE_ENROLLED);
+ return (status == EMBER_ZCL_STATUS_SUCCESS && zoneState == EMBER_ZCL_IAS_ZONE_STATE_ENROLLED);
}
static void updateEnrollState(uint8_t endpoint, bool enrolled)
{
- EmberAfIasZoneState zoneState = (enrolled
- ? EMBER_ZCL_IAS_ZONE_STATE_ENROLLED
- : EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED);
+ EmberAfIasZoneState zoneState = (enrolled ? EMBER_ZCL_IAS_ZONE_STATE_ENROLLED : EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED);
- emberAfWriteServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_STATE_ATTRIBUTE_ID,
- (uint8_t*)&zoneState,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- emberAfIasZoneClusterPrintln("IAS Zone Server State: %pEnrolled",
- (enrolled
- ? ""
- : "NOT "));
+ emberAfWriteServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_STATE_ATTRIBUTE_ID, (uint8_t *) &zoneState,
+ ZCL_INT8U_ATTRIBUTE_TYPE);
+ emberAfIasZoneClusterPrintln("IAS Zone Server State: %pEnrolled", (enrolled ? "" : "NOT "));
}
-bool emberAfIasZoneClusterZoneEnrollResponseCallback(uint8_t enrollResponseCode,
- uint8_t zoneId)
+bool emberAfIasZoneClusterZoneEnrollResponseCallback(uint8_t enrollResponseCode, uint8_t zoneId)
{
- uint8_t endpoint;
- uint8_t epZoneId;
- EmberAfStatus status;
+ uint8_t endpoint;
+ uint8_t epZoneId;
+ EmberAfStatus status;
- endpoint = emberAfCurrentEndpoint();
- status = emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_ID_ATTRIBUTE_ID,
- &epZoneId,
- sizeof(uint8_t));
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- if (enrollResponseCode == EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS) {
- updateEnrollState(endpoint, true);
- setZoneId(endpoint, zoneId);
- } else {
- updateEnrollState(endpoint, false);
- setZoneId(endpoint, UNDEFINED_ZONE_ID);
+ endpoint = emberAfCurrentEndpoint();
+ status = emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_ID_ATTRIBUTE_ID, &epZoneId, sizeof(uint8_t));
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ if (enrollResponseCode == EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS)
+ {
+ updateEnrollState(endpoint, true);
+ setZoneId(endpoint, zoneId);
+ }
+ else
+ {
+ updateEnrollState(endpoint, false);
+ setZoneId(endpoint, UNDEFINED_ZONE_ID);
+ }
+
+ return true;
}
+ emberAfAppPrintln("ERROR: IAS Zone Server unable to read zone ID attribute");
return true;
- }
-
- emberAfAppPrintln("ERROR: IAS Zone Server unable to read zone ID attribute");
- return true;
}
-static EmberStatus sendZoneUpdate(uint16_t zoneStatus,
- uint16_t timeSinceStatusOccurredQs,
- uint8_t endpoint)
+static EmberStatus sendZoneUpdate(uint16_t zoneStatus, uint16_t timeSinceStatusOccurredQs, uint8_t endpoint)
{
- EmberStatus status;
+ EmberStatus status;
- if (!emberAfIasZoneClusterAmIEnrolled(endpoint)) {
- return EMBER_INVALID_CALL;
- }
- emberAfFillCommandIasZoneClusterZoneStatusChangeNotification(
- zoneStatus,
- 0, // extended status, must be zero per spec
- emberAfPluginIasZoneServerGetZoneId(endpoint),
- timeSinceStatusOccurredQs); // called "delay" in the spec
- status = sendToClient(endpoint);
+ if (!emberAfIasZoneClusterAmIEnrolled(endpoint))
+ {
+ return EMBER_INVALID_CALL;
+ }
+ emberAfFillCommandIasZoneClusterZoneStatusChangeNotification(zoneStatus,
+ 0, // extended status, must be zero per spec
+ emberAfPluginIasZoneServerGetZoneId(endpoint),
+ timeSinceStatusOccurredQs); // called "delay" in the spec
+ status = sendToClient(endpoint);
- return status;
+ return status;
}
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
-static void addNewEntryToQueue(const IasZoneStatusQueueEntry *newEntry)
+static void addNewEntryToQueue(const IasZoneStatusQueueEntry * newEntry)
{
- emberAfIasZoneClusterPrintln("Adding new entry to queue");
- copyToBuffer(&messageQueue, newEntry);
+ emberAfIasZoneClusterPrintln("Adding new entry to queue");
+ copyToBuffer(&messageQueue, newEntry);
}
#endif
-EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(
- uint8_t endpoint,
- uint16_t newStatus,
- uint16_t timeSinceStatusOccurredQs)
+EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(uint8_t endpoint, uint16_t newStatus, uint16_t timeSinceStatusOccurredQs)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- IasZoneStatusQueueEntry newBufferEntry;
- newBufferEntry.endpoint = endpoint;
- newBufferEntry.status = newStatus;
- newBufferEntry.eventTimeMs = halCommonGetInt32uMillisecondTick();
+ IasZoneStatusQueueEntry newBufferEntry;
+ newBufferEntry.endpoint = endpoint;
+ newBufferEntry.status = newStatus;
+ newBufferEntry.eventTimeMs = halCommonGetInt32uMillisecondTick();
#endif
- EmberStatus sendStatus;
+ EmberStatus sendStatus;
- emberAfWriteServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_STATUS_ATTRIBUTE_ID,
- (uint8_t*)&newStatus,
- ZCL_INT16U_ATTRIBUTE_TYPE);
+ emberAfWriteServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_STATUS_ATTRIBUTE_ID, (uint8_t *) &newStatus,
+ ZCL_INT16U_ATTRIBUTE_TYPE);
- if (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR) {
- // If unenrolled, send Zone Enroll Request command.
- if (!emberAfIasZoneClusterAmIEnrolled(endpoint)) {
- emberAfScheduleServerTick(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- DELAY_TIMER_MS);
- // Don't send the zone status update since not enrolled.
- return EMBER_SUCCESS;
+ if (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR)
+ {
+ // If unenrolled, send Zone Enroll Request command.
+ if (!emberAfIasZoneClusterAmIEnrolled(endpoint))
+ {
+ emberAfScheduleServerTick(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, DELAY_TIMER_MS);
+ // Don't send the zone status update since not enrolled.
+ return EMBER_SUCCESS;
+ }
}
- }
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- // If there are items in the queue waiting to send, this event should not
- // be transmitted, as that could cause the client to receive the events out
- // of order. Instead, just add the device to the queue
- if (messageQueue.entriesInQueue == 0) {
- sendStatus = sendZoneUpdate(newStatus,
- timeSinceStatusOccurredQs,
- endpoint);
- } else {
- // Add a new element to the status queue and depending on the network state
- // either try to resend the first element in the queue immediately or try to
- // restart the parent research pattern.
- addNewEntryToQueue(&newBufferEntry);
-
- EmberNetworkStatus networkState = emberAfNetworkState();
-
- if (networkState == EMBER_JOINED_NETWORK_NO_PARENT) {
- emberAfStartMoveCallback();
- } else if (networkState == EMBER_JOINED_NETWORK) {
- resetCurrentQueueRetryParams();
- emberEventControlSetActive(emberAfPluginIasZoneServerManageQueueEventControl);
+ // If there are items in the queue waiting to send, this event should not
+ // be transmitted, as that could cause the client to receive the events out
+ // of order. Instead, just add the device to the queue
+ if (messageQueue.entriesInQueue == 0)
+ {
+ sendStatus = sendZoneUpdate(newStatus, timeSinceStatusOccurredQs, endpoint);
}
+ else
+ {
+ // Add a new element to the status queue and depending on the network state
+ // either try to resend the first element in the queue immediately or try to
+ // restart the parent research pattern.
+ addNewEntryToQueue(&newBufferEntry);
- return EMBER_SUCCESS;
- }
+ EmberNetworkStatus networkState = emberAfNetworkState();
+
+ if (networkState == EMBER_JOINED_NETWORK_NO_PARENT)
+ {
+ emberAfStartMoveCallback();
+ }
+ else if (networkState == EMBER_JOINED_NETWORK)
+ {
+ resetCurrentQueueRetryParams();
+ emberEventControlSetActive(emberAfPluginIasZoneServerManageQueueEventControl);
+ }
+
+ return EMBER_SUCCESS;
+ }
#else
- sendStatus = sendZoneUpdate(newStatus, timeSinceStatusOccurredQs, endpoint);
+ sendStatus = sendZoneUpdate(newStatus, timeSinceStatusOccurredQs, endpoint);
#endif
- if (sendStatus == EMBER_SUCCESS) {
+ if (sendStatus == EMBER_SUCCESS)
+ {
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- // Add a new entry to the zoneUpdate buffer
- addNewEntryToQueue(&newBufferEntry);
-#endif
- } else {
- // If we're not on a network and never were, we don't need to do anything.
- // If we used to be on a network and can't talk to our parent, we should
- // try to rejoin the network and add the message to the queue
- if (emberAfNetworkState() == EMBER_JOINED_NETWORK_NO_PARENT) {
- emberAfStartMoveCallback();
-#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- // Add a new entry to the zoneUpdate buffer
- addNewEntryToQueue(&newBufferEntry);
+ // Add a new entry to the zoneUpdate buffer
+ addNewEntryToQueue(&newBufferEntry);
#endif
}
- emberAfIasZoneClusterPrintln("Failed to send IAS Zone update. Err 0x%x",
- sendStatus);
- }
- return sendStatus;
+ else
+ {
+ // If we're not on a network and never were, we don't need to do anything.
+ // If we used to be on a network and can't talk to our parent, we should
+ // try to rejoin the network and add the message to the queue
+ if (emberAfNetworkState() == EMBER_JOINED_NETWORK_NO_PARENT)
+ {
+ emberAfStartMoveCallback();
+#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
+ // Add a new entry to the zoneUpdate buffer
+ addNewEntryToQueue(&newBufferEntry);
+#endif
+ }
+ emberAfIasZoneClusterPrintln("Failed to send IAS Zone update. Err 0x%x", sendStatus);
+ }
+ return sendStatus;
}
void emberAfPluginIasZoneServerManageQueueEventHandler(void)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- IasZoneStatusQueueEntry *bufferStart;
- uint16_t status;
- uint16_t elapsedTimeQs;
- uint16_t airTimeRemainingMs;
+ IasZoneStatusQueueEntry * bufferStart;
+ uint16_t status;
+ uint16_t elapsedTimeQs;
+ uint16_t airTimeRemainingMs;
- //If the queue was emptied without our interaction, do nothing
- if (messageQueue.entriesInQueue == 0) {
- emberEventControlSetInactive(
- emberAfPluginIasZoneServerManageQueueEventControl);
- return;
- }
+ // If the queue was emptied without our interaction, do nothing
+ if (messageQueue.entriesInQueue == 0)
+ {
+ emberEventControlSetInactive(emberAfPluginIasZoneServerManageQueueEventControl);
+ return;
+ }
- // Otherwise, pull out the first item and attempt to retransmit it. The
- // message complete callback will handle removing items from the queue
+ // Otherwise, pull out the first item and attempt to retransmit it. The
+ // message complete callback will handle removing items from the queue
- // To prevent an activity storm from flooding with retry requests, only
- // re-send a message if it's been at least
- // EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS since it was sent.
- bufferStart = &(messageQueue.buffer[messageQueue.startIdx]);
- elapsedTimeQs = computeElapsedTimeQs(bufferStart);
+ // To prevent an activity storm from flooding with retry requests, only
+ // re-send a message if it's been at least
+ // EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS since it was sent.
+ bufferStart = &(messageQueue.buffer[messageQueue.startIdx]);
+ elapsedTimeQs = computeElapsedTimeQs(bufferStart);
- if (elapsedTimeQs < (EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS
- / (MILLISECOND_TICKS_PER_SECOND / 4))) {
- airTimeRemainingMs = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS
- - (elapsedTimeQs * MILLISECOND_TICKS_PER_SECOND / 4);
- emberAfIasZoneClusterPrintln(
- "Not enough time passed for a retry, sleeping %d more mS",
- airTimeRemainingMs);
- emberEventControlSetDelayMS(
- emberAfPluginIasZoneServerManageQueueEventControl,
- airTimeRemainingMs);
- } else {
- status = bufferStart->status;
- emberAfIasZoneClusterPrintln(
- "Attempting to resend a queued zone status update (status: 0x%02X, "
- "event time (s): %d) with time of %d. Retry count: %d",
- bufferStart->status,
- bufferStart->eventTimeMs / MILLISECOND_TICKS_PER_SECOND,
- elapsedTimeQs,
- queueRetryParams.currentRetryCount);
- sendZoneUpdate(status, elapsedTimeQs, bufferStart->endpoint);
- emberEventControlSetInactive(
- emberAfPluginIasZoneServerManageQueueEventControl);
- }
+ if (elapsedTimeQs < (EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS / (MILLISECOND_TICKS_PER_SECOND / 4)))
+ {
+ airTimeRemainingMs = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MIN_OTA_TIME_MS - (elapsedTimeQs * MILLISECOND_TICKS_PER_SECOND / 4);
+ emberAfIasZoneClusterPrintln("Not enough time passed for a retry, sleeping %d more mS", airTimeRemainingMs);
+ emberEventControlSetDelayMS(emberAfPluginIasZoneServerManageQueueEventControl, airTimeRemainingMs);
+ }
+ else
+ {
+ status = bufferStart->status;
+ emberAfIasZoneClusterPrintln("Attempting to resend a queued zone status update (status: 0x%02X, "
+ "event time (s): %d) with time of %d. Retry count: %d",
+ bufferStart->status, bufferStart->eventTimeMs / MILLISECOND_TICKS_PER_SECOND, elapsedTimeQs,
+ queueRetryParams.currentRetryCount);
+ sendZoneUpdate(status, elapsedTimeQs, bufferStart->endpoint);
+ emberEventControlSetInactive(emberAfPluginIasZoneServerManageQueueEventControl);
+ }
#else
- emberEventControlSetInactive(
- emberAfPluginIasZoneServerManageQueueEventControl);
+ emberEventControlSetInactive(emberAfPluginIasZoneServerManageQueueEventControl);
#endif
}
void emberAfIasZoneClusterServerInitCallback(uint8_t endpoint)
{
- EmberAfIasZoneType zoneType;
- if (!areZoneServerAttributesTokenized(endpoint)) {
- emberAfAppPrint("WARNING: ATTRIBUTES ARE NOT BEING STORED IN FLASH! ");
- emberAfAppPrintln("DEVICE WILL NOT FUNCTION PROPERLY AFTER REBOOTING!!");
- }
+ EmberAfIasZoneType zoneType;
+ if (!areZoneServerAttributesTokenized(endpoint))
+ {
+ emberAfAppPrint("WARNING: ATTRIBUTES ARE NOT BEING STORED IN FLASH! ");
+ emberAfAppPrintln("DEVICE WILL NOT FUNCTION PROPERLY AFTER REBOOTING!!");
+ }
#ifndef EZSP_HOST
- halCommonGetToken(&enrollmentMethod, TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD);
+ halCommonGetToken(&enrollmentMethod, TOKEN_PLUGIN_IAS_ZONE_SERVER_ENROLLMENT_METHOD);
#else
- enrollmentMethod = DEFAULT_ENROLLMENT_METHOD;
-#endif
- if (!isValidEnrollmentMode(enrollmentMethod)) {
- // Default Enrollment Method to AUTO-ENROLL-REQUEST.
enrollmentMethod = DEFAULT_ENROLLMENT_METHOD;
- }
+#endif
+ if (!isValidEnrollmentMode(enrollmentMethod))
+ {
+ // Default Enrollment Method to AUTO-ENROLL-REQUEST.
+ enrollmentMethod = DEFAULT_ENROLLMENT_METHOD;
+ }
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- bufferInit(&messageQueue);
+ bufferInit(&messageQueue);
#endif
- zoneType = (EmberAfIasZoneType)EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE;
- emberAfWriteAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_TYPE_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t*)&zoneType,
- ZCL_INT16U_ATTRIBUTE_TYPE);
+ zoneType = (EmberAfIasZoneType) EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE;
+ emberAfWriteAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_TYPE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER, (uint8_t *) &zoneType,
+ ZCL_INT16U_ATTRIBUTE_TYPE);
- emberAfPluginIasZoneServerUpdateZoneStatus(endpoint,
- 0, // status: All alarms cleared
- 0); // time since status occurred
+ emberAfPluginIasZoneServerUpdateZoneStatus(endpoint,
+ 0, // status: All alarms cleared
+ 0); // time since status occurred
}
void emberAfIasZoneClusterServerTickCallback(uint8_t endpoint)
{
- enrollWithClient(endpoint);
+ enrollWithClient(endpoint);
}
uint8_t emberAfPluginIasZoneServerGetZoneId(uint8_t endpoint)
{
- uint8_t zoneId = UNDEFINED_ZONE_ID;
- emberAfReadServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_ID_ATTRIBUTE_ID,
- &zoneId,
- emberAfGetDataSize(ZCL_INT8U_ATTRIBUTE_TYPE));
- return zoneId;
+ uint8_t zoneId = UNDEFINED_ZONE_ID;
+ emberAfReadServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_ID_ATTRIBUTE_ID, &zoneId,
+ emberAfGetDataSize(ZCL_INT8U_ATTRIBUTE_TYPE));
+ return zoneId;
}
//------------------------------------------------------------------------------
@@ -586,162 +563,136 @@
//------------------------------------------------------------------------------
static bool areZoneServerAttributesTokenized(uint8_t endpoint)
{
- EmberAfAttributeMetadata *metadata;
+ EmberAfAttributeMetadata * metadata;
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_STATE_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_STATE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_TYPE_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_TYPE_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_ID_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_ID_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- return true;
+ return true;
}
static void setZoneId(uint8_t endpoint, uint8_t zoneId)
{
- emberAfIasZoneClusterPrintln("IAS Zone Server Zone ID: 0x%X", zoneId);
- emberAfWriteServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_ID_ATTRIBUTE_ID,
- &zoneId,
- ZCL_INT8U_ATTRIBUTE_TYPE);
+ emberAfIasZoneClusterPrintln("IAS Zone Server Zone ID: 0x%X", zoneId);
+ emberAfWriteServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_ID_ATTRIBUTE_ID, &zoneId, ZCL_INT8U_ATTRIBUTE_TYPE);
}
static void unenrollSecurityDevice(uint8_t endpoint)
{
- uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
- uint16_t zoneType = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE;
+ uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ uint16_t zoneType = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE;
- emberAfWriteServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID,
- (uint8_t*)ieeeAddress,
- ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE);
+ emberAfWriteServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, (uint8_t *) ieeeAddress,
+ ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE);
- emberAfWriteServerAttribute(endpoint,
- ZCL_IAS_ZONE_CLUSTER_ID,
- ZCL_ZONE_TYPE_ATTRIBUTE_ID,
- (uint8_t*)&zoneType,
- ZCL_INT16U_ATTRIBUTE_TYPE);
+ emberAfWriteServerAttribute(endpoint, ZCL_IAS_ZONE_CLUSTER_ID, ZCL_ZONE_TYPE_ATTRIBUTE_ID, (uint8_t *) &zoneType,
+ ZCL_INT16U_ATTRIBUTE_TYPE);
- setZoneId(endpoint, UNDEFINED_ZONE_ID);
- // Restore the enrollment method back to its default value.
- emberAfPluginIasZoneClusterSetEnrollmentMethod(endpoint,
- DEFAULT_ENROLLMENT_METHOD);
- updateEnrollState(endpoint, false); // enrolled?
+ setZoneId(endpoint, UNDEFINED_ZONE_ID);
+ // Restore the enrollment method back to its default value.
+ emberAfPluginIasZoneClusterSetEnrollmentMethod(endpoint, DEFAULT_ENROLLMENT_METHOD);
+ updateEnrollState(endpoint, false); // enrolled?
}
// If you leave the network, unenroll yourself.
void emberAfPluginIasZoneServerStackStatusCallback(EmberStatus status)
{
- uint8_t endpoint;
- uint8_t networkIndex;
- uint8_t i;
+ uint8_t endpoint;
+ uint8_t networkIndex;
+ uint8_t i;
- // If the device has left the network, unenroll all endpoints on the device
- // that are servers of the IAS Zone Cluster
- if (status == EMBER_NETWORK_DOWN
- && emberAfNetworkState() == EMBER_NO_NETWORK) {
- for (i = 0; i < emberAfEndpointCount(); i++) {
- endpoint = emberAfEndpointFromIndex(i);
- networkIndex = emberAfNetworkIndexFromEndpointIndex(i);
- if (networkIndex == emberGetCurrentNetwork()
- && emberAfContainsServer(endpoint, ZCL_IAS_ZONE_CLUSTER_ID)) {
- unenrollSecurityDevice(endpoint);
- }
+ // If the device has left the network, unenroll all endpoints on the device
+ // that are servers of the IAS Zone Cluster
+ if (status == EMBER_NETWORK_DOWN && emberAfNetworkState() == EMBER_NO_NETWORK)
+ {
+ for (i = 0; i < emberAfEndpointCount(); i++)
+ {
+ endpoint = emberAfEndpointFromIndex(i);
+ networkIndex = emberAfNetworkIndexFromEndpointIndex(i);
+ if (networkIndex == emberGetCurrentNetwork() && emberAfContainsServer(endpoint, ZCL_IAS_ZONE_CLUSTER_ID))
+ {
+ unenrollSecurityDevice(endpoint);
+ }
+ }
}
- } else if (status == EMBER_NETWORK_UP) {
+ else if (status == EMBER_NETWORK_UP)
+ {
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- // If we're reconnecting, send any items still in the queue
- emberAfIasZoneClusterPrintln(
- "Rejoined network, retransmiting any queued event");
- emberEventControlSetActive(
- emberAfPluginIasZoneServerManageQueueEventControl);
+ // If we're reconnecting, send any items still in the queue
+ emberAfIasZoneClusterPrintln("Rejoined network, retransmiting any queued event");
+ emberEventControlSetActive(emberAfPluginIasZoneServerManageQueueEventControl);
#endif
- }
+ }
}
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
-EmberStatus emberAfIasZoneServerConfigStatusQueueRetryParams(
- IasZoneStatusQueueRetryConfig *retryConfig)
+EmberStatus emberAfIasZoneServerConfigStatusQueueRetryParams(IasZoneStatusQueueRetryConfig * retryConfig)
{
- if (!(retryConfig->firstBackoffTimeSec)
- || (!retryConfig->backoffSeqCommonRatio)
- || (retryConfig->maxBackoffTimeSec < retryConfig->firstBackoffTimeSec)
- || (retryConfig->maxBackoffTimeSec > IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC)
- || (!retryConfig->maxRetryAttempts) ) {
- return EMBER_BAD_ARGUMENT;
- }
+ if (!(retryConfig->firstBackoffTimeSec) || (!retryConfig->backoffSeqCommonRatio) ||
+ (retryConfig->maxBackoffTimeSec < retryConfig->firstBackoffTimeSec) ||
+ (retryConfig->maxBackoffTimeSec > IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC) || (!retryConfig->maxRetryAttempts))
+ {
+ return EMBER_BAD_ARGUMENT;
+ }
- queueRetryParams.config.firstBackoffTimeSec = retryConfig->firstBackoffTimeSec;
- queueRetryParams.config.backoffSeqCommonRatio = retryConfig->backoffSeqCommonRatio;
- queueRetryParams.config.maxBackoffTimeSec = retryConfig->maxBackoffTimeSec;
- queueRetryParams.config.unlimitedRetries = retryConfig->unlimitedRetries;
- queueRetryParams.config.maxRetryAttempts = retryConfig->maxRetryAttempts;
+ queueRetryParams.config.firstBackoffTimeSec = retryConfig->firstBackoffTimeSec;
+ queueRetryParams.config.backoffSeqCommonRatio = retryConfig->backoffSeqCommonRatio;
+ queueRetryParams.config.maxBackoffTimeSec = retryConfig->maxBackoffTimeSec;
+ queueRetryParams.config.unlimitedRetries = retryConfig->unlimitedRetries;
+ queueRetryParams.config.maxRetryAttempts = retryConfig->maxRetryAttempts;
- queueRetryParams.currentBackoffTimeSec = retryConfig->firstBackoffTimeSec;
- queueRetryParams.currentRetryCount = 0;
+ queueRetryParams.currentBackoffTimeSec = retryConfig->firstBackoffTimeSec;
+ queueRetryParams.currentRetryCount = 0;
- return EMBER_SUCCESS;
+ return EMBER_SUCCESS;
}
void emberAfIasZoneServerSetStatusQueueRetryParamsToDefault(void)
{
- queueRetryParams.config.firstBackoffTimeSec =
- EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC;
- queueRetryParams.config.backoffSeqCommonRatio =
- EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO;
- queueRetryParams.config.maxBackoffTimeSec =
- EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC;
+ queueRetryParams.config.firstBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC;
+ queueRetryParams.config.backoffSeqCommonRatio = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_BACKOFF_SEQUENCE_COMMON_RATIO;
+ queueRetryParams.config.maxBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_BACKOFF_TIME_SEC;
#ifdef EMBER_AF_PLUGIN_IAS_ZONE_SERVER_UNLIMITED_RETRIES
- queueRetryParams.config.unlimitedRetries = true;
+ queueRetryParams.config.unlimitedRetries = true;
#else
- queueRetryParams.config.unlimitedRetries = false;
+ queueRetryParams.config.unlimitedRetries = false;
#endif
- queueRetryParams.config.maxRetryAttempts =
- EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS;
+ queueRetryParams.config.maxRetryAttempts = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_MAX_RETRY_ATTEMPTS;
- queueRetryParams.currentBackoffTimeSec =
- EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC;
- queueRetryParams.currentRetryCount = 0;
+ queueRetryParams.currentBackoffTimeSec = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_FIRST_BACKOFF_TIME_SEC;
+ queueRetryParams.currentRetryCount = 0;
}
void emberAfIasZoneServerDiscardPendingEventsInStatusQueue(void)
{
- emberEventControlSetInactive(
- emberAfPluginIasZoneServerManageQueueEventControl);
- bufferInit(&messageQueue);
- resetCurrentQueueRetryParams();
+ emberEventControlSetInactive(emberAfPluginIasZoneServerManageQueueEventControl);
+ bufferInit(&messageQueue);
+ resetCurrentQueueRetryParams();
}
#if defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER)
@@ -750,43 +701,35 @@
uint32_t maxBackoffTimeSeconds,
uint8_t maxRedeliveryAttempts)
{
- IasZoneStatusQueueRetryConfig retryConfig = {
- firstBackoffTimeSeconds,
- backoffSeqCommonRatio,
- maxBackoffTimeSeconds,
- (maxRedeliveryAttempts == 0xFF),
- maxRedeliveryAttempts
- };
+ IasZoneStatusQueueRetryConfig retryConfig = { firstBackoffTimeSeconds, backoffSeqCommonRatio, maxBackoffTimeSeconds,
+ (maxRedeliveryAttempts == 0xFF), maxRedeliveryAttempts };
- // Setting up retry parameters
- return emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig);
+ // Setting up retry parameters
+ return emberAfIasZoneServerConfigStatusQueueRetryParams(&retryConfig);
}
void emberAfWwahAppEventRetryManagerSetBackoffParamsToDefault(void)
{
- emberAfIasZoneServerSetStatusQueueRetryParamsToDefault();
+ emberAfIasZoneServerSetStatusQueueRetryParamsToDefault();
}
#endif // defined(EMBER_AF_PLUGIN_WWAH_APP_EVENT_RETRY_MANAGER)
void emberAfPluginIasZoneServerPrintQueue(void)
{
- emberAfIasZoneClusterPrintln("%d/%d entries", messageQueue.entriesInQueue, NUM_QUEUE_ENTRIES);
- for (int i = 0; i < messageQueue.entriesInQueue; i++) {
- emberAfIasZoneClusterPrintln("Entry %d: Endpoint: %d Status: %d EventTimeMs: %d",
- i,
- messageQueue.buffer[i].endpoint,
- messageQueue.buffer[i].status,
- messageQueue.buffer[i].eventTimeMs
- );
- }
+ emberAfIasZoneClusterPrintln("%d/%d entries", messageQueue.entriesInQueue, NUM_QUEUE_ENTRIES);
+ for (int i = 0; i < messageQueue.entriesInQueue; i++)
+ {
+ emberAfIasZoneClusterPrintln("Entry %d: Endpoint: %d Status: %d EventTimeMs: %d", i, messageQueue.buffer[i].endpoint,
+ messageQueue.buffer[i].status, messageQueue.buffer[i].eventTimeMs);
+ }
}
void emberAfPluginIasZoneServerPrintQueueConfig(void)
{
- emberAfCorePrintln("First backoff time (sec): %d", queueRetryParams.config.firstBackoffTimeSec);
- emberAfCorePrintln("Backoff sequence common ratio: %d", queueRetryParams.config.backoffSeqCommonRatio);
- emberAfCorePrintln("Max backoff time (sec): %d", queueRetryParams.config.maxBackoffTimeSec);
- emberAfCorePrintln("Max redelivery attempts: %d", queueRetryParams.config.maxRetryAttempts);
+ emberAfCorePrintln("First backoff time (sec): %d", queueRetryParams.config.firstBackoffTimeSec);
+ emberAfCorePrintln("Backoff sequence common ratio: %d", queueRetryParams.config.backoffSeqCommonRatio);
+ emberAfCorePrintln("Max backoff time (sec): %d", queueRetryParams.config.maxBackoffTimeSec);
+ emberAfCorePrintln("Max redelivery attempts: %d", queueRetryParams.config.maxRetryAttempts);
}
#endif // defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
@@ -797,155 +740,158 @@
// destination when the destination is the only router the node is joined to.
// In that case, the command will never have been sent, as the device will have
// had no router by which to send the command.
-void emberAfIasZoneClusterServerMessageSentCallback(
- EmberOutgoingMessageType type,
- int16u indexOrDestination,
- EmberApsFrame *apsFrame,
- int16u msgLen,
- int8u *message,
- EmberStatus status)
+void emberAfIasZoneClusterServerMessageSentCallback(EmberOutgoingMessageType type, int16u indexOrDestination,
+ EmberApsFrame * apsFrame, int16u msgLen, int8u * message, EmberStatus status)
{
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
- uint8_t frameControl;
- uint8_t commandId;
+ uint8_t frameControl;
+ uint8_t commandId;
- IasZoneStatusQueueEntry dummyEntry;
+ IasZoneStatusQueueEntry dummyEntry;
- // Verify that this response is for a ZoneStatusChangeNotification command
- // by checking the message length, the command and direction bits of the
- // Frame Control byte, and the command ID
- if (msgLen < IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX) {
- return;
- }
-
- frameControl = message[ZCL_FRAME_CONTROL_IDX];
- if (!(frameControl & ZCL_CLUSTER_SPECIFIC_COMMAND)
- || !(frameControl & ZCL_FRAME_CONTROL_SERVER_TO_CLIENT)) {
- return;
- }
-
- commandId = message[IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX];
- if (commandId != ZCL_ZONE_STATUS_CHANGE_NOTIFICATION_COMMAND_ID) {
- return;
- }
-
- // If a change status change notification command is not received by the
- // client, delay the option specified amount of time and try to resend it.
- // The event handler will perform the retransmit per the preset queue retry
- // parameteres, and the original send request will handle populating the buffer.
- // Do not try to retransmit again if the maximum number of retries attempts
- // is reached, this is however discarded if configured for unlimited retries.
- if ((status == EMBER_DELIVERY_FAILED)
- && (queueRetryParams.config.unlimitedRetries
- || (queueRetryParams.currentRetryCount < queueRetryParams.config.maxRetryAttempts))) {
- queueRetryParams.currentRetryCount++;
-
- emberAfIasZoneClusterPrintln(
- "Status command update failed to send... Retrying in %d seconds...",
- queueRetryParams.currentBackoffTimeSec);
-
- // Delay according to the current retransmit backoff time.
- emberEventControlSetDelayMS(
- emberAfPluginIasZoneServerManageQueueEventControl,
- queueRetryParams.currentBackoffTimeSec * MILLISECOND_TICKS_PER_SECOND);
-
- // The backoff time needs to be increased if the maximum backoff time is not reached yet.
- if ((queueRetryParams.currentBackoffTimeSec * queueRetryParams.config.backoffSeqCommonRatio)
- <= queueRetryParams.config.maxBackoffTimeSec) {
- queueRetryParams.currentBackoffTimeSec *= queueRetryParams.config.backoffSeqCommonRatio;
+ // Verify that this response is for a ZoneStatusChangeNotification command
+ // by checking the message length, the command and direction bits of the
+ // Frame Control byte, and the command ID
+ if (msgLen < IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX)
+ {
+ return;
}
- } else {
- // If a command message was sent or max redelivery attempts were reached,
- // remove it from the queue and move on to the next queued message until the queue is empty.
- if (status == EMBER_SUCCESS) {
- emberAfIasZoneClusterPrintln(
- "\nZone update successful, remove entry from queue");
- } else {
- emberAfIasZoneClusterPrintln(
- "\nZone update unsuccessful, max retry attempts reached, remove entry from queue");
- }
- popFromBuffer(&messageQueue, &dummyEntry);
- // Reset queue retry parameters.
- resetCurrentQueueRetryParams();
-
- if (messageQueue.entriesInQueue) {
- emberEventControlSetActive(
- emberAfPluginIasZoneServerManageQueueEventControl);
+ frameControl = message[ZCL_FRAME_CONTROL_IDX];
+ if (!(frameControl & ZCL_CLUSTER_SPECIFIC_COMMAND) || !(frameControl & ZCL_FRAME_CONTROL_SERVER_TO_CLIENT))
+ {
+ return;
}
- }
+
+ commandId = message[IAS_ZONE_SERVER_PAYLOAD_COMMAND_IDX];
+ if (commandId != ZCL_ZONE_STATUS_CHANGE_NOTIFICATION_COMMAND_ID)
+ {
+ return;
+ }
+
+ // If a change status change notification command is not received by the
+ // client, delay the option specified amount of time and try to resend it.
+ // The event handler will perform the retransmit per the preset queue retry
+ // parameteres, and the original send request will handle populating the buffer.
+ // Do not try to retransmit again if the maximum number of retries attempts
+ // is reached, this is however discarded if configured for unlimited retries.
+ if ((status == EMBER_DELIVERY_FAILED) &&
+ (queueRetryParams.config.unlimitedRetries ||
+ (queueRetryParams.currentRetryCount < queueRetryParams.config.maxRetryAttempts)))
+ {
+ queueRetryParams.currentRetryCount++;
+
+ emberAfIasZoneClusterPrintln("Status command update failed to send... Retrying in %d seconds...",
+ queueRetryParams.currentBackoffTimeSec);
+
+ // Delay according to the current retransmit backoff time.
+ emberEventControlSetDelayMS(emberAfPluginIasZoneServerManageQueueEventControl,
+ queueRetryParams.currentBackoffTimeSec * MILLISECOND_TICKS_PER_SECOND);
+
+ // The backoff time needs to be increased if the maximum backoff time is not reached yet.
+ if ((queueRetryParams.currentBackoffTimeSec * queueRetryParams.config.backoffSeqCommonRatio) <=
+ queueRetryParams.config.maxBackoffTimeSec)
+ {
+ queueRetryParams.currentBackoffTimeSec *= queueRetryParams.config.backoffSeqCommonRatio;
+ }
+ }
+ else
+ {
+ // If a command message was sent or max redelivery attempts were reached,
+ // remove it from the queue and move on to the next queued message until the queue is empty.
+ if (status == EMBER_SUCCESS)
+ {
+ emberAfIasZoneClusterPrintln("\nZone update successful, remove entry from queue");
+ }
+ else
+ {
+ emberAfIasZoneClusterPrintln("\nZone update unsuccessful, max retry attempts reached, remove entry from queue");
+ }
+ popFromBuffer(&messageQueue, &dummyEntry);
+
+ // Reset queue retry parameters.
+ resetCurrentQueueRetryParams();
+
+ if (messageQueue.entriesInQueue)
+ {
+ emberEventControlSetActive(emberAfPluginIasZoneServerManageQueueEventControl);
+ }
+ }
#endif
}
#if defined(EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ENABLE_QUEUE)
-static void bufferInit(IasZoneStatusQueue *ring)
+static void bufferInit(IasZoneStatusQueue * ring)
{
- ring->entriesInQueue = 0;
- ring->startIdx = 0;
- ring->lastIdx = NUM_QUEUE_ENTRIES - 1;
+ ring->entriesInQueue = 0;
+ ring->startIdx = 0;
+ ring->lastIdx = NUM_QUEUE_ENTRIES - 1;
}
// Add the entry to the buffer by copying, returning the index at which it was
// added. If the buffer is full, return -1, but still copy the entry over the
// last item of the buffer, to ensure that the last item in the buffer is
// always representative of the last known device state.
-static int16_t copyToBuffer(IasZoneStatusQueue *ring,
- const IasZoneStatusQueueEntry *entry)
+static int16_t copyToBuffer(IasZoneStatusQueue * ring, const IasZoneStatusQueueEntry * entry)
{
- if (ring->entriesInQueue == NUM_QUEUE_ENTRIES) {
- ring->buffer[ring->lastIdx] = *entry;
- return -1;
- }
+ if (ring->entriesInQueue == NUM_QUEUE_ENTRIES)
+ {
+ ring->buffer[ring->lastIdx] = *entry;
+ return -1;
+ }
- // Increment the last pointer. If it rolls over the size, circle it back to
- // zero.
- ring->lastIdx++;
- if (ring->lastIdx >= NUM_QUEUE_ENTRIES) {
- ring->lastIdx = 0;
- }
+ // Increment the last pointer. If it rolls over the size, circle it back to
+ // zero.
+ ring->lastIdx++;
+ if (ring->lastIdx >= NUM_QUEUE_ENTRIES)
+ {
+ ring->lastIdx = 0;
+ }
- ring->buffer[ring->lastIdx].endpoint = entry->endpoint;
- ring->buffer[ring->lastIdx].status = entry->status;
- ring->buffer[ring->lastIdx].eventTimeMs = entry->eventTimeMs;
+ ring->buffer[ring->lastIdx].endpoint = entry->endpoint;
+ ring->buffer[ring->lastIdx].status = entry->status;
+ ring->buffer[ring->lastIdx].eventTimeMs = entry->eventTimeMs;
- ring->entriesInQueue++;
- return ring->lastIdx;
+ ring->entriesInQueue++;
+ return ring->lastIdx;
}
// Return the idx of the popped entry, or -1 if the buffer was empty.
-static int16_t popFromBuffer(IasZoneStatusQueue *ring,
- IasZoneStatusQueueEntry *entry)
+static int16_t popFromBuffer(IasZoneStatusQueue * ring, IasZoneStatusQueueEntry * entry)
{
- int16_t retVal;
+ int16_t retVal;
- if (ring->entriesInQueue == 0) {
- return -1;
- }
+ if (ring->entriesInQueue == 0)
+ {
+ return -1;
+ }
- // Copy out the first entry, then increment the start pointer. If it rolls
- // over, circle it back to zero.
- *entry = ring->buffer[ring->startIdx];
- retVal = ring->startIdx;
+ // Copy out the first entry, then increment the start pointer. If it rolls
+ // over, circle it back to zero.
+ *entry = ring->buffer[ring->startIdx];
+ retVal = ring->startIdx;
- ring->startIdx++;
- if (ring->startIdx >= NUM_QUEUE_ENTRIES) {
- ring->startIdx = 0;
- }
+ ring->startIdx++;
+ if (ring->startIdx >= NUM_QUEUE_ENTRIES)
+ {
+ ring->startIdx = 0;
+ }
- ring->entriesInQueue--;
+ ring->entriesInQueue--;
- return retVal;
+ return retVal;
}
-uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry *entry)
+uint16_t computeElapsedTimeQs(IasZoneStatusQueueEntry * entry)
{
- uint32_t currentTimeMs = halCommonGetInt32uMillisecondTick();
- int64_t deltaTimeMs = currentTimeMs - entry->eventTimeMs;
+ uint32_t currentTimeMs = halCommonGetInt32uMillisecondTick();
+ int64_t deltaTimeMs = currentTimeMs - entry->eventTimeMs;
- if (deltaTimeMs < 0) {
- deltaTimeMs = -deltaTimeMs + (0xFFFFFFFF - currentTimeMs);
- }
+ if (deltaTimeMs < 0)
+ {
+ deltaTimeMs = -deltaTimeMs + (0xFFFFFFFF - currentTimeMs);
+ }
- return deltaTimeMs / MILLISECOND_TICKS_PER_QUARTERSECOND;
+ return deltaTimeMs / MILLISECOND_TICKS_PER_QUARTERSECOND;
}
#endif
diff --git a/src/app/clusters/ias-zone-server/ias-zone-server.h b/src/app/clusters/ias-zone-server/ias-zone-server.h
index 43bc869..a06e563 100644
--- a/src/app/clusters/ias-zone-server/ias-zone-server.h
+++ b/src/app/clusters/ias-zone-server/ias-zone-server.h
@@ -31,38 +31,42 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief This is the source for the plugin used to add an IAS Zone cluster server
- * to a project. This source handles zone enrollment and storing of
- * attributes from a CIE device and provides an API for different plugins to
- * post updated zone status values.
+ * @brief This is the source for the plugin used to
+ *add an IAS Zone cluster server to a project. This
+ *source handles zone enrollment and storing of
+ * attributes from a CIE device and provides an API
+ *for different plugins to post updated zone status
+ *values.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
//-----------------------------------------------------------------------------
#ifndef SILABS_IAS_ZONE_SERVER_H
#define SILABS_IAS_ZONE_SERVER_H
-#define EM_AF_UNKNOWN_ENDPOINT 0
+#define EM_AF_UNKNOWN_ENDPOINT 0
// Absolute max backoff time, at least one retry a day
// (ie. 24 hours * 60 minutes * 60 seconds).
#define IAS_ZONE_STATUS_QUEUE_RETRY_ABS_MAX_BACKOFF_TIME_SEC (24 * 60 * 60)
// Definitions for the IAS Zone enrollment mode.
-typedef enum {
- EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR = 0x00,
- EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_AUTO_ENROLLMENT_RESPONSE = 0x01,
- EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST = 0x02
+typedef enum
+{
+ EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR = 0x00,
+ EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_AUTO_ENROLLMENT_RESPONSE = 0x01,
+ EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_REQUEST = 0x02
} EmberAfIasZoneEnrollmentMode;
// Status queue retry parameters
-typedef struct {
- uint8_t firstBackoffTimeSec;
- uint8_t backoffSeqCommonRatio;
- uint32_t maxBackoffTimeSec;
- bool unlimitedRetries;
- uint8_t maxRetryAttempts;
+typedef struct
+{
+ uint8_t firstBackoffTimeSec;
+ uint8_t backoffSeqCommonRatio;
+ uint32_t maxBackoffTimeSec;
+ bool unlimitedRetries;
+ uint8_t maxRetryAttempts;
} IasZoneStatusQueueRetryConfig;
/** @brief Updates the zone status for an endpoint.
@@ -79,10 +83,7 @@
* @return EMBER_SUCCESS if the attribute update and notify succeeded, error
* code otherwise.
*/
-EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(
- uint8_t endpoint,
- uint16_t newStatus,
- uint16_t timeSinceStatusOccurredQs);
+EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(uint8_t endpoint, uint16_t newStatus, uint16_t timeSinceStatusOccurredQs);
/** @brief Gets the CIE assigned zone id of a given endpoint.
*
@@ -115,8 +116,7 @@
*
* @return An ::EmberAfStatus value indicating the status of the set action.
*/
-EmberAfStatus emberAfPluginIasZoneClusterSetEnrollmentMethod(uint8_t endpoint,
- EmberAfIasZoneEnrollmentMode method);
+EmberAfStatus emberAfPluginIasZoneClusterSetEnrollmentMethod(uint8_t endpoint, EmberAfIasZoneEnrollmentMode method);
/** @brief Configure the retry parameters of the status queue.
*
@@ -124,7 +124,7 @@
*
* @param retryConfig Status queue retry configuration.
*/
-EmberStatus emberAfIasZoneServerConfigStatusQueueRetryParams(IasZoneStatusQueueRetryConfig *retryConfig);
+EmberStatus emberAfIasZoneServerConfigStatusQueueRetryParams(IasZoneStatusQueueRetryConfig * retryConfig);
/** @brief Set the retry parameters of the status queue to default.
*
diff --git a/src/app/clusters/identify/identify-cli.c b/src/app/clusters/identify/identify-cli.c
index b94711d..d2c7cf6 100644
--- a/src/app/clusters/identify/identify-cli.c
+++ b/src/app/clusters/identify/identify-cli.c
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the Identify plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// *******************************************************************
// * identify-cli.c
@@ -51,8 +51,8 @@
#if !defined(EMBER_AF_GENERATE_CLI)
EmberCommandEntry emberAfPluginIdentifyCommands[] = {
- emberCommandEntryAction("print", emAfPluginIdentifyCliPrint, "", "Print the identify state of each endpoint"),
- emberCommandEntryTerminator(),
+ emberCommandEntryAction("print", emAfPluginIdentifyCliPrint, "", "Print the identify state of each endpoint"),
+ emberCommandEntryTerminator(),
};
#endif // EMBER_AF_GENERATE_CLI
@@ -60,14 +60,12 @@
void emAfPluginIdentifyCliPrint(void)
{
#if defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
- uint8_t i;
- for (i = 0; i < emberAfEndpointCount(); ++i) {
- uint8_t endpoint = emberAfEndpointFromIndex(i);
- emberAfIdentifyClusterPrintln("Endpoint 0x%x is identifying: %p",
- endpoint,
- (emberAfIsDeviceIdentifying(endpoint)
- ? "true"
- : "false"));
- }
-#endif //defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
+ uint8_t i;
+ for (i = 0; i < emberAfEndpointCount(); ++i)
+ {
+ uint8_t endpoint = emberAfEndpointFromIndex(i);
+ emberAfIdentifyClusterPrintln("Endpoint 0x%x is identifying: %p", endpoint,
+ (emberAfIsDeviceIdentifying(endpoint) ? "true" : "false"));
+ }
+#endif // defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
}
diff --git a/src/app/clusters/identify/identify.c b/src/app/clusters/identify/identify.c
index 16812da..b49f199 100644
--- a/src/app/clusters/identify/identify.c
+++ b/src/app/clusters/identify/identify.c
@@ -31,12 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Identify plugin, which implements the Identify
- * cluster.
+ * @brief Routines for the Identify plugin, which
+ *implements the Identify cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// *******************************************************************
// * identify.c
@@ -49,160 +49,155 @@
#include "app/framework/include/af.h"
#include "app/framework/util/common.h"
-typedef struct {
- bool identifying;
- uint16_t identifyTime;
+typedef struct
+{
+ bool identifying;
+ uint16_t identifyTime;
} EmAfIdentifyState;
static EmAfIdentifyState stateTable[EMBER_AF_IDENTIFY_CLUSTER_SERVER_ENDPOINT_COUNT];
-static EmberAfStatus readIdentifyTime(uint8_t endpoint, uint16_t *identifyTime);
+static EmberAfStatus readIdentifyTime(uint8_t endpoint, uint16_t * identifyTime);
static EmberAfStatus writeIdentifyTime(uint8_t endpoint, uint16_t identifyTime);
static EmberStatus scheduleIdentifyTick(uint8_t endpoint);
-static EmAfIdentifyState *getIdentifyState(uint8_t endpoint);
+static EmAfIdentifyState * getIdentifyState(uint8_t endpoint);
-static EmAfIdentifyState *getIdentifyState(uint8_t endpoint)
+static EmAfIdentifyState * getIdentifyState(uint8_t endpoint)
{
- uint8_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ZCL_IDENTIFY_CLUSTER_ID);
- return (ep == 0xFF ? NULL : &stateTable[ep]);
+ uint8_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ZCL_IDENTIFY_CLUSTER_ID);
+ return (ep == 0xFF ? NULL : &stateTable[ep]);
}
void emberAfIdentifyClusterServerInitCallback(uint8_t endpoint)
{
- scheduleIdentifyTick(endpoint);
+ scheduleIdentifyTick(endpoint);
}
void emberAfIdentifyClusterServerTickCallback(uint8_t endpoint)
{
- uint16_t identifyTime;
- if (readIdentifyTime(endpoint, &identifyTime) == EMBER_ZCL_STATUS_SUCCESS) {
- // This tick writes the new attribute, which will trigger the Attribute
- // Changed callback below, which in turn will schedule or cancel the tick.
- // Because of this, the tick does not have to be scheduled here.
- writeIdentifyTime(endpoint, (identifyTime == 0 ? 0 : identifyTime - 1));
- }
+ uint16_t identifyTime;
+ if (readIdentifyTime(endpoint, &identifyTime) == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ // This tick writes the new attribute, which will trigger the Attribute
+ // Changed callback below, which in turn will schedule or cancel the tick.
+ // Because of this, the tick does not have to be scheduled here.
+ writeIdentifyTime(endpoint, (identifyTime == 0 ? 0 : identifyTime - 1));
+ }
}
-void emberAfIdentifyClusterServerAttributeChangedCallback(uint8_t endpoint,
- EmberAfAttributeId attributeId)
+void emberAfIdentifyClusterServerAttributeChangedCallback(uint8_t endpoint, EmberAfAttributeId attributeId)
{
- if (attributeId == ZCL_IDENTIFY_TIME_ATTRIBUTE_ID) {
- scheduleIdentifyTick(endpoint);
- }
+ if (attributeId == ZCL_IDENTIFY_TIME_ATTRIBUTE_ID)
+ {
+ scheduleIdentifyTick(endpoint);
+ }
}
bool emberAfIdentifyClusterIdentifyCallback(uint16_t time)
{
- EmberStatus sendStatus;
- // This Identify callback writes the new attribute, which will trigger the
- // Attribute Changed callback above, which in turn will schedule or cancel the
- // tick. Because of this, the tick does not have to be scheduled here.
- emberAfIdentifyClusterPrintln("RX identify:IDENTIFY 0x%2x", time);
- sendStatus = emberAfSendImmediateDefaultResponse(
- writeIdentifyTime(emberAfCurrentEndpoint(), time));
- if (EMBER_SUCCESS != sendStatus) {
- emberAfIdentifyClusterPrintln("Identify: failed to send %s response: "
- "0x%x",
- "default",
- sendStatus);
- }
- return true;
+ EmberStatus sendStatus;
+ // This Identify callback writes the new attribute, which will trigger the
+ // Attribute Changed callback above, which in turn will schedule or cancel the
+ // tick. Because of this, the tick does not have to be scheduled here.
+ emberAfIdentifyClusterPrintln("RX identify:IDENTIFY 0x%2x", time);
+ sendStatus = emberAfSendImmediateDefaultResponse(writeIdentifyTime(emberAfCurrentEndpoint(), time));
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfIdentifyClusterPrintln("Identify: failed to send %s response: "
+ "0x%x",
+ "default", sendStatus);
+ }
+ return true;
}
bool emberAfIdentifyClusterIdentifyQueryCallback(void)
{
- EmberAfStatus status;
- EmberStatus sendStatus;
- uint16_t identifyTime;
+ EmberAfStatus status;
+ EmberStatus sendStatus;
+ uint16_t identifyTime;
- emberAfIdentifyClusterPrintln("RX identify:QUERY");
+ emberAfIdentifyClusterPrintln("RX identify:QUERY");
- // According to the 075123r02ZB, a device shall not send an Identify Query
- // Response if it is not currently identifying. Instead, or if reading the
- // Identify Time attribute fails, send a Default Response.
- status = readIdentifyTime(emberAfCurrentEndpoint(), &identifyTime);
- if (status != EMBER_ZCL_STATUS_SUCCESS || identifyTime == 0) {
- sendStatus = emberAfSendImmediateDefaultResponse(status);
- if (EMBER_SUCCESS != sendStatus) {
- emberAfIdentifyClusterPrintln("Identify: failed to send %s response: "
- "0x%x",
- "default",
- sendStatus);
+ // According to the 075123r02ZB, a device shall not send an Identify Query
+ // Response if it is not currently identifying. Instead, or if reading the
+ // Identify Time attribute fails, send a Default Response.
+ status = readIdentifyTime(emberAfCurrentEndpoint(), &identifyTime);
+ if (status != EMBER_ZCL_STATUS_SUCCESS || identifyTime == 0)
+ {
+ sendStatus = emberAfSendImmediateDefaultResponse(status);
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfIdentifyClusterPrintln("Identify: failed to send %s response: "
+ "0x%x",
+ "default", sendStatus);
+ }
+ return true;
+ }
+
+ emberAfFillCommandIdentifyClusterIdentifyQueryResponse(identifyTime);
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfIdentifyClusterPrintln("Identify: failed to send %s response: 0x%x", "query", sendStatus);
}
return true;
- }
-
- emberAfFillCommandIdentifyClusterIdentifyQueryResponse(identifyTime);
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfIdentifyClusterPrintln("Identify: failed to send %s response: 0x%x",
- "query",
- sendStatus);
- }
- return true;
}
-EmberAfStatus readIdentifyTime(uint8_t endpoint,
- uint16_t *identifyTime)
+EmberAfStatus readIdentifyTime(uint8_t endpoint, uint16_t * identifyTime)
{
- EmberAfStatus status = emberAfReadAttribute(endpoint,
- ZCL_IDENTIFY_CLUSTER_ID,
- ZCL_IDENTIFY_TIME_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)identifyTime,
- sizeof(*identifyTime),
- NULL); // data type
+ EmberAfStatus status = emberAfReadAttribute(endpoint, ZCL_IDENTIFY_CLUSTER_ID, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) identifyTime, sizeof(*identifyTime),
+ NULL); // data type
#if defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfIdentifyClusterPrintln("ERR: reading identify time %x", status);
- }
-#endif //defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
- return status;
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfIdentifyClusterPrintln("ERR: reading identify time %x", status);
+ }
+#endif // defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
+ return status;
}
static EmberAfStatus writeIdentifyTime(uint8_t endpoint, uint16_t identifyTime)
{
- EmberAfStatus status = emberAfWriteAttribute(endpoint,
- ZCL_IDENTIFY_CLUSTER_ID,
- ZCL_IDENTIFY_TIME_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&identifyTime,
- ZCL_INT16U_ATTRIBUTE_TYPE);
+ EmberAfStatus status = emberAfWriteAttribute(endpoint, ZCL_IDENTIFY_CLUSTER_ID, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) &identifyTime, ZCL_INT16U_ATTRIBUTE_TYPE);
#if defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfIdentifyClusterPrintln("ERR: writing identify time %x", status);
- }
-#endif //defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
- return status;
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfIdentifyClusterPrintln("ERR: writing identify time %x", status);
+ }
+#endif // defined(EMBER_AF_PRINT_ENABLE) && defined(EMBER_AF_PRINT_IDENTIFY_CLUSTER)
+ return status;
}
static EmberStatus scheduleIdentifyTick(uint8_t endpoint)
{
- EmberAfStatus status;
- EmAfIdentifyState *state = getIdentifyState(endpoint);
- uint16_t identifyTime;
+ EmberAfStatus status;
+ EmAfIdentifyState * state = getIdentifyState(endpoint);
+ uint16_t identifyTime;
- if (state == NULL) {
- return EMBER_BAD_ARGUMENT;
- }
-
- status = readIdentifyTime(endpoint, &identifyTime);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- if (!state->identifying) {
- state->identifying = true;
- state->identifyTime = identifyTime;
- emberAfPluginIdentifyStartFeedbackCallback(endpoint,
- identifyTime);
+ if (state == NULL)
+ {
+ return EMBER_BAD_ARGUMENT;
}
- if (identifyTime > 0) {
- return emberAfScheduleServerTick(endpoint,
- ZCL_IDENTIFY_CLUSTER_ID,
- MILLISECOND_TICKS_PER_SECOND);
- }
- }
- state->identifying = false;
- emberAfPluginIdentifyStopFeedbackCallback(endpoint);
- return emberAfDeactivateServerTick(endpoint, ZCL_IDENTIFY_CLUSTER_ID);
+ status = readIdentifyTime(endpoint, &identifyTime);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ if (!state->identifying)
+ {
+ state->identifying = true;
+ state->identifyTime = identifyTime;
+ emberAfPluginIdentifyStartFeedbackCallback(endpoint, identifyTime);
+ }
+ if (identifyTime > 0)
+ {
+ return emberAfScheduleServerTick(endpoint, ZCL_IDENTIFY_CLUSTER_ID, MILLISECOND_TICKS_PER_SECOND);
+ }
+ }
+
+ state->identifying = false;
+ emberAfPluginIdentifyStopFeedbackCallback(endpoint);
+ return emberAfDeactivateServerTick(endpoint, ZCL_IDENTIFY_CLUSTER_ID);
}
diff --git a/src/app/clusters/level-control/level-control.c b/src/app/clusters/level-control/level-control.c
index 2490bd2..0f365b4 100644
--- a/src/app/clusters/level-control/level-control.c
+++ b/src/app/clusters/level-control/level-control.c
@@ -31,12 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Level Control plugin, which implements the
- * Level Control cluster.
+ * @brief Routines for the Level Control plugin, which
+ *implements the Level Control cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// this file contains all the common includes for clusters in the util
#include "app/framework/include/af.h"
@@ -45,29 +45,29 @@
#include "level-control.h"
#ifdef EMBER_AF_PLUGIN_REPORTING
- #include "app/framework/plugin/reporting/reporting.h"
+#include "app/framework/plugin/reporting/reporting.h"
#endif
#ifdef EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER
- #include "app/framework/plugin/zll-level-control-server/zll-level-control-server.h"
-#endif //EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER
+#include "app/framework/plugin/zll-level-control-server/zll-level-control-server.h"
+#endif // EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_START_UP_CURRENT_LEVEL_ATTRIBUTE
static bool areStartUpLevelControlServerAttributesTokenized(uint8_t endpoint);
#endif
#if (EMBER_AF_PLUGIN_LEVEL_CONTROL_RATE == 0)
- #define FASTEST_TRANSITION_TIME_MS 0
+#define FASTEST_TRANSITION_TIME_MS 0
#else
- #define FASTEST_TRANSITION_TIME_MS (MILLISECOND_TICKS_PER_SECOND / EMBER_AF_PLUGIN_LEVEL_CONTROL_RATE)
+#define FASTEST_TRANSITION_TIME_MS (MILLISECOND_TICKS_PER_SECOND / EMBER_AF_PLUGIN_LEVEL_CONTROL_RATE)
#endif
#ifdef EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER
- #define MIN_LEVEL EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER_MINIMUM_LEVEL
- #define MAX_LEVEL EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER_MAXIMUM_LEVEL
+#define MIN_LEVEL EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER_MINIMUM_LEVEL
+#define MAX_LEVEL EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER_MAXIMUM_LEVEL
#else
- #define MIN_LEVEL EMBER_AF_PLUGIN_LEVEL_CONTROL_MINIMUM_LEVEL
- #define MAX_LEVEL EMBER_AF_PLUGIN_LEVEL_CONTROL_MAXIMUM_LEVEL
+#define MIN_LEVEL EMBER_AF_PLUGIN_LEVEL_CONTROL_MINIMUM_LEVEL
+#define MAX_LEVEL EMBER_AF_PLUGIN_LEVEL_CONTROL_MAXIMUM_LEVEL
#endif
#define INVALID_STORED_LEVEL 0xFFFF
@@ -75,52 +75,35 @@
#define STARTUP_CURRENT_LEVEL_USE_DEVICE_MINIMUM 0x00
#define STARTUP_CURRENT_LEVEL_USE_PREVIOUS_LEVEL 0xFF
-typedef struct {
- uint8_t commandId;
- uint8_t moveToLevel;
- bool increasing;
- bool useOnLevel;
- uint8_t onLevel;
- uint16_t storedLevel;
- uint32_t eventDurationMs;
- uint32_t transitionTimeMs;
- uint32_t elapsedTimeMs;
+typedef struct
+{
+ uint8_t commandId;
+ uint8_t moveToLevel;
+ bool increasing;
+ bool useOnLevel;
+ uint8_t onLevel;
+ uint16_t storedLevel;
+ uint32_t eventDurationMs;
+ uint32_t transitionTimeMs;
+ uint32_t elapsedTimeMs;
} EmberAfLevelControlState;
static EmberAfLevelControlState stateTable[EMBER_AF_LEVEL_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT];
-static EmberAfLevelControlState *getState(uint8_t endpoint);
+static EmberAfLevelControlState * getState(uint8_t endpoint);
-static void moveToLevelHandler(uint8_t commandId,
- uint8_t level,
- uint16_t transitionTimeDs,
- uint8_t optionMask,
- uint8_t optionOverride,
- uint16_t storedLevel);
-static void moveHandler(uint8_t commandId,
- uint8_t moveMode,
- uint8_t rate,
- uint8_t optionMask,
+static void moveToLevelHandler(uint8_t commandId, uint8_t level, uint16_t transitionTimeDs, uint8_t optionMask,
+ uint8_t optionOverride, uint16_t storedLevel);
+static void moveHandler(uint8_t commandId, uint8_t moveMode, uint8_t rate, uint8_t optionMask, uint8_t optionOverride);
+static void stepHandler(uint8_t commandId, uint8_t stepMode, uint8_t stepSize, uint16_t transitionTimeDs, uint8_t optionMask,
uint8_t optionOverride);
-static void stepHandler(uint8_t commandId,
- uint8_t stepMode,
- uint8_t stepSize,
- uint16_t transitionTimeDs,
- uint8_t optionMask,
- uint8_t optionOverride);
-static void stopHandler(uint8_t commandId,
- uint8_t optionMask,
- uint8_t optionOverride);
+static void stopHandler(uint8_t commandId, uint8_t optionMask, uint8_t optionOverride);
static void setOnOffValue(uint8_t endpoint, bool onOff);
static void writeRemainingTime(uint8_t endpoint, uint16_t remainingTimeMs);
-static bool shouldExecuteIfOff(uint8_t endpoint,
- uint8_t commandId,
- uint8_t optionMask,
- uint8_t optionOverride);
+static bool shouldExecuteIfOff(uint8_t endpoint, uint8_t commandId, uint8_t optionMask, uint8_t optionOverride);
-#if defined(ZCL_USING_LEVEL_CONTROL_CLUSTER_OPTIONS_ATTRIBUTE) \
- && defined(EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_TEMP)
+#if defined(ZCL_USING_LEVEL_CONTROL_CLUSTER_OPTIONS_ATTRIBUTE) && defined(EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_TEMP)
static void reallyUpdateCoupledColorTemp(uint8_t endpoint);
#define updateCoupledColorTemp(endpoint) reallyUpdateCoupledColorTemp(endpoint)
#else
@@ -129,944 +112,883 @@
static void schedule(uint8_t endpoint, uint32_t delayMs)
{
- emberAfScheduleServerTickExtended(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- delayMs,
- EMBER_AF_LONG_POLL,
- EMBER_AF_OK_TO_SLEEP);
+ emberAfScheduleServerTickExtended(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, delayMs, EMBER_AF_LONG_POLL, EMBER_AF_OK_TO_SLEEP);
}
static void deactivate(uint8_t endpoint)
{
- emberAfDeactivateServerTick(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID);
+ emberAfDeactivateServerTick(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID);
}
-static EmberAfLevelControlState *getState(uint8_t endpoint)
+static EmberAfLevelControlState * getState(uint8_t endpoint)
{
- uint8_t ep = emberAfFindClusterServerEndpointIndex(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID);
- return (ep == 0xFF ? NULL : &stateTable[ep]);
+ uint8_t ep = emberAfFindClusterServerEndpointIndex(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID);
+ return (ep == 0xFF ? NULL : &stateTable[ep]);
}
-#if defined(ZCL_USING_LEVEL_CONTROL_CLUSTER_OPTIONS_ATTRIBUTE) \
- && defined(EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_TEMP)
+#if defined(ZCL_USING_LEVEL_CONTROL_CLUSTER_OPTIONS_ATTRIBUTE) && defined(EMBER_AF_PLUGIN_COLOR_CONTROL_SERVER_TEMP)
static void reallyUpdateCoupledColorTemp(uint8_t endpoint)
{
- uint8_t options;
- EmberAfStatus status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_OPTIONS_ATTRIBUTE_ID,
- &options,
- sizeof(options));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("Unable to read Options attribute: 0x%X",
- status);
- return;
- }
+ uint8_t options;
+ EmberAfStatus status =
+ emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_OPTIONS_ATTRIBUTE_ID, &options, sizeof(options));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("Unable to read Options attribute: 0x%X", status);
+ return;
+ }
- if (READBITS(options, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_COUPLE_COLOR_TEMP_TO_LEVEL)) {
- emberAfPluginLevelControlCoupledColorTempChangeCallback(endpoint);
- }
+ if (READBITS(options, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_COUPLE_COLOR_TEMP_TO_LEVEL))
+ {
+ emberAfPluginLevelControlCoupledColorTempChangeCallback(endpoint);
+ }
}
#endif // LEVEL...OPTIONS_ATTRIBUTE && COLOR...SERVER_TEMP
void emberAfLevelControlClusterServerTickCallback(uint8_t endpoint)
{
- EmberAfLevelControlState *state = getState(endpoint);
- EmberAfStatus status;
- uint8_t currentLevel;
+ EmberAfLevelControlState * state = getState(endpoint);
+ EmberAfStatus status;
+ uint8_t currentLevel;
- if (state == NULL) {
- return;
- }
+ if (state == NULL)
+ {
+ return;
+ }
- state->elapsedTimeMs += state->eventDurationMs;
+ state->elapsedTimeMs += state->eventDurationMs;
-#if !defined(ZCL_USING_LEVEL_CONTROL_CLUSTER_OPTIONS_ATTRIBUTE) \
- && defined(EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER)
- if (emberAfPluginZllLevelControlServerIgnoreMoveToLevelMoveStepStop(endpoint,
- state->commandId)) {
- return;
- }
+#if !defined(ZCL_USING_LEVEL_CONTROL_CLUSTER_OPTIONS_ATTRIBUTE) && defined(EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER)
+ if (emberAfPluginZllLevelControlServerIgnoreMoveToLevelMoveStepStop(endpoint, state->commandId))
+ {
+ return;
+ }
#endif
- // Read the attribute; print error message and return if it can't be read
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)¤tLevel,
- sizeof(currentLevel));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- writeRemainingTime(endpoint, 0);
- return;
- }
-
- emberAfLevelControlClusterPrint("Event: move from %d", currentLevel);
-
- // adjust by the proper amount, either up or down
- if (state->transitionTimeMs == 0) {
- // Immediate, not over a time interval.
- currentLevel = state->moveToLevel;
- } else if (state->increasing) {
- assert(currentLevel < MAX_LEVEL);
- assert(currentLevel < state->moveToLevel);
- currentLevel++;
- } else {
- assert(MIN_LEVEL < currentLevel);
- assert(state->moveToLevel < currentLevel);
- currentLevel--;
- }
-
- emberAfLevelControlClusterPrint(" to %d ", currentLevel);
- emberAfLevelControlClusterPrintln("(diff %c1)",
- state->increasing ? '+' : '-');
-
- status = emberAfWriteServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)¤tLevel,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: writing current level %x", status);
- writeRemainingTime(endpoint, 0);
- return;
- }
-
- updateCoupledColorTemp(endpoint);
-
- // The level has changed, so the scene is no longer valid.
- if (emberAfContainsServer(endpoint, ZCL_SCENES_CLUSTER_ID)) {
- emberAfScenesClusterMakeInvalidCallback(endpoint);
- }
-
- // Are we at the requested level?
- if (currentLevel == state->moveToLevel) {
- if (state->commandId == ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID
- || state->commandId == ZCL_MOVE_WITH_ON_OFF_COMMAND_ID
- || state->commandId == ZCL_STEP_WITH_ON_OFF_COMMAND_ID) {
- setOnOffValue(endpoint, (currentLevel != MIN_LEVEL));
- if (currentLevel == MIN_LEVEL && state->useOnLevel) {
- status = emberAfWriteServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)&state->onLevel,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: writing current level %x",
- status);
- } else {
- updateCoupledColorTemp(endpoint);
- }
- }
- } else {
- if (state->storedLevel != INVALID_STORED_LEVEL) {
- uint8_t storedLevel8u = (uint8_t) state->storedLevel;
- status = emberAfWriteServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)&storedLevel8u,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: writing current level %x",
- status);
- } else {
- updateCoupledColorTemp(endpoint);
- }
- }
+ // Read the attribute; print error message and return if it can't be read
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) ¤tLevel, sizeof(currentLevel));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ writeRemainingTime(endpoint, 0);
+ return;
}
- writeRemainingTime(endpoint, 0);
- } else {
- writeRemainingTime(endpoint,
- state->transitionTimeMs - state->elapsedTimeMs);
- schedule(endpoint, state->eventDurationMs);
- }
+
+ emberAfLevelControlClusterPrint("Event: move from %d", currentLevel);
+
+ // adjust by the proper amount, either up or down
+ if (state->transitionTimeMs == 0)
+ {
+ // Immediate, not over a time interval.
+ currentLevel = state->moveToLevel;
+ }
+ else if (state->increasing)
+ {
+ assert(currentLevel < MAX_LEVEL);
+ assert(currentLevel < state->moveToLevel);
+ currentLevel++;
+ }
+ else
+ {
+ assert(MIN_LEVEL < currentLevel);
+ assert(state->moveToLevel < currentLevel);
+ currentLevel--;
+ }
+
+ emberAfLevelControlClusterPrint(" to %d ", currentLevel);
+ emberAfLevelControlClusterPrintln("(diff %c1)", state->increasing ? '+' : '-');
+
+ status = emberAfWriteServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) ¤tLevel, ZCL_INT8U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: writing current level %x", status);
+ writeRemainingTime(endpoint, 0);
+ return;
+ }
+
+ updateCoupledColorTemp(endpoint);
+
+ // The level has changed, so the scene is no longer valid.
+ if (emberAfContainsServer(endpoint, ZCL_SCENES_CLUSTER_ID))
+ {
+ emberAfScenesClusterMakeInvalidCallback(endpoint);
+ }
+
+ // Are we at the requested level?
+ if (currentLevel == state->moveToLevel)
+ {
+ if (state->commandId == ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID || state->commandId == ZCL_MOVE_WITH_ON_OFF_COMMAND_ID ||
+ state->commandId == ZCL_STEP_WITH_ON_OFF_COMMAND_ID)
+ {
+ setOnOffValue(endpoint, (currentLevel != MIN_LEVEL));
+ if (currentLevel == MIN_LEVEL && state->useOnLevel)
+ {
+ status = emberAfWriteServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) &state->onLevel, ZCL_INT8U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: writing current level %x", status);
+ }
+ else
+ {
+ updateCoupledColorTemp(endpoint);
+ }
+ }
+ }
+ else
+ {
+ if (state->storedLevel != INVALID_STORED_LEVEL)
+ {
+ uint8_t storedLevel8u = (uint8_t) state->storedLevel;
+ status = emberAfWriteServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) &storedLevel8u, ZCL_INT8U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: writing current level %x", status);
+ }
+ else
+ {
+ updateCoupledColorTemp(endpoint);
+ }
+ }
+ }
+ writeRemainingTime(endpoint, 0);
+ }
+ else
+ {
+ writeRemainingTime(endpoint, state->transitionTimeMs - state->elapsedTimeMs);
+ schedule(endpoint, state->eventDurationMs);
+ }
}
static void writeRemainingTime(uint8_t endpoint, uint16_t remainingTimeMs)
{
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_LEVEL_CONTROL_REMAINING_TIME_ATTRIBUTE
- // Convert milliseconds to tenths of a second, rounding any fractional value
- // up to the nearest whole value. This means:
- //
- // 0 ms = 0.00 ds = 0 ds
- // 1 ms = 0.01 ds = 1 ds
- // ...
- // 100 ms = 1.00 ds = 1 ds
- // 101 ms = 1.01 ds = 2 ds
- // ...
- // 200 ms = 2.00 ds = 2 ds
- // 201 ms = 2.01 ds = 3 ds
- // ...
- //
- // This is done to ensure that the attribute, in tenths of a second, only
- // goes to zero when the remaining time in milliseconds is actually zero.
- uint16_t remainingTimeDs = (remainingTimeMs + 99) / 100;
- EmberStatus status = emberAfWriteServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_LEVEL_CONTROL_REMAINING_TIME_ATTRIBUTE_ID,
- (uint8_t *)&remainingTimeDs,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: writing remaining time %x", status);
- }
+ // Convert milliseconds to tenths of a second, rounding any fractional value
+ // up to the nearest whole value. This means:
+ //
+ // 0 ms = 0.00 ds = 0 ds
+ // 1 ms = 0.01 ds = 1 ds
+ // ...
+ // 100 ms = 1.00 ds = 1 ds
+ // 101 ms = 1.01 ds = 2 ds
+ // ...
+ // 200 ms = 2.00 ds = 2 ds
+ // 201 ms = 2.01 ds = 3 ds
+ // ...
+ //
+ // This is done to ensure that the attribute, in tenths of a second, only
+ // goes to zero when the remaining time in milliseconds is actually zero.
+ uint16_t remainingTimeDs = (remainingTimeMs + 99) / 100;
+ EmberStatus status =
+ emberAfWriteServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_LEVEL_CONTROL_REMAINING_TIME_ATTRIBUTE_ID,
+ (uint8_t *) &remainingTimeDs, ZCL_INT16U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: writing remaining time %x", status);
+ }
#endif
}
static void setOnOffValue(uint8_t endpoint, bool onOff)
{
- if (emberAfContainsServer(endpoint, ZCL_ON_OFF_CLUSTER_ID)) {
- emberAfLevelControlClusterPrintln("Setting on/off to %p due to level change",
- onOff ? "ON" : "OFF");
- emberAfOnOffClusterSetValueCallback(endpoint,
- (onOff ? ZCL_ON_COMMAND_ID : ZCL_OFF_COMMAND_ID),
- true);
- }
+ if (emberAfContainsServer(endpoint, ZCL_ON_OFF_CLUSTER_ID))
+ {
+ emberAfLevelControlClusterPrintln("Setting on/off to %p due to level change", onOff ? "ON" : "OFF");
+ emberAfOnOffClusterSetValueCallback(endpoint, (onOff ? ZCL_ON_COMMAND_ID : ZCL_OFF_COMMAND_ID), true);
+ }
}
-static bool shouldExecuteIfOff(uint8_t endpoint,
- uint8_t commandId,
- uint8_t optionMask,
- uint8_t optionOverride)
+static bool shouldExecuteIfOff(uint8_t endpoint, uint8_t commandId, uint8_t optionMask, uint8_t optionOverride)
{
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_OPTIONS_ATTRIBUTE
- // From 3.10.2.2.8.1 of ZCL7 document 14-0127-20j-zcl-ch-3-general.docx:
- // "Command execution SHALL NOT continue beyond the Options processing if
- // all of these criteria are true:
- // - The command is one of the ‘without On/Off’ commands: Move, Move to
- // Level, Stop, or Step.
- // - The On/Off cluster exists on the same endpoint as this cluster.
- // - The OnOff attribute of the On/Off cluster, on this endpoint, is 0x00
- // (FALSE).
- // - The value of the ExecuteIfOff bit is 0."
- if (commandId > ZCL_STOP_COMMAND_ID) {
- return true;
- }
+ // From 3.10.2.2.8.1 of ZCL7 document 14-0127-20j-zcl-ch-3-general.docx:
+ // "Command execution SHALL NOT continue beyond the Options processing if
+ // all of these criteria are true:
+ // - The command is one of the ‘without On/Off’ commands: Move, Move to
+ // Level, Stop, or Step.
+ // - The On/Off cluster exists on the same endpoint as this cluster.
+ // - The OnOff attribute of the On/Off cluster, on this endpoint, is 0x00
+ // (FALSE).
+ // - The value of the ExecuteIfOff bit is 0."
+ if (commandId > ZCL_STOP_COMMAND_ID)
+ {
+ return true;
+ }
- if (!emberAfContainsServer(endpoint, ZCL_ON_OFF_CLUSTER_ID)) {
- return true;
- }
+ if (!emberAfContainsServer(endpoint, ZCL_ON_OFF_CLUSTER_ID))
+ {
+ return true;
+ }
- uint8_t options;
- EmberAfStatus status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_OPTIONS_ATTRIBUTE_ID,
- &options,
- sizeof(options));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("Unable to read Options attribute: 0x%X",
- status);
- // If we can't read the attribute, then we should just assume that it has its
- // default value.
- options = 0x00;
- }
+ uint8_t options;
+ EmberAfStatus status =
+ emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_OPTIONS_ATTRIBUTE_ID, &options, sizeof(options));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("Unable to read Options attribute: 0x%X", status);
+ // If we can't read the attribute, then we should just assume that it has its
+ // default value.
+ options = 0x00;
+ }
- bool on;
- status = emberAfReadServerAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- (uint8_t *)&on,
- sizeof(on));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("Unable to read OnOff attribute: 0x%X",
- status);
- return true;
- }
- // The device is on - hence ExecuteIfOff does not matter
- if (on) {
- return true;
- }
- // The OptionsMask & OptionsOverride fields SHALL both be present or both
- // omitted in the command. A temporary Options bitmap SHALL be created from
- // the Options attribute, using the OptionsMask & OptionsOverride fields, if
- // present. Each bit of the temporary Options bitmap SHALL be determined as
- // follows:
- // Each bit in the Options attribute SHALL determine the corresponding bit in
- // the temporary Options bitmap, unless the OptionsMask field is present and
- // has the corresponding bit set to 1, in which case the corresponding bit in
- // the OptionsOverride field SHALL determine the corresponding bit in the
- // temporary Options bitmap.
- //The resulting temporary Options bitmap SHALL then be processed as defined
- // in section 3.10.2.2.3.
+ bool on;
+ status = emberAfReadServerAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, (uint8_t *) &on, sizeof(on));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("Unable to read OnOff attribute: 0x%X", status);
+ return true;
+ }
+ // The device is on - hence ExecuteIfOff does not matter
+ if (on)
+ {
+ return true;
+ }
+ // The OptionsMask & OptionsOverride fields SHALL both be present or both
+ // omitted in the command. A temporary Options bitmap SHALL be created from
+ // the Options attribute, using the OptionsMask & OptionsOverride fields, if
+ // present. Each bit of the temporary Options bitmap SHALL be determined as
+ // follows:
+ // Each bit in the Options attribute SHALL determine the corresponding bit in
+ // the temporary Options bitmap, unless the OptionsMask field is present and
+ // has the corresponding bit set to 1, in which case the corresponding bit in
+ // the OptionsOverride field SHALL determine the corresponding bit in the
+ // temporary Options bitmap.
+ // The resulting temporary Options bitmap SHALL then be processed as defined
+ // in section 3.10.2.2.3.
- // ---------- The following order is important in decission making -------
- // -----------more readable ----------
- //
- if (optionMask == 0xFF && optionOverride == 0xFF) {
- // 0xFF are the default values passed to the command handler when
- // the payload is not present - in that case there is use of option
- // attribute to decide execution of the command
- return READBITS(options, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF);
- }
- // ---------- The above is to distinguish if the payload is present or not
+ // ---------- The following order is important in decission making -------
+ // -----------more readable ----------
+ //
+ if (optionMask == 0xFF && optionOverride == 0xFF)
+ {
+ // 0xFF are the default values passed to the command handler when
+ // the payload is not present - in that case there is use of option
+ // attribute to decide execution of the command
+ return READBITS(options, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF);
+ }
+ // ---------- The above is to distinguish if the payload is present or not
- if (READBITS(optionMask, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF)) {
- // Mask is present and set in the command payload, this indicates
- // use the over ride as temporary option
- return READBITS(optionOverride, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF);
- }
- // if we are here - use the option bits
- return (READBITS(options, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF));
+ if (READBITS(optionMask, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF))
+ {
+ // Mask is present and set in the command payload, this indicates
+ // use the over ride as temporary option
+ return READBITS(optionOverride, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF);
+ }
+ // if we are here - use the option bits
+ return (READBITS(options, EMBER_ZCL_LEVEL_CONTROL_OPTIONS_EXECUTE_IF_OFF));
#else
- // By default, we return true to continue supporting backwards compatibility.
- return true;
+ // By default, we return true to continue supporting backwards compatibility.
+ return true;
#endif
}
-bool emberAfLevelControlClusterMoveToLevelCallback(uint8_t level,
- uint16_t transitionTime,
- uint8_t optionMask,
+bool emberAfLevelControlClusterMoveToLevelCallback(uint8_t level, uint16_t transitionTime, uint8_t optionMask,
uint8_t optionOverride)
{
- emberAfLevelControlClusterPrintln("%pMOVE_TO_LEVEL %x %2x %x %x",
- "RX level-control:",
- level,
- transitionTime,
- optionMask,
- optionOverride);
- moveToLevelHandler(ZCL_MOVE_TO_LEVEL_COMMAND_ID,
- level,
- transitionTime,
- optionMask,
- optionOverride,
- INVALID_STORED_LEVEL); // Don't revert to the stored level
- return true;
+ emberAfLevelControlClusterPrintln("%pMOVE_TO_LEVEL %x %2x %x %x", "RX level-control:", level, transitionTime, optionMask,
+ optionOverride);
+ moveToLevelHandler(ZCL_MOVE_TO_LEVEL_COMMAND_ID, level, transitionTime, optionMask, optionOverride,
+ INVALID_STORED_LEVEL); // Don't revert to the stored level
+ return true;
}
-bool emberAfLevelControlClusterMoveToLevelWithOnOffCallback(uint8_t level,
- uint16_t transitionTime)
+bool emberAfLevelControlClusterMoveToLevelWithOnOffCallback(uint8_t level, uint16_t transitionTime)
{
- emberAfLevelControlClusterPrintln("%pMOVE_TO_LEVEL_WITH_ON_OFF %x %2x",
- "RX level-control:",
- level,
- transitionTime);
- moveToLevelHandler(ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID,
- level,
- transitionTime,
- 0xFF,
- 0xFF,
- INVALID_STORED_LEVEL); // Don't revert to the stored level
- return true;
+ emberAfLevelControlClusterPrintln("%pMOVE_TO_LEVEL_WITH_ON_OFF %x %2x", "RX level-control:", level, transitionTime);
+ moveToLevelHandler(ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID, level, transitionTime, 0xFF, 0xFF,
+ INVALID_STORED_LEVEL); // Don't revert to the stored level
+ return true;
}
-bool emberAfLevelControlClusterMoveCallback(uint8_t moveMode,
- uint8_t rate,
- uint8_t optionMask,
- uint8_t optionOverride)
+bool emberAfLevelControlClusterMoveCallback(uint8_t moveMode, uint8_t rate, uint8_t optionMask, uint8_t optionOverride)
{
- emberAfLevelControlClusterPrintln("%pMOVE %x %x",
- "RX level-control:",
- moveMode,
- rate);
- moveHandler(ZCL_MOVE_COMMAND_ID, moveMode, rate, optionMask, optionOverride);
- return true;
+ emberAfLevelControlClusterPrintln("%pMOVE %x %x", "RX level-control:", moveMode, rate);
+ moveHandler(ZCL_MOVE_COMMAND_ID, moveMode, rate, optionMask, optionOverride);
+ return true;
}
bool emberAfLevelControlClusterMoveWithOnOffCallback(uint8_t moveMode, uint8_t rate)
{
- emberAfLevelControlClusterPrintln("%pMOVE_WITH_ON_OFF %x %x",
- "RX level-control:",
- moveMode,
- rate);
- moveHandler(ZCL_MOVE_WITH_ON_OFF_COMMAND_ID, moveMode, rate, 0xFF, 0xFF);
- return true;
+ emberAfLevelControlClusterPrintln("%pMOVE_WITH_ON_OFF %x %x", "RX level-control:", moveMode, rate);
+ moveHandler(ZCL_MOVE_WITH_ON_OFF_COMMAND_ID, moveMode, rate, 0xFF, 0xFF);
+ return true;
}
-bool emberAfLevelControlClusterStepCallback(uint8_t stepMode,
- uint8_t stepSize,
- uint16_t transitionTime,
- uint8_t optionMask,
+bool emberAfLevelControlClusterStepCallback(uint8_t stepMode, uint8_t stepSize, uint16_t transitionTime, uint8_t optionMask,
uint8_t optionOverride)
{
- emberAfLevelControlClusterPrintln("%pSTEP %x %x %2x",
- "RX level-control:",
- stepMode,
- stepSize,
- transitionTime);
- stepHandler(ZCL_STEP_COMMAND_ID, stepMode, stepSize, transitionTime, optionMask, optionOverride);
- return true;
+ emberAfLevelControlClusterPrintln("%pSTEP %x %x %2x", "RX level-control:", stepMode, stepSize, transitionTime);
+ stepHandler(ZCL_STEP_COMMAND_ID, stepMode, stepSize, transitionTime, optionMask, optionOverride);
+ return true;
}
-bool emberAfLevelControlClusterStepWithOnOffCallback(uint8_t stepMode,
- uint8_t stepSize,
- uint16_t transitionTime)
+bool emberAfLevelControlClusterStepWithOnOffCallback(uint8_t stepMode, uint8_t stepSize, uint16_t transitionTime)
{
- emberAfLevelControlClusterPrintln("%pSTEP_WITH_ON_OFF %x %x %2x",
- "RX level-control:",
- stepMode,
- stepSize,
- transitionTime);
- stepHandler(ZCL_STEP_WITH_ON_OFF_COMMAND_ID,
- stepMode,
- stepSize,
- transitionTime,
- 0xFF,
- 0xFF);
- return true;
+ emberAfLevelControlClusterPrintln("%pSTEP_WITH_ON_OFF %x %x %2x", "RX level-control:", stepMode, stepSize, transitionTime);
+ stepHandler(ZCL_STEP_WITH_ON_OFF_COMMAND_ID, stepMode, stepSize, transitionTime, 0xFF, 0xFF);
+ return true;
}
-bool emberAfLevelControlClusterStopCallback(uint8_t optionMask,
- uint8_t optionOverride)
+bool emberAfLevelControlClusterStopCallback(uint8_t optionMask, uint8_t optionOverride)
{
- emberAfLevelControlClusterPrintln("%pSTOP", "RX level-control:");
- stopHandler(ZCL_STOP_COMMAND_ID, optionMask, optionOverride);
- return true;
+ emberAfLevelControlClusterPrintln("%pSTOP", "RX level-control:");
+ stopHandler(ZCL_STOP_COMMAND_ID, optionMask, optionOverride);
+ return true;
}
bool emberAfLevelControlClusterStopWithOnOffCallback(void)
{
- emberAfLevelControlClusterPrintln("%pSTOP_WITH_ON_OFF", "RX level-control:");
- stopHandler(ZCL_STOP_WITH_ON_OFF_COMMAND_ID, 0xFF, 0xFF);
- return true;
+ emberAfLevelControlClusterPrintln("%pSTOP_WITH_ON_OFF", "RX level-control:");
+ stopHandler(ZCL_STOP_WITH_ON_OFF_COMMAND_ID, 0xFF, 0xFF);
+ return true;
}
-static void moveToLevelHandler(uint8_t commandId,
- uint8_t level,
- uint16_t transitionTimeDs,
- uint8_t optionMask,
- uint8_t optionOverride,
- uint16_t storedLevel)
+static void moveToLevelHandler(uint8_t commandId, uint8_t level, uint16_t transitionTimeDs, uint8_t optionMask,
+ uint8_t optionOverride, uint16_t storedLevel)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
- EmberAfLevelControlState *state = getState(endpoint);
- EmberAfStatus status;
- uint8_t currentLevel;
- uint8_t actualStepSize;
+ uint8_t endpoint = emberAfCurrentEndpoint();
+ EmberAfLevelControlState * state = getState(endpoint);
+ EmberAfStatus status;
+ uint8_t currentLevel;
+ uint8_t actualStepSize;
- if (state == NULL) {
- status = EMBER_ZCL_STATUS_FAILURE;
- goto send_default_response;
- }
-
- if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride)) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- goto send_default_response;
- }
-
- // Cancel any currently active command before fiddling with the state.
- deactivate(endpoint);
-
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)¤tLevel,
- sizeof(currentLevel));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- goto send_default_response;
- }
-
- state->commandId = commandId;
-
- // Move To Level commands cause the device to move from its current level to
- // the specified level at the specified rate.
- if (MAX_LEVEL < level) {
- state->moveToLevel = MAX_LEVEL;
- } else if (level < MIN_LEVEL) {
- state->moveToLevel = MIN_LEVEL;
- } else {
- state->moveToLevel = level;
- }
-
- // If the level is decreasing, the On/Off attribute is left unchanged. This
- // logic is to prevent a light from transitioning from off to bright to dim.
- // Instead, a light that is off will stay off until the target level is
- // reached.
- if (currentLevel <= state->moveToLevel) {
- if (commandId == ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID) {
- setOnOffValue(endpoint, (state->moveToLevel != MIN_LEVEL));
+ if (state == NULL)
+ {
+ status = EMBER_ZCL_STATUS_FAILURE;
+ goto send_default_response;
}
- if (currentLevel == state->moveToLevel) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- goto send_default_response;
- }
- state->increasing = true;
- actualStepSize = state->moveToLevel - currentLevel;
- } else {
- state->increasing = false;
- actualStepSize = currentLevel - state->moveToLevel;
- }
- // If the Transition time field takes the value 0xFFFF, then the time taken
- // to move to the new level shall instead be determined by the On/Off
- // Transition Time attribute. If On/Off Transition Time, which is an
- // optional attribute, is not present, the device shall move to its new level
- // as fast as it is able.
- if (transitionTimeDs == 0xFFFF) {
+ if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride))
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ goto send_default_response;
+ }
+
+ // Cancel any currently active command before fiddling with the state.
+ deactivate(endpoint);
+
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) ¤tLevel, sizeof(currentLevel));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ goto send_default_response;
+ }
+
+ state->commandId = commandId;
+
+ // Move To Level commands cause the device to move from its current level to
+ // the specified level at the specified rate.
+ if (MAX_LEVEL < level)
+ {
+ state->moveToLevel = MAX_LEVEL;
+ }
+ else if (level < MIN_LEVEL)
+ {
+ state->moveToLevel = MIN_LEVEL;
+ }
+ else
+ {
+ state->moveToLevel = level;
+ }
+
+ // If the level is decreasing, the On/Off attribute is left unchanged. This
+ // logic is to prevent a light from transitioning from off to bright to dim.
+ // Instead, a light that is off will stay off until the target level is
+ // reached.
+ if (currentLevel <= state->moveToLevel)
+ {
+ if (commandId == ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID)
+ {
+ setOnOffValue(endpoint, (state->moveToLevel != MIN_LEVEL));
+ }
+ if (currentLevel == state->moveToLevel)
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ goto send_default_response;
+ }
+ state->increasing = true;
+ actualStepSize = state->moveToLevel - currentLevel;
+ }
+ else
+ {
+ state->increasing = false;
+ actualStepSize = currentLevel - state->moveToLevel;
+ }
+
+ // If the Transition time field takes the value 0xFFFF, then the time taken
+ // to move to the new level shall instead be determined by the On/Off
+ // Transition Time attribute. If On/Off Transition Time, which is an
+ // optional attribute, is not present, the device shall move to its new level
+ // as fast as it is able.
+ if (transitionTimeDs == 0xFFFF)
+ {
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_OFF_TRANSITION_TIME_ATTRIBUTE
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_ON_OFF_TRANSITION_TIME_ATTRIBUTE_ID,
- (uint8_t *)&transitionTimeDs,
- sizeof(transitionTimeDs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading on/off transition time %x",
- status);
- goto send_default_response;
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_ON_OFF_TRANSITION_TIME_ATTRIBUTE_ID,
+ (uint8_t *) &transitionTimeDs, sizeof(transitionTimeDs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading on/off transition time %x", status);
+ goto send_default_response;
+ }
+
+ // Transition time comes in (or is stored, in the case of On/Off Transition
+ // Time) as tenths of a second, but we work in milliseconds.
+ state->transitionTimeMs = (transitionTimeDs * MILLISECOND_TICKS_PER_SECOND / 10);
+#else // ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_OFF_TRANSITION_TIME_ATTRIBUTE
+ // If the Transition Time field is 0xFFFF and On/Off Transition Time,
+ // which is an optional attribute, is not present, the device shall move to
+ // its new level as fast as it is able.
+ state->transitionTimeMs = FASTEST_TRANSITION_TIME_MS;
+#endif // ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_OFF_TRANSITION_TIME_ATTRIBUTE
+ }
+ else
+ {
+ // Transition time comes in (or is stored, in the case of On/Off Transition
+ // Time) as tenths of a second, but we work in milliseconds.
+ state->transitionTimeMs = (transitionTimeDs * MILLISECOND_TICKS_PER_SECOND / 10);
}
- // Transition time comes in (or is stored, in the case of On/Off Transition
- // Time) as tenths of a second, but we work in milliseconds.
- state->transitionTimeMs = (transitionTimeDs
- * MILLISECOND_TICKS_PER_SECOND
- / 10);
-#else //ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_OFF_TRANSITION_TIME_ATTRIBUTE
- // If the Transition Time field is 0xFFFF and On/Off Transition Time,
- // which is an optional attribute, is not present, the device shall move to
- // its new level as fast as it is able.
- state->transitionTimeMs = FASTEST_TRANSITION_TIME_MS;
-#endif //ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_OFF_TRANSITION_TIME_ATTRIBUTE
- } else {
- // Transition time comes in (or is stored, in the case of On/Off Transition
- // Time) as tenths of a second, but we work in milliseconds.
- state->transitionTimeMs = (transitionTimeDs
- * MILLISECOND_TICKS_PER_SECOND
- / 10);
- }
+ // The duration between events will be the transition time divided by the
+ // distance we must move.
+ state->eventDurationMs = state->transitionTimeMs / actualStepSize;
+ state->elapsedTimeMs = 0;
- // The duration between events will be the transition time divided by the
- // distance we must move.
- state->eventDurationMs = state->transitionTimeMs / actualStepSize;
- state->elapsedTimeMs = 0;
+ // OnLevel is not used for Move commands.
+ state->useOnLevel = false;
- // OnLevel is not used for Move commands.
- state->useOnLevel = false;
+ state->storedLevel = storedLevel;
- state->storedLevel = storedLevel;
-
- // The setup was successful, so mark the new state as active and return.
- schedule(endpoint, state->eventDurationMs);
- status = EMBER_ZCL_STATUS_SUCCESS;
+ // The setup was successful, so mark the new state as active and return.
+ schedule(endpoint, state->eventDurationMs);
+ status = EMBER_ZCL_STATUS_SUCCESS;
#ifdef EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER
- if (commandId == ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID) {
- emberAfPluginZllLevelControlServerMoveToLevelWithOnOffZllExtensions(emberAfCurrentCommand());
- }
+ if (commandId == ZCL_MOVE_TO_LEVEL_WITH_ON_OFF_COMMAND_ID)
+ {
+ emberAfPluginZllLevelControlServerMoveToLevelWithOnOffZllExtensions(emberAfCurrentCommand());
+ }
#endif
- send_default_response:
- if (emberAfCurrentCommand()->apsFrame->clusterId
- == ZCL_LEVEL_CONTROL_CLUSTER_ID) {
- emberAfSendImmediateDefaultResponse(status);
- }
+send_default_response:
+ if (emberAfCurrentCommand()->apsFrame->clusterId == ZCL_LEVEL_CONTROL_CLUSTER_ID)
+ {
+ emberAfSendImmediateDefaultResponse(status);
+ }
}
static void moveHandler(uint8_t commandId, uint8_t moveMode, uint8_t rate, uint8_t optionMask, uint8_t optionOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
- EmberAfLevelControlState *state = getState(endpoint);
- EmberAfStatus status;
- uint8_t currentLevel;
- uint8_t difference;
+ uint8_t endpoint = emberAfCurrentEndpoint();
+ EmberAfLevelControlState * state = getState(endpoint);
+ EmberAfStatus status;
+ uint8_t currentLevel;
+ uint8_t difference;
- if (state == NULL) {
- status = EMBER_ZCL_STATUS_FAILURE;
- goto send_default_response;
- }
+ if (state == NULL)
+ {
+ status = EMBER_ZCL_STATUS_FAILURE;
+ goto send_default_response;
+ }
- if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride)) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- goto send_default_response;
- }
+ if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride))
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ goto send_default_response;
+ }
- // Cancel any currently active command before fiddling with the state.
- deactivate(endpoint);
+ // Cancel any currently active command before fiddling with the state.
+ deactivate(endpoint);
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)¤tLevel,
- sizeof(currentLevel));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- goto send_default_response;
- }
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) ¤tLevel, sizeof(currentLevel));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ goto send_default_response;
+ }
- state->commandId = commandId;
+ state->commandId = commandId;
- // Move commands cause the device to move from its current level to either
- // the maximum or minimum level at the specified rate.
- switch (moveMode) {
+ // Move commands cause the device to move from its current level to either
+ // the maximum or minimum level at the specified rate.
+ switch (moveMode)
+ {
case EMBER_ZCL_MOVE_MODE_UP:
- state->increasing = true;
- state->moveToLevel = MAX_LEVEL;
- difference = MAX_LEVEL - currentLevel;
- break;
- case EMBER_ZCL_MOVE_MODE_DOWN:
- state->increasing = false;
- state->moveToLevel = MIN_LEVEL;
- difference = currentLevel - MIN_LEVEL;
- break;
- default:
- status = EMBER_ZCL_STATUS_INVALID_FIELD;
- goto send_default_response;
- }
-
- // If the level is decreasing, the On/Off attribute is left unchanged. This
- // logic is to prevent a light from transitioning from off to bright to dim.
- // Instead, a light that is off will stay off until the target level is
- // reached.
- if (currentLevel <= state->moveToLevel) {
- if (commandId == ZCL_MOVE_WITH_ON_OFF_COMMAND_ID) {
- setOnOffValue(endpoint, (state->moveToLevel != MIN_LEVEL));
- }
- if (currentLevel == state->moveToLevel) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- goto send_default_response;
- }
- }
-
- // If the Rate field is 0xFF, the device should move as fast as it is able.
- // Otherwise, the rate is in units per second.
- if (rate == 0xFF) {
- state->eventDurationMs = FASTEST_TRANSITION_TIME_MS;
- } else {
- state->eventDurationMs = MILLISECOND_TICKS_PER_SECOND / rate;
- }
- state->transitionTimeMs = difference * state->eventDurationMs;
- state->elapsedTimeMs = 0;
-
- // OnLevel is not used for Move commands.
- state->useOnLevel = false;
-
- // The setup was successful, so mark the new state as active and return.
- schedule(endpoint, state->eventDurationMs);
- status = EMBER_ZCL_STATUS_SUCCESS;
-
- send_default_response:
- emberAfSendImmediateDefaultResponse(status);
-}
-
-static void stepHandler(uint8_t commandId,
- uint8_t stepMode,
- uint8_t stepSize,
- uint16_t transitionTimeDs,
- uint8_t optionMask,
- uint8_t optionOverride)
-{
- uint8_t endpoint = emberAfCurrentEndpoint();
- EmberAfLevelControlState *state = getState(endpoint);
- EmberAfStatus status;
- uint8_t currentLevel;
- uint8_t actualStepSize = stepSize;
-
- if (state == NULL) {
- status = EMBER_ZCL_STATUS_FAILURE;
- goto send_default_response;
- }
-
- if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride)) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- goto send_default_response;
- }
-
- // Cancel any currently active command before fiddling with the state.
- deactivate(endpoint);
-
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)¤tLevel,
- sizeof(currentLevel));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- goto send_default_response;
- }
-
- state->commandId = commandId;
-
- // Step commands cause the device to move from its current level to a new
- // level over the specified transition time.
- switch (stepMode) {
- case EMBER_ZCL_STEP_MODE_UP:
- state->increasing = true;
- if (MAX_LEVEL - currentLevel < stepSize) {
+ state->increasing = true;
state->moveToLevel = MAX_LEVEL;
- actualStepSize = (MAX_LEVEL - currentLevel);
- } else {
- state->moveToLevel = currentLevel + stepSize;
- }
- break;
- case EMBER_ZCL_STEP_MODE_DOWN:
- state->increasing = false;
- if (currentLevel - MIN_LEVEL < stepSize) {
+ difference = MAX_LEVEL - currentLevel;
+ break;
+ case EMBER_ZCL_MOVE_MODE_DOWN:
+ state->increasing = false;
state->moveToLevel = MIN_LEVEL;
- actualStepSize = (currentLevel - MIN_LEVEL);
- } else {
- state->moveToLevel = currentLevel - stepSize;
- }
- break;
+ difference = currentLevel - MIN_LEVEL;
+ break;
default:
- status = EMBER_ZCL_STATUS_INVALID_FIELD;
- goto send_default_response;
- }
-
- // If the level is decreasing, the On/Off attribute is left unchanged. This
- // logic is to prevent a light from transitioning from off to bright to dim.
- // Instead, a light that is off will stay off until the target level is
- // reached.
- if (currentLevel <= state->moveToLevel) {
- if (commandId == ZCL_STEP_WITH_ON_OFF_COMMAND_ID) {
- setOnOffValue(endpoint, (state->moveToLevel != MIN_LEVEL));
+ status = EMBER_ZCL_STATUS_INVALID_FIELD;
+ goto send_default_response;
}
- if (currentLevel == state->moveToLevel) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- goto send_default_response;
+
+ // If the level is decreasing, the On/Off attribute is left unchanged. This
+ // logic is to prevent a light from transitioning from off to bright to dim.
+ // Instead, a light that is off will stay off until the target level is
+ // reached.
+ if (currentLevel <= state->moveToLevel)
+ {
+ if (commandId == ZCL_MOVE_WITH_ON_OFF_COMMAND_ID)
+ {
+ setOnOffValue(endpoint, (state->moveToLevel != MIN_LEVEL));
+ }
+ if (currentLevel == state->moveToLevel)
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ goto send_default_response;
+ }
}
- }
- // If the Transition Time field is 0xFFFF, the device should move as fast as
- // it is able.
- if (transitionTimeDs == 0xFFFF) {
- state->transitionTimeMs = FASTEST_TRANSITION_TIME_MS;
- } else {
- // Transition time comes in as tenths of a second, but we work in
- // milliseconds.
- state->transitionTimeMs = (transitionTimeDs
- * MILLISECOND_TICKS_PER_SECOND
- / 10);
- // If the new level was pegged at the minimum level, the transition time
- // shall be proportionally reduced. This is done after the conversion to
- // milliseconds to reduce rounding errors in integer division.
- if (stepSize != actualStepSize) {
- state->transitionTimeMs = (state->transitionTimeMs
- * actualStepSize
- / stepSize);
+ // If the Rate field is 0xFF, the device should move as fast as it is able.
+ // Otherwise, the rate is in units per second.
+ if (rate == 0xFF)
+ {
+ state->eventDurationMs = FASTEST_TRANSITION_TIME_MS;
}
- }
+ else
+ {
+ state->eventDurationMs = MILLISECOND_TICKS_PER_SECOND / rate;
+ }
+ state->transitionTimeMs = difference * state->eventDurationMs;
+ state->elapsedTimeMs = 0;
- // The duration between events will be the transition time divided by the
- // distance we must move.
- state->eventDurationMs = state->transitionTimeMs / actualStepSize;
- state->elapsedTimeMs = 0;
+ // OnLevel is not used for Move commands.
+ state->useOnLevel = false;
- // OnLevel is not used for Step commands.
- state->useOnLevel = false;
+ // The setup was successful, so mark the new state as active and return.
+ schedule(endpoint, state->eventDurationMs);
+ status = EMBER_ZCL_STATUS_SUCCESS;
- // The setup was successful, so mark the new state as active and return.
- schedule(endpoint, state->eventDurationMs);
- status = EMBER_ZCL_STATUS_SUCCESS;
-
- send_default_response:
- emberAfSendImmediateDefaultResponse(status);
+send_default_response:
+ emberAfSendImmediateDefaultResponse(status);
}
-static void stopHandler(uint8_t commandId,
- uint8_t optionMask,
+static void stepHandler(uint8_t commandId, uint8_t stepMode, uint8_t stepSize, uint16_t transitionTimeDs, uint8_t optionMask,
uint8_t optionOverride)
{
- uint8_t endpoint = emberAfCurrentEndpoint();
- EmberAfLevelControlState *state = getState(endpoint);
- EmberAfStatus status;
+ uint8_t endpoint = emberAfCurrentEndpoint();
+ EmberAfLevelControlState * state = getState(endpoint);
+ EmberAfStatus status;
+ uint8_t currentLevel;
+ uint8_t actualStepSize = stepSize;
- if (state == NULL) {
- status = EMBER_ZCL_STATUS_FAILURE;
- goto send_default_response;
- }
+ if (state == NULL)
+ {
+ status = EMBER_ZCL_STATUS_FAILURE;
+ goto send_default_response;
+ }
- if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride)) {
+ if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride))
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ goto send_default_response;
+ }
+
+ // Cancel any currently active command before fiddling with the state.
+ deactivate(endpoint);
+
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) ¤tLevel, sizeof(currentLevel));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ goto send_default_response;
+ }
+
+ state->commandId = commandId;
+
+ // Step commands cause the device to move from its current level to a new
+ // level over the specified transition time.
+ switch (stepMode)
+ {
+ case EMBER_ZCL_STEP_MODE_UP:
+ state->increasing = true;
+ if (MAX_LEVEL - currentLevel < stepSize)
+ {
+ state->moveToLevel = MAX_LEVEL;
+ actualStepSize = (MAX_LEVEL - currentLevel);
+ }
+ else
+ {
+ state->moveToLevel = currentLevel + stepSize;
+ }
+ break;
+ case EMBER_ZCL_STEP_MODE_DOWN:
+ state->increasing = false;
+ if (currentLevel - MIN_LEVEL < stepSize)
+ {
+ state->moveToLevel = MIN_LEVEL;
+ actualStepSize = (currentLevel - MIN_LEVEL);
+ }
+ else
+ {
+ state->moveToLevel = currentLevel - stepSize;
+ }
+ break;
+ default:
+ status = EMBER_ZCL_STATUS_INVALID_FIELD;
+ goto send_default_response;
+ }
+
+ // If the level is decreasing, the On/Off attribute is left unchanged. This
+ // logic is to prevent a light from transitioning from off to bright to dim.
+ // Instead, a light that is off will stay off until the target level is
+ // reached.
+ if (currentLevel <= state->moveToLevel)
+ {
+ if (commandId == ZCL_STEP_WITH_ON_OFF_COMMAND_ID)
+ {
+ setOnOffValue(endpoint, (state->moveToLevel != MIN_LEVEL));
+ }
+ if (currentLevel == state->moveToLevel)
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ goto send_default_response;
+ }
+ }
+
+ // If the Transition Time field is 0xFFFF, the device should move as fast as
+ // it is able.
+ if (transitionTimeDs == 0xFFFF)
+ {
+ state->transitionTimeMs = FASTEST_TRANSITION_TIME_MS;
+ }
+ else
+ {
+ // Transition time comes in as tenths of a second, but we work in
+ // milliseconds.
+ state->transitionTimeMs = (transitionTimeDs * MILLISECOND_TICKS_PER_SECOND / 10);
+ // If the new level was pegged at the minimum level, the transition time
+ // shall be proportionally reduced. This is done after the conversion to
+ // milliseconds to reduce rounding errors in integer division.
+ if (stepSize != actualStepSize)
+ {
+ state->transitionTimeMs = (state->transitionTimeMs * actualStepSize / stepSize);
+ }
+ }
+
+ // The duration between events will be the transition time divided by the
+ // distance we must move.
+ state->eventDurationMs = state->transitionTimeMs / actualStepSize;
+ state->elapsedTimeMs = 0;
+
+ // OnLevel is not used for Step commands.
+ state->useOnLevel = false;
+
+ // The setup was successful, so mark the new state as active and return.
+ schedule(endpoint, state->eventDurationMs);
status = EMBER_ZCL_STATUS_SUCCESS;
- goto send_default_response;
- }
- // Cancel any currently active command.
- deactivate(endpoint);
- writeRemainingTime(endpoint, 0);
- status = EMBER_ZCL_STATUS_SUCCESS;
+send_default_response:
+ emberAfSendImmediateDefaultResponse(status);
+}
- send_default_response:
- emberAfSendImmediateDefaultResponse(status);
+static void stopHandler(uint8_t commandId, uint8_t optionMask, uint8_t optionOverride)
+{
+ uint8_t endpoint = emberAfCurrentEndpoint();
+ EmberAfLevelControlState * state = getState(endpoint);
+ EmberAfStatus status;
+
+ if (state == NULL)
+ {
+ status = EMBER_ZCL_STATUS_FAILURE;
+ goto send_default_response;
+ }
+
+ if (!shouldExecuteIfOff(endpoint, commandId, optionMask, optionOverride))
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ goto send_default_response;
+ }
+
+ // Cancel any currently active command.
+ deactivate(endpoint);
+ writeRemainingTime(endpoint, 0);
+ status = EMBER_ZCL_STATUS_SUCCESS;
+
+send_default_response:
+ emberAfSendImmediateDefaultResponse(status);
}
// Follows 07-5123-04 (ZigBee Cluster Library doc), section 3.10.2.1.1.
// Quotes are from table 3.46.
-void emberAfOnOffClusterLevelControlEffectCallback(uint8_t endpoint,
- bool newValue)
+void emberAfOnOffClusterLevelControlEffectCallback(uint8_t endpoint, bool newValue)
{
- uint8_t temporaryCurrentLevelCache;
- uint16_t currentOnOffTransitionTime;
- uint8_t resolvedLevel;
- uint8_t minimumLevelAllowedForTheDevice = MIN_LEVEL;
- EmberAfStatus status;
+ uint8_t temporaryCurrentLevelCache;
+ uint16_t currentOnOffTransitionTime;
+ uint8_t resolvedLevel;
+ uint8_t minimumLevelAllowedForTheDevice = MIN_LEVEL;
+ EmberAfStatus status;
- // "Temporarily store CurrentLevel."
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)&temporaryCurrentLevelCache,
- sizeof(temporaryCurrentLevelCache));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- return;
- }
-
- // Read the OnLevel attribute.
-#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_LEVEL_ATTRIBUTE
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_ON_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)&resolvedLevel, // OnLevel value
- sizeof(resolvedLevel));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- return;
- }
-
- if (resolvedLevel == 0xFF) {
- // OnLevel has undefined value; fall back to CurrentLevel.
- resolvedLevel = temporaryCurrentLevelCache;
- }
-#else
- resolvedLevel = temporaryCurrentLevelCache;
-#endif
-
- // Read the OnOffTransitionTime attribute.
-#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_OFF_TRANSITION_TIME_ATTRIBUTE
- status = emberAfReadServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_ON_OFF_TRANSITION_TIME_ATTRIBUTE_ID,
- (uint8_t *)¤tOnOffTransitionTime,
- sizeof(currentOnOffTransitionTime));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- return;
- }
-#else
- currentOnOffTransitionTime = 0xFFFF;
-#endif
-
- if (newValue) {
- // If newValue is ZCL_ON_COMMAND_ID...
- // "Set CurrentLevel to minimum level allowed for the device."
- status = emberAfWriteServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- (uint8_t *)&minimumLevelAllowedForTheDevice,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
- return;
+ // "Temporarily store CurrentLevel."
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) &temporaryCurrentLevelCache, sizeof(temporaryCurrentLevelCache));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ return;
}
- // "Move CurrentLevel to OnLevel, or to the stored level if OnLevel is not
- // defined, over the time period OnOffTransitionTime."
- moveToLevelHandler(ZCL_MOVE_TO_LEVEL_COMMAND_ID,
- resolvedLevel,
- currentOnOffTransitionTime,
- 0xFF,
- 0xFF,
- INVALID_STORED_LEVEL); // Don't revert to stored level
- } else {
- // ...else if newValue is ZCL_OFF_COMMAND_ID...
- // "Move CurrentLevel to the minimum level allowed for the device over the
- // time period OnOffTransitionTime."
- moveToLevelHandler(ZCL_MOVE_TO_LEVEL_COMMAND_ID,
- minimumLevelAllowedForTheDevice,
- currentOnOffTransitionTime,
- 0xFF,
- 0xFF,
- temporaryCurrentLevelCache);
+ // Read the OnLevel attribute.
+#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_LEVEL_ATTRIBUTE
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_ON_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) &resolvedLevel, // OnLevel value
+ sizeof(resolvedLevel));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ return;
+ }
- // "If OnLevel is not defined, set the CurrentLevel to the stored level."
- // The emberAfLevelControlClusterServerTickCallback implementation handles
- // this.
- }
+ if (resolvedLevel == 0xFF)
+ {
+ // OnLevel has undefined value; fall back to CurrentLevel.
+ resolvedLevel = temporaryCurrentLevelCache;
+ }
+#else
+ resolvedLevel = temporaryCurrentLevelCache;
+#endif
+
+ // Read the OnOffTransitionTime attribute.
+#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_ON_OFF_TRANSITION_TIME_ATTRIBUTE
+ status = emberAfReadServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_ON_OFF_TRANSITION_TIME_ATTRIBUTE_ID,
+ (uint8_t *) ¤tOnOffTransitionTime, sizeof(currentOnOffTransitionTime));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ return;
+ }
+#else
+ currentOnOffTransitionTime = 0xFFFF;
+#endif
+
+ if (newValue)
+ {
+ // If newValue is ZCL_ON_COMMAND_ID...
+ // "Set CurrentLevel to minimum level allowed for the device."
+ status = emberAfWriteServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ (uint8_t *) &minimumLevelAllowedForTheDevice, ZCL_INT8U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfLevelControlClusterPrintln("ERR: reading current level %x", status);
+ return;
+ }
+
+ // "Move CurrentLevel to OnLevel, or to the stored level if OnLevel is not
+ // defined, over the time period OnOffTransitionTime."
+ moveToLevelHandler(ZCL_MOVE_TO_LEVEL_COMMAND_ID, resolvedLevel, currentOnOffTransitionTime, 0xFF, 0xFF,
+ INVALID_STORED_LEVEL); // Don't revert to stored level
+ }
+ else
+ {
+ // ...else if newValue is ZCL_OFF_COMMAND_ID...
+ // "Move CurrentLevel to the minimum level allowed for the device over the
+ // time period OnOffTransitionTime."
+ moveToLevelHandler(ZCL_MOVE_TO_LEVEL_COMMAND_ID, minimumLevelAllowedForTheDevice, currentOnOffTransitionTime, 0xFF, 0xFF,
+ temporaryCurrentLevelCache);
+
+ // "If OnLevel is not defined, set the CurrentLevel to the stored level."
+ // The emberAfLevelControlClusterServerTickCallback implementation handles
+ // this.
+ }
}
void emberAfLevelControlClusterServerInitCallback(uint8_t endpoint)
{
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_START_UP_CURRENT_LEVEL_ATTRIBUTE
- // StartUp behavior relies StartUpCurrentLevel attributes being tokenized.
- if (areStartUpLevelControlServerAttributesTokenized(endpoint)) {
- // Read the StartUpOnOff attribute and set the OnOff attribute as per
- // following from zcl 7 14-0127-20i-zcl-ch-3-general.doc.
- // 3.10.2.2.14 StartUpCurrentLevel Attribute
- // The StartUpCurrentLevel attribute SHALL define the desired startup level
- // for a device when it is supplied with power and this level SHALL be
- // reflected in the CurrentLevel attribute. The values of the StartUpCurrentLevel
- // attribute are listed below:
- // Table 3 58. Values of the StartUpCurrentLevel Attribute
- // Value Action on power up
- // 0x00 Set the CurrentLevel attribute to the minimum value permitted on the device.
- // 0x01-0xfe Set the CurrentLevel attribute to this value.
- // 0xff Set the CurrentLevel attribute to its previous value.
+ // StartUp behavior relies StartUpCurrentLevel attributes being tokenized.
+ if (areStartUpLevelControlServerAttributesTokenized(endpoint))
+ {
+ // Read the StartUpOnOff attribute and set the OnOff attribute as per
+ // following from zcl 7 14-0127-20i-zcl-ch-3-general.doc.
+ // 3.10.2.2.14 StartUpCurrentLevel Attribute
+ // The StartUpCurrentLevel attribute SHALL define the desired startup level
+ // for a device when it is supplied with power and this level SHALL be
+ // reflected in the CurrentLevel attribute. The values of the StartUpCurrentLevel
+ // attribute are listed below:
+ // Table 3 58. Values of the StartUpCurrentLevel Attribute
+ // Value Action on power up
+ // 0x00 Set the CurrentLevel attribute to the minimum value permitted on the device.
+ // 0x01-0xfe Set the CurrentLevel attribute to this value.
+ // 0xff Set the CurrentLevel attribute to its previous value.
- // Initialize startUpCurrentLevel to assume previous value for currentLevel.
- uint8_t startUpCurrentLevel = STARTUP_CURRENT_LEVEL_USE_PREVIOUS_LEVEL;
- EmberAfStatus status = emberAfReadAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_START_UP_CURRENT_LEVEL_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&startUpCurrentLevel,
- sizeof(startUpCurrentLevel),
- NULL);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- uint8_t currentLevel = 0;
- status = emberAfReadAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)¤tLevel,
- sizeof(currentLevel),
- NULL);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- switch (startUpCurrentLevel) {
- case STARTUP_CURRENT_LEVEL_USE_DEVICE_MINIMUM:
- currentLevel = MIN_LEVEL;
- break;
- case STARTUP_CURRENT_LEVEL_USE_PREVIOUS_LEVEL:
- // Just fetched it.
- break;
- default:
- // Otherwise set to specified value 0x01-0xFE.
- // But, need to enforce currentLevel's min/max, right?
- // Spec doesn't mention this.
- if (startUpCurrentLevel < MIN_LEVEL) {
- currentLevel = MIN_LEVEL;
- } else if (startUpCurrentLevel > MAX_LEVEL) {
- currentLevel = MAX_LEVEL;
- } else {
- currentLevel = startUpCurrentLevel;
+ // Initialize startUpCurrentLevel to assume previous value for currentLevel.
+ uint8_t startUpCurrentLevel = STARTUP_CURRENT_LEVEL_USE_PREVIOUS_LEVEL;
+ EmberAfStatus status =
+ emberAfReadAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_START_UP_CURRENT_LEVEL_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) &startUpCurrentLevel, sizeof(startUpCurrentLevel), NULL);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ uint8_t currentLevel = 0;
+ status = emberAfReadAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) ¤tLevel, sizeof(currentLevel), NULL);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ switch (startUpCurrentLevel)
+ {
+ case STARTUP_CURRENT_LEVEL_USE_DEVICE_MINIMUM:
+ currentLevel = MIN_LEVEL;
+ break;
+ case STARTUP_CURRENT_LEVEL_USE_PREVIOUS_LEVEL:
+ // Just fetched it.
+ break;
+ default:
+ // Otherwise set to specified value 0x01-0xFE.
+ // But, need to enforce currentLevel's min/max, right?
+ // Spec doesn't mention this.
+ if (startUpCurrentLevel < MIN_LEVEL)
+ {
+ currentLevel = MIN_LEVEL;
+ }
+ else if (startUpCurrentLevel > MAX_LEVEL)
+ {
+ currentLevel = MAX_LEVEL;
+ }
+ else
+ {
+ currentLevel = startUpCurrentLevel;
+ }
+ break;
+ }
+ status = emberAfWriteAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) ¤tLevel, ZCL_INT8U_ATTRIBUTE_TYPE);
}
- break;
}
- status = emberAfWriteAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)¤tLevel,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
}
- }
#endif
- emberAfPluginLevelControlClusterServerPostInitCallback(endpoint);
+ emberAfPluginLevelControlClusterServerPostInitCallback(endpoint);
}
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_START_UP_CURRENT_LEVEL_ATTRIBUTE
static bool areStartUpLevelControlServerAttributesTokenized(uint8_t endpoint)
{
- EmberAfAttributeMetadata *metadata;
+ EmberAfAttributeMetadata * metadata;
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_START_UP_CURRENT_LEVEL_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_START_UP_CURRENT_LEVEL_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- return true;
+ return true;
}
#endif
diff --git a/src/app/clusters/level-control/level-control.h b/src/app/clusters/level-control/level-control.h
index d077b2e..797df28 100644
--- a/src/app/clusters/level-control/level-control.h
+++ b/src/app/clusters/level-control/level-control.h
@@ -31,18 +31,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief APIs and defines for the Level Control plugin, which implements the
- * Level Control cluster.
+ * @brief APIs and defines for the Level Control
+ *plugin, which implements the Level Control cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// Rate of level control tick execution.
// To increase tick frequency (for more granular updates of device state based
// on level), redefine EMBER_AF_PLUGIN_LEVEL_CONTROL_TICKS_PER_SECOND.
#ifndef EMBER_AF_PLUGIN_LEVEL_CONTROL_TICKS_PER_SECOND
- #define EMBER_AF_PLUGIN_LEVEL_CONTROL_TICKS_PER_SECOND 32
+#define EMBER_AF_PLUGIN_LEVEL_CONTROL_TICKS_PER_SECOND 32
#endif
-#define EMBER_AF_PLUGIN_LEVEL_CONTROL_TICK_TIME \
- (MILLISECOND_TICKS_PER_SECOND / EMBER_AF_PLUGIN_LEVEL_CONTROL_TICKS_PER_SECOND)
+#define EMBER_AF_PLUGIN_LEVEL_CONTROL_TICK_TIME (MILLISECOND_TICKS_PER_SECOND / EMBER_AF_PLUGIN_LEVEL_CONTROL_TICKS_PER_SECOND)
diff --git a/src/app/clusters/on-off/on-off.c b/src/app/clusters/on-off/on-off.c
index a21a046..71181d7 100644
--- a/src/app/clusters/on-off/on-off.c
+++ b/src/app/clusters/on-off/on-off.c
@@ -31,271 +31,246 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the On-Off plugin, which implements the On-Off server
- * cluster.
+ * @brief Routines for the On-Off plugin, which
+ *implements the On-Off server cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "af.h"
#ifdef EMBER_AF_PLUGIN_REPORTING
- #include "app/framework/plugin/reporting/reporting.h"
+#include "app/framework/plugin/reporting/reporting.h"
#endif
#ifdef EMBER_AF_PLUGIN_SCENES
- #include "../scenes/scenes.h"
-#endif //EMBER_AF_PLUGIN_SCENES
+#include "../scenes/scenes.h"
+#endif // EMBER_AF_PLUGIN_SCENES
#ifdef EMBER_AF_PLUGIN_ZLL_ON_OFF_SERVER
- #include "../zll-on-off-server/zll-on-off-server.h"
+#include "../zll-on-off-server/zll-on-off-server.h"
#endif
#ifdef EMBER_AF_PLUGIN_ZLL_LEVEL_CONTROL_SERVER
- #include "../zll-level-control-server/zll-level-control-server.h"
+#include "../zll-level-control-server/zll-level-control-server.h"
#endif
#ifdef ZCL_USING_ON_OFF_CLUSTER_START_UP_ON_OFF_ATTRIBUTE
static bool areStartUpOnOffServerAttributesTokenized(uint8_t endpoint);
#endif
-EmberAfStatus emberAfOnOffClusterSetValueCallback(uint8_t endpoint,
- uint8_t command,
- bool initiatedByLevelChange)
+EmberAfStatus emberAfOnOffClusterSetValueCallback(uint8_t endpoint, uint8_t command, bool initiatedByLevelChange)
{
- EmberAfStatus status;
- bool currentValue, newValue;
+ EmberAfStatus status;
+ bool currentValue, newValue;
- emberAfOnOffClusterPrintln("On/Off set value: %x %x", endpoint, command);
+ emberAfOnOffClusterPrintln("On/Off set value: %x %x", endpoint, command);
- // read current on/off value
- status = emberAfReadAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)¤tValue,
- sizeof(currentValue),
- NULL); // data type
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfOnOffClusterPrintln("ERR: reading on/off %x", status);
- return status;
- }
-
- // if the value is already what we want to set it to then do nothing
- if ((!currentValue && command == ZCL_OFF_COMMAND_ID)
- || (currentValue && command == ZCL_ON_COMMAND_ID)) {
- emberAfOnOffClusterPrintln("On/off already set to new value");
- return EMBER_ZCL_STATUS_SUCCESS;
- }
-
- // we either got a toggle, or an on when off, or an off when on,
- // so we need to swap the value
- newValue = !currentValue;
- emberAfOnOffClusterPrintln("Toggle on/off from %x to %x", currentValue, newValue);
-
- // the sequence of updating on/off attribute and kick off level change effect should
- // be depend on whether we are turning on or off. If we are turning on the light, we
- // should update the on/off attribute before kicking off level change, if we are
- // turning off the light, we should do the opposite, that is kick off level change
- // before updating the on/off attribute.
- if (newValue) {
- // write the new on/off value
- status = emberAfWriteAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&newValue,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfOnOffClusterPrintln("ERR: writing on/off %x", status);
- return status;
+ // read current on/off value
+ status = emberAfReadAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ (uint8_t *) ¤tValue, sizeof(currentValue),
+ NULL); // data type
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfOnOffClusterPrintln("ERR: reading on/off %x", status);
+ return status;
}
- // If initiatedByLevelChange is false, then we assume that the level change
- // ZCL stuff has not happened and we do it here
- if (!initiatedByLevelChange
- && emberAfContainsServer(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID)) {
- emberAfOnOffClusterLevelControlEffectCallback(endpoint,
- newValue);
- }
- } else {
- // If initiatedByLevelChange is false, then we assume that the level change
- // ZCL stuff has not happened and we do it here
- if (!initiatedByLevelChange
- && emberAfContainsServer(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID)) {
- emberAfOnOffClusterLevelControlEffectCallback(endpoint,
- newValue);
+ // if the value is already what we want to set it to then do nothing
+ if ((!currentValue && command == ZCL_OFF_COMMAND_ID) || (currentValue && command == ZCL_ON_COMMAND_ID))
+ {
+ emberAfOnOffClusterPrintln("On/off already set to new value");
+ return EMBER_ZCL_STATUS_SUCCESS;
}
- // write the new on/off value
- status = emberAfWriteAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&newValue,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfOnOffClusterPrintln("ERR: writing on/off %x", status);
- return status;
+ // we either got a toggle, or an on when off, or an off when on,
+ // so we need to swap the value
+ newValue = !currentValue;
+ emberAfOnOffClusterPrintln("Toggle on/off from %x to %x", currentValue, newValue);
+
+ // the sequence of updating on/off attribute and kick off level change effect should
+ // be depend on whether we are turning on or off. If we are turning on the light, we
+ // should update the on/off attribute before kicking off level change, if we are
+ // turning off the light, we should do the opposite, that is kick off level change
+ // before updating the on/off attribute.
+ if (newValue)
+ {
+ // write the new on/off value
+ status = emberAfWriteAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ (uint8_t *) &newValue, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfOnOffClusterPrintln("ERR: writing on/off %x", status);
+ return status;
+ }
+
+ // If initiatedByLevelChange is false, then we assume that the level change
+ // ZCL stuff has not happened and we do it here
+ if (!initiatedByLevelChange && emberAfContainsServer(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID))
+ {
+ emberAfOnOffClusterLevelControlEffectCallback(endpoint, newValue);
+ }
}
- }
+ else
+ {
+ // If initiatedByLevelChange is false, then we assume that the level change
+ // ZCL stuff has not happened and we do it here
+ if (!initiatedByLevelChange && emberAfContainsServer(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID))
+ {
+ emberAfOnOffClusterLevelControlEffectCallback(endpoint, newValue);
+ }
+
+ // write the new on/off value
+ status = emberAfWriteAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ (uint8_t *) &newValue, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfOnOffClusterPrintln("ERR: writing on/off %x", status);
+ return status;
+ }
+ }
#ifdef EMBER_AF_PLUGIN_ZLL_ON_OFF_SERVER
- if (initiatedByLevelChange) {
- emberAfPluginZllOnOffServerLevelControlZllExtensions(endpoint);
- }
+ if (initiatedByLevelChange)
+ {
+ emberAfPluginZllOnOffServerLevelControlZllExtensions(endpoint);
+ }
#endif
- // the scene has been changed (the value of on/off has changed) so
- // the current scene as descibed in the attribute table is invalid,
- // so mark it as invalid (just writes the valid/invalid attribute)
- if (emberAfContainsServer(endpoint, ZCL_SCENES_CLUSTER_ID)) {
- emberAfScenesClusterMakeInvalidCallback(endpoint);
- }
+ // the scene has been changed (the value of on/off has changed) so
+ // the current scene as descibed in the attribute table is invalid,
+ // so mark it as invalid (just writes the valid/invalid attribute)
+ if (emberAfContainsServer(endpoint, ZCL_SCENES_CLUSTER_ID))
+ {
+ emberAfScenesClusterMakeInvalidCallback(endpoint);
+ }
- // The returned status is based solely on the On/Off cluster. Errors in the
- // Level Control and/or Scenes cluster are ignored.
- return EMBER_ZCL_STATUS_SUCCESS;
+ // The returned status is based solely on the On/Off cluster. Errors in the
+ // Level Control and/or Scenes cluster are ignored.
+ return EMBER_ZCL_STATUS_SUCCESS;
}
bool emberAfOnOffClusterOffCallback(void)
{
- EmberAfStatus status = emberAfOnOffClusterSetValueCallback(emberAfCurrentEndpoint(),
- ZCL_OFF_COMMAND_ID,
- false);
+ EmberAfStatus status = emberAfOnOffClusterSetValueCallback(emberAfCurrentEndpoint(), ZCL_OFF_COMMAND_ID, false);
#ifdef EMBER_AF_PLUGIN_ZLL_ON_OFF_SERVER
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfPluginZllOnOffServerOffZllExtensions(emberAfCurrentCommand());
- }
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfPluginZllOnOffServerOffZllExtensions(emberAfCurrentCommand());
+ }
#endif
- emberAfSendImmediateDefaultResponse(status);
- return true;
+ emberAfSendImmediateDefaultResponse(status);
+ return true;
}
bool emberAfOnOffClusterOnCallback(void)
{
- EmberAfStatus status = emberAfOnOffClusterSetValueCallback(emberAfCurrentEndpoint(),
- ZCL_ON_COMMAND_ID,
- false);
+ EmberAfStatus status = emberAfOnOffClusterSetValueCallback(emberAfCurrentEndpoint(), ZCL_ON_COMMAND_ID, false);
#ifdef EMBER_AF_PLUGIN_ZLL_ON_OFF_SERVER
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfPluginZllOnOffServerOnZllExtensions(emberAfCurrentCommand());
- }
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfPluginZllOnOffServerOnZllExtensions(emberAfCurrentCommand());
+ }
#endif
- emberAfSendImmediateDefaultResponse(status);
- return true;
+ emberAfSendImmediateDefaultResponse(status);
+ return true;
}
bool emberAfOnOffClusterToggleCallback(void)
{
- EmberAfStatus status = emberAfOnOffClusterSetValueCallback(emberAfCurrentEndpoint(),
- ZCL_TOGGLE_COMMAND_ID,
- false);
+ EmberAfStatus status = emberAfOnOffClusterSetValueCallback(emberAfCurrentEndpoint(), ZCL_TOGGLE_COMMAND_ID, false);
#ifdef EMBER_AF_PLUGIN_ZLL_ON_OFF_SERVER
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfPluginZllOnOffServerToggleZllExtensions(emberAfCurrentCommand());
- }
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfPluginZllOnOffServerToggleZllExtensions(emberAfCurrentCommand());
+ }
#endif
- emberAfSendImmediateDefaultResponse(status);
- return true;
+ emberAfSendImmediateDefaultResponse(status);
+ return true;
}
void emberAfOnOffClusterServerInitCallback(uint8_t endpoint)
{
#ifdef ZCL_USING_ON_OFF_CLUSTER_START_UP_ON_OFF_ATTRIBUTE
- // StartUp behavior relies on OnOff and StartUpOnOff attributes being tokenized.
- if (areStartUpOnOffServerAttributesTokenized(endpoint)) {
- // Read the StartUpOnOff attribute and set the OnOff attribute as per
- // following from zcl 7 14-0127-20i-zcl-ch-3-general.doc.
- // 3.8.2.2.5 StartUpOnOff Attribute
- // The StartUpOnOff attribute SHALL define the desired startup behavior of a
- // lamp device when it is supplied with power and this state SHALL be
- // reflected in the OnOff attribute. The values of the StartUpOnOff
- // attribute are listed below.
- // Table 3 46. Values of the StartUpOnOff Attribute
- // Value Action on power up
- // 0x00 Set the OnOff attribute to 0 (off).
- // 0x01 Set the OnOff attribute to 1 (on).
- // 0x02 If the previous value of the OnOff attribute is equal to 0,
- // set the OnOff attribute to 1.If the previous value of the OnOff
- // attribute is equal to 1, set the OnOff attribute to 0 (toggle).
- // 0x03-0xfe These values are reserved. No action.
- // 0xff Set the OnOff attribute to its previous value.
+ // StartUp behavior relies on OnOff and StartUpOnOff attributes being tokenized.
+ if (areStartUpOnOffServerAttributesTokenized(endpoint))
+ {
+ // Read the StartUpOnOff attribute and set the OnOff attribute as per
+ // following from zcl 7 14-0127-20i-zcl-ch-3-general.doc.
+ // 3.8.2.2.5 StartUpOnOff Attribute
+ // The StartUpOnOff attribute SHALL define the desired startup behavior of a
+ // lamp device when it is supplied with power and this state SHALL be
+ // reflected in the OnOff attribute. The values of the StartUpOnOff
+ // attribute are listed below.
+ // Table 3 46. Values of the StartUpOnOff Attribute
+ // Value Action on power up
+ // 0x00 Set the OnOff attribute to 0 (off).
+ // 0x01 Set the OnOff attribute to 1 (on).
+ // 0x02 If the previous value of the OnOff attribute is equal to 0,
+ // set the OnOff attribute to 1.If the previous value of the OnOff
+ // attribute is equal to 1, set the OnOff attribute to 0 (toggle).
+ // 0x03-0xfe These values are reserved. No action.
+ // 0xff Set the OnOff attribute to its previous value.
- // Initialize startUpOnOff to No action value 0xFE
- uint8_t startUpOnOff = 0xFE;
- EmberAfStatus status = emberAfReadAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_START_UP_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&startUpOnOff,
- sizeof(startUpOnOff),
- NULL);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- // Initialise updated value to 0
- bool updatedOnOff = 0;
- status = emberAfReadAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&updatedOnOff,
- sizeof(updatedOnOff),
- NULL);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- switch (startUpOnOff) {
- case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_OFF:
- updatedOnOff = 0; // Off
- break;
- case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_ON:
- updatedOnOff = 1; //On
- break;
- case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_TOGGLE:
- updatedOnOff = !updatedOnOff;
- break;
- case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_PREVIOUS:
- default:
- // All other values 0x03- 0xFE are reserved - no action.
- // When value is 0xFF - update with last value - that is as good as
- // no action.
- break;
+ // Initialize startUpOnOff to No action value 0xFE
+ uint8_t startUpOnOff = 0xFE;
+ EmberAfStatus status = emberAfReadAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_START_UP_ON_OFF_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, (uint8_t *) &startUpOnOff, sizeof(startUpOnOff), NULL);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ // Initialise updated value to 0
+ bool updatedOnOff = 0;
+ status = emberAfReadAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ (uint8_t *) &updatedOnOff, sizeof(updatedOnOff), NULL);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ switch (startUpOnOff)
+ {
+ case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_OFF:
+ updatedOnOff = 0; // Off
+ break;
+ case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_ON:
+ updatedOnOff = 1; // On
+ break;
+ case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_TOGGLE:
+ updatedOnOff = !updatedOnOff;
+ break;
+ case EMBER_ZCL_START_UP_ON_OFF_VALUE_SET_TO_PREVIOUS:
+ default:
+ // All other values 0x03- 0xFE are reserved - no action.
+ // When value is 0xFF - update with last value - that is as good as
+ // no action.
+ break;
+ }
+ status = emberAfWriteAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ (uint8_t *) &updatedOnOff, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ }
}
- status = emberAfWriteAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- (uint8_t *)&updatedOnOff,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
- }
}
- }
#endif
- emberAfPluginOnOffClusterServerPostInitCallback(endpoint);
+ emberAfPluginOnOffClusterServerPostInitCallback(endpoint);
}
#ifdef ZCL_USING_ON_OFF_CLUSTER_START_UP_ON_OFF_ATTRIBUTE
static bool areStartUpOnOffServerAttributesTokenized(uint8_t endpoint)
{
- EmberAfAttributeMetadata *metadata;
+ EmberAfAttributeMetadata * metadata;
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, CLUSTER_MASK_SERVER,
+ EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- metadata = emberAfLocateAttributeMetadata(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_START_UP_ON_OFF_ATTRIBUTE_ID,
- CLUSTER_MASK_SERVER,
- EMBER_AF_NULL_MANUFACTURER_CODE);
- if (!emberAfAttributeIsTokenized(metadata)) {
- return false;
- }
+ metadata = emberAfLocateAttributeMetadata(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_START_UP_ON_OFF_ATTRIBUTE_ID,
+ CLUSTER_MASK_SERVER, EMBER_AF_NULL_MANUFACTURER_CODE);
+ if (!emberAfAttributeIsTokenized(metadata))
+ {
+ return false;
+ }
- return true;
+ return true;
}
#endif
diff --git a/src/app/clusters/poll-control-client/poll-control-client-cli.c b/src/app/clusters/poll-control-client/poll-control-client-cli.c
index 7169a3d..dd1a56d 100644
--- a/src/app/clusters/poll-control-client/poll-control-client-cli.c
+++ b/src/app/clusters/poll-control-client/poll-control-client-cli.c
@@ -31,15 +31,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the Poll Control Client plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
-#include "app/util/serial/command-interpreter2.h"
#include "app/framework/plugin/poll-control-client/poll-control-client.h"
+#include "app/util/serial/command-interpreter2.h"
void mode(void);
void timeout(void);
@@ -48,39 +48,39 @@
#ifndef EMBER_AF_GENERATE_CLI
EmberCommandEntry emberAfPluginPollControlClientCommands[] = {
- emberCommandEntryAction("mode", mode, "u", ""),
- emberCommandEntryAction("timeout", timeout, "v", ""),
- emberCommandEntryAction("respond", respond, "u", ""),
- emberCommandEntryAction("print", print, "", ""),
- emberCommandEntryTerminator(),
+ emberCommandEntryAction("mode", mode, "u", ""),
+ emberCommandEntryAction("timeout", timeout, "v", ""),
+ emberCommandEntryAction("respond", respond, "u", ""),
+ emberCommandEntryAction("print", print, "", ""),
+ emberCommandEntryTerminator(),
};
#endif // EMBER_AF_GENERATE_CLI
// plugin poll-control-client mode <mode:1>
void mode(void)
{
- uint8_t mode = (uint8_t)emberUnsignedCommandArgument(0);
- emAfSetFastPollingMode(mode);
- emberAfPollControlClusterPrintln("%p 0x%x", "mode", mode);
+ uint8_t mode = (uint8_t) emberUnsignedCommandArgument(0);
+ emAfSetFastPollingMode(mode);
+ emberAfPollControlClusterPrintln("%p 0x%x", "mode", mode);
}
// plugin poll-control-client timeout <timeout:2>
void timeout(void)
{
- uint16_t timeout = (uint16_t)emberUnsignedCommandArgument(0);
- emAfSetFastPollingTimeout(timeout);
- emberAfPollControlClusterPrintln("%p 0x%2x", "timeout", timeout);
+ uint16_t timeout = (uint16_t) emberUnsignedCommandArgument(0);
+ emAfSetFastPollingTimeout(timeout);
+ emberAfPollControlClusterPrintln("%p 0x%2x", "timeout", timeout);
}
// plugin poll-control-client respond <mode:1>
void respond(void)
{
- uint8_t mode = (uint8_t)emberUnsignedCommandArgument(0);
- emAfSetResponseMode(mode);
- emberAfPollControlClusterPrintln("%p 0x%x", "respond", mode);
+ uint8_t mode = (uint8_t) emberUnsignedCommandArgument(0);
+ emAfSetResponseMode(mode);
+ emberAfPollControlClusterPrintln("%p 0x%x", "respond", mode);
}
void print(void)
{
- emAfPollControlClientPrint();
+ emAfPollControlClientPrint();
}
diff --git a/src/app/clusters/poll-control-client/poll-control-client.c b/src/app/clusters/poll-control-client/poll-control-client.c
index 28b7280..565dce2 100644
--- a/src/app/clusters/poll-control-client/poll-control-client.c
+++ b/src/app/clusters/poll-control-client/poll-control-client.c
@@ -31,53 +31,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Poll Control Client plugin, which implement the
- * client side of the Poll Control cluster. The Poll Control cluster
- * provides a means to communicate with an end device with a sleep
+ * @brief Routines for the Poll Control Client plugin,
+ *which implement the client side of the Poll Control
+ *cluster. The Poll Control cluster provides a means
+ *to communicate with an end device with a sleep
* schedule.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-#include "../../include/af.h"
#include "poll-control-client.h"
+#include "../../include/af.h"
-static bool fastPolling = false;
-static bool respondToCheckIn = true;
+static bool fastPolling = false;
+static bool respondToCheckIn = true;
static uint16_t fastPollingTimeout = EMBER_AF_PLUGIN_POLL_CONTROL_CLIENT_DEFAULT_FAST_POLL_TIMEOUT;
void emAfSetFastPollingMode(bool mode)
{
- fastPolling = mode;
+ fastPolling = mode;
}
void emAfSetFastPollingTimeout(uint16_t timeout)
{
- fastPollingTimeout = timeout;
+ fastPollingTimeout = timeout;
}
void emAfSetResponseMode(bool mode)
{
- respondToCheckIn = mode;
+ respondToCheckIn = mode;
}
bool emberAfPollControlClusterCheckInCallback(void)
{
- emberAfPollControlClusterPrintln("RX: CheckIn");
- if (respondToCheckIn) {
- emberAfFillCommandPollControlClusterCheckInResponse(fastPolling,
- fastPollingTimeout);
- emberAfSendResponse();
- }
- return true;
+ emberAfPollControlClusterPrintln("RX: CheckIn");
+ if (respondToCheckIn)
+ {
+ emberAfFillCommandPollControlClusterCheckInResponse(fastPolling, fastPollingTimeout);
+ emberAfSendResponse();
+ }
+ return true;
}
void emAfPollControlClientPrint(void)
{
- emberAfPollControlClusterPrintln("Poll Control Client:\n%p %p\n%p 0x%2x",
- "fast polling: ",
- fastPolling ? "on" : "off",
- "fast polling timeout: ",
- fastPollingTimeout);
+ emberAfPollControlClusterPrintln("Poll Control Client:\n%p %p\n%p 0x%2x", "fast polling: ", fastPolling ? "on" : "off",
+ "fast polling timeout: ", fastPollingTimeout);
}
diff --git a/src/app/clusters/poll-control-client/poll-control-client.h b/src/app/clusters/poll-control-client/poll-control-client.h
index 1155f51..9664789 100644
--- a/src/app/clusters/poll-control-client/poll-control-client.h
+++ b/src/app/clusters/poll-control-client/poll-control-client.h
@@ -31,11 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief APIs and defines for the Poll Control Client plugin.
+ * @brief APIs and defines for the Poll Control Client
+ *plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// Set fast polling mode
void emAfSetFastPollingMode(bool mode);
diff --git a/src/app/clusters/poll-control-server/poll-control-server.c b/src/app/clusters/poll-control-server/poll-control-server.c
index fc02cf6..1380e77 100644
--- a/src/app/clusters/poll-control-server/poll-control-server.c
+++ b/src/app/clusters/poll-control-server/poll-control-server.c
@@ -31,14 +31,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Poll Control Server plugin, which implement the
- * server side of the Poll Control cluster. The Poll Control cluster
- * provides a means to communicate with an end device with a sleep
+ * @brief Routines for the Poll Control Server plugin,
+ *which implement the server side of the Poll Control
+ *cluster. The Poll Control cluster provides a means
+ *to communicate with an end device with a sleep
* schedule.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
@@ -47,7 +48,7 @@
// limited to exactly one endpoint that implements the Poll Control cluster
// server.
#if EMBER_AF_POLL_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT != 1
- #error "The Poll Control Server plugin only supports one endpoint."
+#error "The Poll Control Server plugin only supports one endpoint."
#endif
// The built-in cluster tick has hooks into the polling code and is therefore
@@ -76,17 +77,19 @@
extern EmberEventControl emberAfPluginPollControlServerCheckInEndpointEventControls[];
-typedef struct {
- uint8_t bindingIndex;
- uint16_t fastPollTimeoutQs;
+typedef struct
+{
+ uint8_t bindingIndex;
+ uint16_t fastPollTimeoutQs;
} Client;
static Client clients[EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS];
static bool ignoreNonTrustCenter = false;
-enum {
- INITIAL = 0,
- WAITING = 1,
- POLLING = 2,
+enum
+{
+ INITIAL = 0,
+ WAITING = 1,
+ POLLING = 2,
};
static uint8_t state = INITIAL;
static uint32_t fastPollStartTimeMs;
@@ -97,737 +100,699 @@
static uint8_t trustCenterCheckInFailureCount;
// The timeout option is in quarter seconds, but we use it in milliseconds.
-#define CHECK_IN_TIMEOUT_DURATION_MS \
- (EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_CHECK_IN_RESPONSE_TIMEOUT \
- * MILLISECOND_TICKS_PER_QUARTERSECOND)
+#define CHECK_IN_TIMEOUT_DURATION_MS \
+ (EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_CHECK_IN_RESPONSE_TIMEOUT * MILLISECOND_TICKS_PER_QUARTERSECOND)
#define NULL_INDEX 0xFF
-static EmberAfStatus readServerAttribute(uint8_t endpoint,
- EmberAfAttributeId attributeId,
- const char * name,
- uint8_t *data,
+static EmberAfStatus readServerAttribute(uint8_t endpoint, EmberAfAttributeId attributeId, const char * name, uint8_t * data,
uint8_t size)
{
- EmberAfStatus status = emberAfReadServerAttribute(endpoint,
- ZCL_POLL_CONTROL_CLUSTER_ID,
- attributeId,
- data,
- size);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfPollControlClusterPrintln("ERR: %ping %p 0x%x", "read", name, status);
- }
- return status;
+ EmberAfStatus status = emberAfReadServerAttribute(endpoint, ZCL_POLL_CONTROL_CLUSTER_ID, attributeId, data, size);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfPollControlClusterPrintln("ERR: %ping %p 0x%x", "read", name, status);
+ }
+ return status;
}
-static EmberAfStatus writeServerAttribute(uint8_t endpoint,
- EmberAfAttributeId attributeId,
- const char * name,
- uint8_t *data,
+static EmberAfStatus writeServerAttribute(uint8_t endpoint, EmberAfAttributeId attributeId, const char * name, uint8_t * data,
EmberAfAttributeType type)
{
- EmberAfStatus status = emberAfWriteServerAttribute(endpoint,
- ZCL_POLL_CONTROL_CLUSTER_ID,
- attributeId,
- data,
- type);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfPollControlClusterPrintln("ERR: %ping %p 0x%x", "writ", name, status);
- }
- return status;
+ EmberAfStatus status = emberAfWriteServerAttribute(endpoint, ZCL_POLL_CONTROL_CLUSTER_ID, attributeId, data, type);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfPollControlClusterPrintln("ERR: %ping %p 0x%x", "writ", name, status);
+ }
+ return status;
}
static EmberStatus scheduleServerTick(uint8_t endpoint, uint32_t delayMs)
{
- return emberAfScheduleServerTickExtended(endpoint,
- ZCL_POLL_CONTROL_CLUSTER_ID,
- delayMs,
- EMBER_AF_SHORT_POLL,
- EMBER_AF_OK_TO_SLEEP);
+ return emberAfScheduleServerTickExtended(endpoint, ZCL_POLL_CONTROL_CLUSTER_ID, delayMs, EMBER_AF_SHORT_POLL,
+ EMBER_AF_OK_TO_SLEEP);
}
static EmberStatus deactivateServerTick(uint8_t endpoint)
{
- return emberAfDeactivateServerTick(endpoint, ZCL_POLL_CONTROL_CLUSTER_ID);
+ return emberAfDeactivateServerTick(endpoint, ZCL_POLL_CONTROL_CLUSTER_ID);
}
static void scheduleCheckIn(uint8_t endpoint)
{
- EmberAfStatus status;
- uint32_t checkInIntervalQs;
- status = readServerAttribute(endpoint,
- ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID,
- "check in interval",
- (uint8_t *)&checkInIntervalQs,
- sizeof(checkInIntervalQs));
- if (status == EMBER_ZCL_STATUS_SUCCESS && checkInIntervalQs != 0) {
- emberAfEndpointEventControlSetDelayMS(emberAfPluginPollControlServerCheckInEndpointEventControls,
- endpoint,
- (checkInIntervalQs
- * MILLISECOND_TICKS_PER_QUARTERSECOND));
- } else {
- emberAfEndpointEventControlSetInactive(emberAfPluginPollControlServerCheckInEndpointEventControls,
- endpoint);
- }
+ EmberAfStatus status;
+ uint32_t checkInIntervalQs;
+ status = readServerAttribute(endpoint, ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID, "check in interval", (uint8_t *) &checkInIntervalQs,
+ sizeof(checkInIntervalQs));
+ if (status == EMBER_ZCL_STATUS_SUCCESS && checkInIntervalQs != 0)
+ {
+ emberAfEndpointEventControlSetDelayMS(emberAfPluginPollControlServerCheckInEndpointEventControls, endpoint,
+ (checkInIntervalQs * MILLISECOND_TICKS_PER_QUARTERSECOND));
+ }
+ else
+ {
+ emberAfEndpointEventControlSetInactive(emberAfPluginPollControlServerCheckInEndpointEventControls, endpoint);
+ }
}
static uint8_t findClientIndex(void)
{
- EmberBindingTableEntry incomingBinding;
- uint8_t incomingBindingIndex = emberAfGetBindingIndex();
- if (emberGetBinding(incomingBindingIndex, &incomingBinding)
- == EMBER_SUCCESS) {
- uint8_t clientIndex;
- for (clientIndex = 0;
- clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS;
- clientIndex++) {
- EmberBindingTableEntry clientBinding;
- if ((emberGetBinding(clients[clientIndex].bindingIndex, &clientBinding)
- == EMBER_SUCCESS)
- && incomingBinding.type == clientBinding.type
- && incomingBinding.local == clientBinding.local
- && incomingBinding.remote == clientBinding.remote
- && (MEMCOMPARE(incomingBinding.identifier,
- clientBinding.identifier,
- EUI64_SIZE)
- == 0)) {
- return clientIndex;
- }
+ EmberBindingTableEntry incomingBinding;
+ uint8_t incomingBindingIndex = emberAfGetBindingIndex();
+ if (emberGetBinding(incomingBindingIndex, &incomingBinding) == EMBER_SUCCESS)
+ {
+ uint8_t clientIndex;
+ for (clientIndex = 0; clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; clientIndex++)
+ {
+ EmberBindingTableEntry clientBinding;
+ if ((emberGetBinding(clients[clientIndex].bindingIndex, &clientBinding) == EMBER_SUCCESS) &&
+ incomingBinding.type == clientBinding.type && incomingBinding.local == clientBinding.local &&
+ incomingBinding.remote == clientBinding.remote &&
+ (MEMCOMPARE(incomingBinding.identifier, clientBinding.identifier, EUI64_SIZE) == 0))
+ {
+ return clientIndex;
+ }
+ }
}
- }
- return NULL_INDEX;
+ return NULL_INDEX;
}
static bool pendingCheckInResponses(void)
{
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; i++) {
- if (clients[i].bindingIndex != NULL_INDEX
- && clients[i].fastPollTimeoutQs == 0) {
- return true;
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; i++)
+ {
+ if (clients[i].bindingIndex != NULL_INDEX && clients[i].fastPollTimeoutQs == 0)
+ {
+ return true;
+ }
}
- }
- return false;
+ return false;
}
static bool isPollControlBindingTrustCenter(uint8_t endpoint, uint8_t bindingIndex)
{
- EmberBindingTableEntry binding;
- if (emberGetBinding(bindingIndex, &binding) == EMBER_SUCCESS
- && binding.type == EMBER_UNICAST_BINDING
- && binding.local == endpoint
- && binding.clusterId == ZCL_POLL_CONTROL_CLUSTER_ID) {
- EmberEUI64 trustCenterEui64;
- if (emberLookupEui64ByNodeId(EMBER_TRUST_CENTER_NODE_ID, trustCenterEui64) != EMBER_SUCCESS) {
- return false;
- }
+ EmberBindingTableEntry binding;
+ if (emberGetBinding(bindingIndex, &binding) == EMBER_SUCCESS && binding.type == EMBER_UNICAST_BINDING &&
+ binding.local == endpoint && binding.clusterId == ZCL_POLL_CONTROL_CLUSTER_ID)
+ {
+ EmberEUI64 trustCenterEui64;
+ if (emberLookupEui64ByNodeId(EMBER_TRUST_CENTER_NODE_ID, trustCenterEui64) != EMBER_SUCCESS)
+ {
+ return false;
+ }
- if (0 == MEMCOMPARE(binding.identifier, trustCenterEui64, EUI64_SIZE)) {
- return true;
+ if (0 == MEMCOMPARE(binding.identifier, trustCenterEui64, EUI64_SIZE))
+ {
+ return true;
+ }
}
- }
- return false;
+ return false;
}
static bool outstandingFastPollRequests(uint8_t endpoint)
{
- uint32_t currentTimeMs = halCommonGetInt32uMillisecondTick();
- uint32_t elapsedFastPollTimeMs = elapsedTimeInt32u(fastPollStartTimeMs,
- currentTimeMs);
- uint16_t fastPollTimeoutQs = 0;
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; i++) {
- if (clients[i].bindingIndex != NULL_INDEX) {
- if (clients[i].fastPollTimeoutQs * MILLISECOND_TICKS_PER_QUARTERSECOND
- < elapsedFastPollTimeMs) {
- clients[i].bindingIndex = NULL_INDEX;
- } else if (fastPollTimeoutQs < clients[i].fastPollTimeoutQs) {
- fastPollTimeoutQs = clients[i].fastPollTimeoutQs;
- }
+ uint32_t currentTimeMs = halCommonGetInt32uMillisecondTick();
+ uint32_t elapsedFastPollTimeMs = elapsedTimeInt32u(fastPollStartTimeMs, currentTimeMs);
+ uint16_t fastPollTimeoutQs = 0;
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; i++)
+ {
+ if (clients[i].bindingIndex != NULL_INDEX)
+ {
+ if (clients[i].fastPollTimeoutQs * MILLISECOND_TICKS_PER_QUARTERSECOND < elapsedFastPollTimeMs)
+ {
+ clients[i].bindingIndex = NULL_INDEX;
+ }
+ else if (fastPollTimeoutQs < clients[i].fastPollTimeoutQs)
+ {
+ fastPollTimeoutQs = clients[i].fastPollTimeoutQs;
+ }
+ }
}
- }
- if (fastPollTimeoutQs == 0) {
- return false;
- } else {
- uint32_t newFastPollEndTimeMs = (fastPollStartTimeMs
- + (fastPollTimeoutQs
- * MILLISECOND_TICKS_PER_QUARTERSECOND));
- uint32_t remainingFastPollTimeMs = elapsedTimeInt32u(currentTimeMs,
- newFastPollEndTimeMs);
- scheduleServerTick(endpoint, remainingFastPollTimeMs);
- return true;
- }
+ if (fastPollTimeoutQs == 0)
+ {
+ return false;
+ }
+ else
+ {
+ uint32_t newFastPollEndTimeMs = (fastPollStartTimeMs + (fastPollTimeoutQs * MILLISECOND_TICKS_PER_QUARTERSECOND));
+ uint32_t remainingFastPollTimeMs = elapsedTimeInt32u(currentTimeMs, newFastPollEndTimeMs);
+ scheduleServerTick(endpoint, remainingFastPollTimeMs);
+ return true;
+ }
}
-static EmberAfStatus validateCheckInInterval(uint8_t endpoint,
- uint32_t newCheckInIntervalQs)
+static EmberAfStatus validateCheckInInterval(uint8_t endpoint, uint32_t newCheckInIntervalQs)
{
- EmberAfStatus status;
- uint32_t longPollIntervalQs;
+ EmberAfStatus status;
+ uint32_t longPollIntervalQs;
- if (newCheckInIntervalQs == 0) {
- return EMBER_ZCL_STATUS_SUCCESS;
- }
+ if (newCheckInIntervalQs == 0)
+ {
+ return EMBER_ZCL_STATUS_SUCCESS;
+ }
- status = readServerAttribute(endpoint,
- ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID,
- "long poll interval",
- (uint8_t *)&longPollIntervalQs,
- sizeof(longPollIntervalQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (newCheckInIntervalQs < longPollIntervalQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
+ status = readServerAttribute(endpoint, ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID, "long poll interval",
+ (uint8_t *) &longPollIntervalQs, sizeof(longPollIntervalQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (newCheckInIntervalQs < longPollIntervalQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
#ifdef ZCL_USING_POLL_CONTROL_CLUSTER_CHECK_IN_INTERVAL_MIN_ATTRIBUTE
- {
- uint32_t checkInIntervalMinQs;
- status = readServerAttribute(endpoint,
- ZCL_CHECK_IN_INTERVAL_MIN_ATTRIBUTE_ID,
- "check in interval min",
- (uint8_t *)&checkInIntervalMinQs,
- sizeof(checkInIntervalMinQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (newCheckInIntervalQs < checkInIntervalMinQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
+ {
+ uint32_t checkInIntervalMinQs;
+ status = readServerAttribute(endpoint, ZCL_CHECK_IN_INTERVAL_MIN_ATTRIBUTE_ID, "check in interval min",
+ (uint8_t *) &checkInIntervalMinQs, sizeof(checkInIntervalMinQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (newCheckInIntervalQs < checkInIntervalMinQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
}
- }
#endif
- return EMBER_ZCL_STATUS_SUCCESS;
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-static EmberAfStatus validateLongPollInterval(uint8_t endpoint,
- uint32_t newLongPollIntervalQs)
+static EmberAfStatus validateLongPollInterval(uint8_t endpoint, uint32_t newLongPollIntervalQs)
{
- EmberAfStatus status;
- uint32_t checkInIntervalQs;
- uint16_t shortPollIntervalQs;
+ EmberAfStatus status;
+ uint32_t checkInIntervalQs;
+ uint16_t shortPollIntervalQs;
- status = readServerAttribute(endpoint,
- ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID,
- "check in interval",
- (uint8_t *)&checkInIntervalQs,
- sizeof(checkInIntervalQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (checkInIntervalQs < newLongPollIntervalQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
+ status = readServerAttribute(endpoint, ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID, "check in interval", (uint8_t *) &checkInIntervalQs,
+ sizeof(checkInIntervalQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (checkInIntervalQs < newLongPollIntervalQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
- status = readServerAttribute(endpoint,
- ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID,
- "short poll interval",
- (uint8_t *)&shortPollIntervalQs,
- sizeof(shortPollIntervalQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (newLongPollIntervalQs < shortPollIntervalQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
+ status = readServerAttribute(endpoint, ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID, "short poll interval",
+ (uint8_t *) &shortPollIntervalQs, sizeof(shortPollIntervalQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (newLongPollIntervalQs < shortPollIntervalQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
#ifdef ZCL_USING_POLL_CONTROL_CLUSTER_LONG_POLL_INTERVAL_MIN_ATTRIBUTE
- {
- uint32_t longPollIntervalMinQs;
- status = readServerAttribute(endpoint,
- ZCL_LONG_POLL_INTERVAL_MIN_ATTRIBUTE_ID,
- "long poll interval min",
- (uint8_t *)&longPollIntervalMinQs,
- sizeof(longPollIntervalMinQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (newLongPollIntervalQs < longPollIntervalMinQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
+ {
+ uint32_t longPollIntervalMinQs;
+ status = readServerAttribute(endpoint, ZCL_LONG_POLL_INTERVAL_MIN_ATTRIBUTE_ID, "long poll interval min",
+ (uint8_t *) &longPollIntervalMinQs, sizeof(longPollIntervalMinQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (newLongPollIntervalQs < longPollIntervalMinQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
}
- }
#endif
- return EMBER_ZCL_STATUS_SUCCESS;
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-static EmberAfStatus validateShortPollInterval(uint8_t endpoint,
- uint16_t newShortPollIntervalQs)
+static EmberAfStatus validateShortPollInterval(uint8_t endpoint, uint16_t newShortPollIntervalQs)
{
- EmberAfStatus status;
- uint32_t longPollIntervalQs;
- status = readServerAttribute(endpoint,
- ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID,
- "long poll interval",
- (uint8_t *)&longPollIntervalQs,
- sizeof(longPollIntervalQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (longPollIntervalQs < newShortPollIntervalQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
- return EMBER_ZCL_STATUS_SUCCESS;
+ EmberAfStatus status;
+ uint32_t longPollIntervalQs;
+ status = readServerAttribute(endpoint, ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID, "long poll interval",
+ (uint8_t *) &longPollIntervalQs, sizeof(longPollIntervalQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (longPollIntervalQs < newShortPollIntervalQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-static EmberAfStatus validateFastPollInterval(uint8_t endpoint,
- uint16_t newFastPollIntervalQs)
+static EmberAfStatus validateFastPollInterval(uint8_t endpoint, uint16_t newFastPollIntervalQs)
{
#ifdef ZCL_USING_POLL_CONTROL_CLUSTER_FAST_POLL_TIMEOUT_MAX_ATTRIBUTE
- EmberAfStatus status;
- uint16_t fastPollTimeoutMaxQs;
- status = readServerAttribute(endpoint,
- ZCL_FAST_POLL_TIMEOUT_MAX_ATTRIBUTE_ID,
- "fast poll timeout max",
- (uint8_t *)&fastPollTimeoutMaxQs,
- sizeof(fastPollTimeoutMaxQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (fastPollTimeoutMaxQs < newFastPollIntervalQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
+ EmberAfStatus status;
+ uint16_t fastPollTimeoutMaxQs;
+ status = readServerAttribute(endpoint, ZCL_FAST_POLL_TIMEOUT_MAX_ATTRIBUTE_ID, "fast poll timeout max",
+ (uint8_t *) &fastPollTimeoutMaxQs, sizeof(fastPollTimeoutMaxQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (fastPollTimeoutMaxQs < newFastPollIntervalQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
#endif
- return EMBER_ZCL_STATUS_SUCCESS;
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-static EmberAfStatus validateCheckInIntervalMin(uint8_t endpoint,
- uint32_t newCheckInIntervalMinQs)
+static EmberAfStatus validateCheckInIntervalMin(uint8_t endpoint, uint32_t newCheckInIntervalMinQs)
{
- EmberAfStatus status;
- uint32_t checkInIntervalQs;
- status = readServerAttribute(endpoint,
- ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID,
- "check in interval",
- (uint8_t *)&checkInIntervalQs,
- sizeof(checkInIntervalQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (checkInIntervalQs < newCheckInIntervalMinQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
- return EMBER_ZCL_STATUS_SUCCESS;
+ EmberAfStatus status;
+ uint32_t checkInIntervalQs;
+ status = readServerAttribute(endpoint, ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID, "check in interval", (uint8_t *) &checkInIntervalQs,
+ sizeof(checkInIntervalQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (checkInIntervalQs < newCheckInIntervalMinQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-static EmberAfStatus validateLongPollIntervalMin(uint8_t endpoint,
- uint32_t newLongPollIntervalMinQs)
+static EmberAfStatus validateLongPollIntervalMin(uint8_t endpoint, uint32_t newLongPollIntervalMinQs)
{
- EmberAfStatus status;
- uint32_t longPollIntervalQs;
- status = readServerAttribute(endpoint,
- ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID,
- "long poll interval",
- (uint8_t *)&longPollIntervalQs,
- sizeof(longPollIntervalQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (longPollIntervalQs < newLongPollIntervalMinQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
- return EMBER_ZCL_STATUS_SUCCESS;
+ EmberAfStatus status;
+ uint32_t longPollIntervalQs;
+ status = readServerAttribute(endpoint, ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID, "long poll interval",
+ (uint8_t *) &longPollIntervalQs, sizeof(longPollIntervalQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (longPollIntervalQs < newLongPollIntervalMinQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-static EmberAfStatus validateFastPollTimeoutMax(uint8_t endpoint,
- uint16_t newFastPollTimeoutMaxQs)
+static EmberAfStatus validateFastPollTimeoutMax(uint8_t endpoint, uint16_t newFastPollTimeoutMaxQs)
{
- EmberAfStatus status;
- uint16_t fastPollTimeoutQs;
- status = readServerAttribute(endpoint,
- ZCL_FAST_POLL_TIMEOUT_ATTRIBUTE_ID,
- "fast poll timeout",
- (uint8_t *)&fastPollTimeoutQs,
- sizeof(fastPollTimeoutQs));
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- } else if (newFastPollTimeoutMaxQs < fastPollTimeoutQs) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
- return EMBER_ZCL_STATUS_SUCCESS;
+ EmberAfStatus status;
+ uint16_t fastPollTimeoutQs;
+ status = readServerAttribute(endpoint, ZCL_FAST_POLL_TIMEOUT_ATTRIBUTE_ID, "fast poll timeout", (uint8_t *) &fastPollTimeoutQs,
+ sizeof(fastPollTimeoutQs));
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+ else if (newFastPollTimeoutMaxQs < fastPollTimeoutQs)
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
+ return EMBER_ZCL_STATUS_SUCCESS;
}
void emberAfPollControlClusterServerInitCallback(uint8_t endpoint)
{
- uint32_t longPollIntervalQs;
- uint16_t shortPollIntervalQs;
+ uint32_t longPollIntervalQs;
+ uint16_t shortPollIntervalQs;
- if (readServerAttribute(endpoint,
- ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID,
- "long poll interval",
- (uint8_t *)&longPollIntervalQs,
- sizeof(longPollIntervalQs))
- == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfSetLongPollIntervalQsCallback(longPollIntervalQs);
- }
+ if (readServerAttribute(endpoint, ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID, "long poll interval", (uint8_t *) &longPollIntervalQs,
+ sizeof(longPollIntervalQs)) == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfSetLongPollIntervalQsCallback(longPollIntervalQs);
+ }
- if (readServerAttribute(endpoint,
- ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID,
- "short poll interval",
- (uint8_t *)&shortPollIntervalQs,
- sizeof(shortPollIntervalQs))
- == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfSetShortPollIntervalQsCallback(shortPollIntervalQs);
- }
+ if (readServerAttribute(endpoint, ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID, "short poll interval", (uint8_t *) &shortPollIntervalQs,
+ sizeof(shortPollIntervalQs)) == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfSetShortPollIntervalQsCallback(shortPollIntervalQs);
+ }
- // TODO: Begin checking in after the network comes up instead of at startup.
- scheduleCheckIn(endpoint);
+ // TODO: Begin checking in after the network comes up instead of at startup.
+ scheduleCheckIn(endpoint);
}
void emberAfPollControlClusterServerTickCallback(uint8_t endpoint)
{
- if (state == WAITING) {
- uint16_t fastPollTimeoutQs = 0;
- uint8_t i;
+ if (state == WAITING)
+ {
+ uint16_t fastPollTimeoutQs = 0;
+ uint8_t i;
- if (trustCenterCheckInRequestSent && !trustCenterCheckInResponseReceived) {
- trustCenterCheckInFailureCount++;
- emberAfPollControlClusterPrintln("ERR: Poll control check in failure (%d of %d)",
- trustCenterCheckInFailureCount,
- EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_TRUST_CENTER_CHECK_IN_FAILURE_THRESHOLD);
- if (trustCenterCheckInFailureCount >= EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_TRUST_CENTER_CHECK_IN_FAILURE_THRESHOLD) {
- emberAfPollControlClusterPrintln("ERR: Trust Center check in failure threshold reached");
- emberAfPluginPollControlServerCheckInTimeoutCallback();
- trustCenterCheckInFailureCount = 0;
- }
+ if (trustCenterCheckInRequestSent && !trustCenterCheckInResponseReceived)
+ {
+ trustCenterCheckInFailureCount++;
+ emberAfPollControlClusterPrintln("ERR: Poll control check in failure (%d of %d)", trustCenterCheckInFailureCount,
+ EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_TRUST_CENTER_CHECK_IN_FAILURE_THRESHOLD);
+ if (trustCenterCheckInFailureCount >= EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_TRUST_CENTER_CHECK_IN_FAILURE_THRESHOLD)
+ {
+ emberAfPollControlClusterPrintln("ERR: Trust Center check in failure threshold reached");
+ emberAfPluginPollControlServerCheckInTimeoutCallback();
+ trustCenterCheckInFailureCount = 0;
+ }
+ }
+
+ for (i = 0; i < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; i++)
+ {
+ if (clients[i].bindingIndex != NULL_INDEX && fastPollTimeoutQs < clients[i].fastPollTimeoutQs)
+ {
+ fastPollTimeoutQs = clients[i].fastPollTimeoutQs;
+ }
+ }
+
+ if (fastPollTimeoutQs != 0)
+ {
+ state = POLLING;
+ fastPollStartTimeMs = halCommonGetInt32uMillisecondTick();
+ scheduleServerTick(endpoint, (fastPollTimeoutQs * MILLISECOND_TICKS_PER_QUARTERSECOND));
+ return;
+ }
}
- for (i = 0; i < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; i++) {
- if (clients[i].bindingIndex != NULL_INDEX
- && fastPollTimeoutQs < clients[i].fastPollTimeoutQs) {
- fastPollTimeoutQs = clients[i].fastPollTimeoutQs;
- }
- }
-
- if (fastPollTimeoutQs != 0) {
- state = POLLING;
- fastPollStartTimeMs = halCommonGetInt32uMillisecondTick();
- scheduleServerTick(endpoint,
- (fastPollTimeoutQs
- * MILLISECOND_TICKS_PER_QUARTERSECOND));
- return;
- }
- }
-
- state = INITIAL;
- deactivateServerTick(endpoint);
+ state = INITIAL;
+ deactivateServerTick(endpoint);
}
void emberAfPluginPollControlServerCheckInEndpointEventHandler(uint8_t endpoint)
{
- uint8_t bindingIndex, clientIndex;
+ uint8_t bindingIndex, clientIndex;
- trustCenterCheckInRequestSent = false;
- trustCenterCheckInResponseReceived = false;
- for (clientIndex = 0;
- clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS;
- clientIndex++) {
- clients[clientIndex].bindingIndex = EMBER_NULL_BINDING;
- }
-
- for (bindingIndex = 0, clientIndex = 0;
- (bindingIndex < EMBER_BINDING_TABLE_SIZE
- && clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS);
- bindingIndex++) {
- EmberBindingTableEntry binding;
- if (emberGetBinding(bindingIndex, &binding) == EMBER_SUCCESS
- && binding.type == EMBER_UNICAST_BINDING
- && binding.local == endpoint
- && binding.clusterId == ZCL_POLL_CONTROL_CLUSTER_ID) {
- // If ignoreNonTrustCenter is true, then we only add
- // the trust center as a client.
- if (ignoreNonTrustCenter
- && (!isPollControlBindingTrustCenter(endpoint, bindingIndex))) {
- emberAfPollControlClusterPrintln("Ignoring poll control client with bindingIndex %d in search of TC",
- bindingIndex);
- continue;
- }
-
- emberAfFillCommandPollControlClusterCheckIn();
- if (emberAfSendCommandUnicast(EMBER_OUTGOING_VIA_BINDING, bindingIndex)
- == EMBER_SUCCESS) {
- clients[clientIndex].bindingIndex = bindingIndex;
- clients[clientIndex].fastPollTimeoutQs = 0;
- clientIndex++;
- if (isPollControlBindingTrustCenter(endpoint, bindingIndex)) {
- trustCenterCheckInRequestSent = true;
- }
- }
+ trustCenterCheckInRequestSent = false;
+ trustCenterCheckInResponseReceived = false;
+ for (clientIndex = 0; clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS; clientIndex++)
+ {
+ clients[clientIndex].bindingIndex = EMBER_NULL_BINDING;
}
- }
- if (clientIndex == 0) {
- state = INITIAL;
- deactivateServerTick(endpoint);
- } else {
- state = WAITING;
- scheduleServerTick(endpoint, CHECK_IN_TIMEOUT_DURATION_MS);
- }
+ for (bindingIndex = 0, clientIndex = 0;
+ (bindingIndex < EMBER_BINDING_TABLE_SIZE && clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS); bindingIndex++)
+ {
+ EmberBindingTableEntry binding;
+ if (emberGetBinding(bindingIndex, &binding) == EMBER_SUCCESS && binding.type == EMBER_UNICAST_BINDING &&
+ binding.local == endpoint && binding.clusterId == ZCL_POLL_CONTROL_CLUSTER_ID)
+ {
+ // If ignoreNonTrustCenter is true, then we only add
+ // the trust center as a client.
+ if (ignoreNonTrustCenter && (!isPollControlBindingTrustCenter(endpoint, bindingIndex)))
+ {
+ emberAfPollControlClusterPrintln("Ignoring poll control client with bindingIndex %d in search of TC", bindingIndex);
+ continue;
+ }
- scheduleCheckIn(endpoint);
+ emberAfFillCommandPollControlClusterCheckIn();
+ if (emberAfSendCommandUnicast(EMBER_OUTGOING_VIA_BINDING, bindingIndex) == EMBER_SUCCESS)
+ {
+ clients[clientIndex].bindingIndex = bindingIndex;
+ clients[clientIndex].fastPollTimeoutQs = 0;
+ clientIndex++;
+ if (isPollControlBindingTrustCenter(endpoint, bindingIndex))
+ {
+ trustCenterCheckInRequestSent = true;
+ }
+ }
+ }
+ }
+
+ if (clientIndex == 0)
+ {
+ state = INITIAL;
+ deactivateServerTick(endpoint);
+ }
+ else
+ {
+ state = WAITING;
+ scheduleServerTick(endpoint, CHECK_IN_TIMEOUT_DURATION_MS);
+ }
+
+ scheduleCheckIn(endpoint);
}
-EmberAfStatus emberAfPollControlClusterServerPreAttributeChangedCallback(uint8_t endpoint,
- EmberAfAttributeId attributeId,
- EmberAfAttributeType attributeType,
- uint8_t size,
- uint8_t *value)
+EmberAfStatus emberAfPollControlClusterServerPreAttributeChangedCallback(uint8_t endpoint, EmberAfAttributeId attributeId,
+ EmberAfAttributeType attributeType, uint8_t size,
+ uint8_t * value)
{
- switch (attributeId) {
- case ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID:
+ switch (attributeId)
{
- uint32_t newCheckInIntervalQs;
- MEMMOVE(&newCheckInIntervalQs, value, size);
- return validateCheckInInterval(endpoint, newCheckInIntervalQs);
+ case ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID: {
+ uint32_t newCheckInIntervalQs;
+ MEMMOVE(&newCheckInIntervalQs, value, size);
+ return validateCheckInInterval(endpoint, newCheckInIntervalQs);
}
- case ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID:
- {
- uint32_t newLongPollIntervalQs;
- MEMMOVE(&newLongPollIntervalQs, value, size);
- return validateLongPollInterval(endpoint, newLongPollIntervalQs);
+ case ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID: {
+ uint32_t newLongPollIntervalQs;
+ MEMMOVE(&newLongPollIntervalQs, value, size);
+ return validateLongPollInterval(endpoint, newLongPollIntervalQs);
}
- case ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID:
- {
- uint16_t newShortPollIntervalQs;
- MEMMOVE(&newShortPollIntervalQs, value, size);
- return validateShortPollInterval(endpoint, newShortPollIntervalQs);
+ case ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID: {
+ uint16_t newShortPollIntervalQs;
+ MEMMOVE(&newShortPollIntervalQs, value, size);
+ return validateShortPollInterval(endpoint, newShortPollIntervalQs);
}
- case ZCL_FAST_POLL_TIMEOUT_ATTRIBUTE_ID:
- {
- uint16_t newFastPollIntervalQs;
- MEMMOVE(&newFastPollIntervalQs, value, size);
- return validateFastPollInterval(endpoint, newFastPollIntervalQs);
+ case ZCL_FAST_POLL_TIMEOUT_ATTRIBUTE_ID: {
+ uint16_t newFastPollIntervalQs;
+ MEMMOVE(&newFastPollIntervalQs, value, size);
+ return validateFastPollInterval(endpoint, newFastPollIntervalQs);
}
- case ZCL_CHECK_IN_INTERVAL_MIN_ATTRIBUTE_ID:
- {
- uint32_t newCheckInIntervalMinQs;
- MEMMOVE(&newCheckInIntervalMinQs, value, size);
- return validateCheckInIntervalMin(endpoint, newCheckInIntervalMinQs);
+ case ZCL_CHECK_IN_INTERVAL_MIN_ATTRIBUTE_ID: {
+ uint32_t newCheckInIntervalMinQs;
+ MEMMOVE(&newCheckInIntervalMinQs, value, size);
+ return validateCheckInIntervalMin(endpoint, newCheckInIntervalMinQs);
}
- case ZCL_LONG_POLL_INTERVAL_MIN_ATTRIBUTE_ID:
- {
- uint32_t newLongPollIntervalMinQs;
- MEMMOVE(&newLongPollIntervalMinQs, value, size);
- return validateLongPollIntervalMin(endpoint, newLongPollIntervalMinQs);
+ case ZCL_LONG_POLL_INTERVAL_MIN_ATTRIBUTE_ID: {
+ uint32_t newLongPollIntervalMinQs;
+ MEMMOVE(&newLongPollIntervalMinQs, value, size);
+ return validateLongPollIntervalMin(endpoint, newLongPollIntervalMinQs);
}
- case ZCL_FAST_POLL_TIMEOUT_MAX_ATTRIBUTE_ID:
- {
- uint32_t newFastPollTimeoutMaxQs;
- MEMMOVE(&newFastPollTimeoutMaxQs, value, size);
- return validateFastPollTimeoutMax(endpoint, newFastPollTimeoutMaxQs);
+ case ZCL_FAST_POLL_TIMEOUT_MAX_ATTRIBUTE_ID: {
+ uint32_t newFastPollTimeoutMaxQs;
+ MEMMOVE(&newFastPollTimeoutMaxQs, value, size);
+ return validateFastPollTimeoutMax(endpoint, newFastPollTimeoutMaxQs);
}
default:
- return EMBER_ZCL_STATUS_SUCCESS;
- }
+ return EMBER_ZCL_STATUS_SUCCESS;
+ }
}
-void emberAfPollControlClusterServerAttributeChangedCallback(uint8_t endpoint,
- EmberAfAttributeId attributeId)
+void emberAfPollControlClusterServerAttributeChangedCallback(uint8_t endpoint, EmberAfAttributeId attributeId)
{
- switch (attributeId) {
+ switch (attributeId)
+ {
case ZCL_CHECK_IN_INTERVAL_ATTRIBUTE_ID:
- scheduleCheckIn(endpoint);
- break;
- case ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID:
- {
- EmberAfStatus status;
- uint32_t longPollIntervalQs;
- status = readServerAttribute(endpoint,
- ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID,
- "long poll interval",
- (uint8_t *)&longPollIntervalQs,
- sizeof(longPollIntervalQs));
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfSetLongPollIntervalQsCallback(longPollIntervalQs);
- }
- break;
+ scheduleCheckIn(endpoint);
+ break;
+ case ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID: {
+ EmberAfStatus status;
+ uint32_t longPollIntervalQs;
+ status = readServerAttribute(endpoint, ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID, "long poll interval",
+ (uint8_t *) &longPollIntervalQs, sizeof(longPollIntervalQs));
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfSetLongPollIntervalQsCallback(longPollIntervalQs);
+ }
+ break;
}
- case ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID:
- {
- EmberAfStatus status;
- uint16_t shortPollIntervalQs;
- status = readServerAttribute(endpoint,
- ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID,
- "short poll interval",
- (uint8_t *)&shortPollIntervalQs,
- sizeof(shortPollIntervalQs));
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfSetShortPollIntervalQsCallback(shortPollIntervalQs);
- }
- break;
+ case ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID: {
+ EmberAfStatus status;
+ uint16_t shortPollIntervalQs;
+ status = readServerAttribute(endpoint, ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID, "short poll interval",
+ (uint8_t *) &shortPollIntervalQs, sizeof(shortPollIntervalQs));
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfSetShortPollIntervalQsCallback(shortPollIntervalQs);
+ }
+ break;
}
case ZCL_FAST_POLL_TIMEOUT_ATTRIBUTE_ID:
case ZCL_CHECK_IN_INTERVAL_MIN_ATTRIBUTE_ID:
case ZCL_LONG_POLL_INTERVAL_MIN_ATTRIBUTE_ID:
case ZCL_FAST_POLL_TIMEOUT_MAX_ATTRIBUTE_ID:
default:
- break;
- }
+ break;
+ }
}
-bool emberAfPollControlClusterCheckInResponseCallback(uint8_t startFastPolling,
- uint16_t fastPollTimeoutQs)
+bool emberAfPollControlClusterCheckInResponseCallback(uint8_t startFastPolling, uint16_t fastPollTimeoutQs)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_ACTION_DENIED;
- uint8_t clientIndex = findClientIndex();
+ EmberAfStatus status = EMBER_ZCL_STATUS_ACTION_DENIED;
+ uint8_t clientIndex = findClientIndex();
- emberAfPollControlClusterPrintln("RX: CheckInResponse 0x%x, 0x%2x",
- startFastPolling,
- fastPollTimeoutQs);
+ emberAfPollControlClusterPrintln("RX: CheckInResponse 0x%x, 0x%2x", startFastPolling, fastPollTimeoutQs);
- // clientIndex will always be less than EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS
- if (clientIndex != NULL_INDEX
- && clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS) {
- if (state == WAITING) {
- uint8_t endpoint = emberAfCurrentEndpoint();
+ // clientIndex will always be less than EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS
+ if (clientIndex != NULL_INDEX && clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS)
+ {
+ if (state == WAITING)
+ {
+ uint8_t endpoint = emberAfCurrentEndpoint();
- if (isPollControlBindingTrustCenter(endpoint, clients[clientIndex].bindingIndex)) {
- trustCenterCheckInResponseReceived = true;
- if (trustCenterCheckInFailureCount > 0) {
- emberAfPollControlClusterPrintln("Poll Control: trust center "
- "responding to checkins after %d"
- "failure%s",
- trustCenterCheckInFailureCount,
- trustCenterCheckInFailureCount == 1
- ? "" : "s");
+ if (isPollControlBindingTrustCenter(endpoint, clients[clientIndex].bindingIndex))
+ {
+ trustCenterCheckInResponseReceived = true;
+ if (trustCenterCheckInFailureCount > 0)
+ {
+ emberAfPollControlClusterPrintln("Poll Control: trust center "
+ "responding to checkins after %d"
+ "failure%s",
+ trustCenterCheckInFailureCount,
+ trustCenterCheckInFailureCount == 1 ? "" : "s");
+ }
+ trustCenterCheckInFailureCount = 0;
+ }
+
+ if (startFastPolling)
+ {
+ if (fastPollTimeoutQs == 0)
+ {
+ status = readServerAttribute(endpoint, ZCL_FAST_POLL_TIMEOUT_ATTRIBUTE_ID, "fast poll timeout",
+ (uint8_t *) &fastPollTimeoutQs, sizeof(fastPollTimeoutQs));
+ }
+ else
+ {
+ status = validateFastPollInterval(endpoint, fastPollTimeoutQs);
+ }
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ clients[clientIndex].fastPollTimeoutQs = fastPollTimeoutQs;
+ }
+ else
+ {
+ clients[clientIndex].bindingIndex = NULL_INDEX;
+ }
+ }
+ else
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ clients[clientIndex].bindingIndex = NULL_INDEX;
+ }
+
+ // Calling the tick directly when in the waiting state will cause the
+ // temporarily fast poll mode to stop and will begin the actual fast poll
+ // mode if applicable.
+ if (!pendingCheckInResponses())
+ {
+ emberAfPollControlClusterServerTickCallback(endpoint);
+ }
}
- trustCenterCheckInFailureCount = 0;
- }
-
- if (startFastPolling) {
- if (fastPollTimeoutQs == 0) {
- status = readServerAttribute(endpoint,
- ZCL_FAST_POLL_TIMEOUT_ATTRIBUTE_ID,
- "fast poll timeout",
- (uint8_t *)&fastPollTimeoutQs,
- sizeof(fastPollTimeoutQs));
- } else {
- status = validateFastPollInterval(endpoint, fastPollTimeoutQs);
+ else
+ {
+ status = EMBER_ZCL_STATUS_TIMEOUT;
}
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- clients[clientIndex].fastPollTimeoutQs = fastPollTimeoutQs;
- } else {
- clients[clientIndex].bindingIndex = NULL_INDEX;
- }
- } else {
- status = EMBER_ZCL_STATUS_SUCCESS;
- clients[clientIndex].bindingIndex = NULL_INDEX;
- }
-
- // Calling the tick directly when in the waiting state will cause the
- // temporarily fast poll mode to stop and will begin the actual fast poll
- // mode if applicable.
- if (!pendingCheckInResponses()) {
- emberAfPollControlClusterServerTickCallback(endpoint);
- }
- } else {
- status = EMBER_ZCL_STATUS_TIMEOUT;
}
- }
- emberAfSendImmediateDefaultResponse(status);
- return true;
+ emberAfSendImmediateDefaultResponse(status);
+ return true;
}
bool emberAfPollControlClusterFastPollStopCallback(void)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_ACTION_DENIED;
- uint8_t clientIndex = findClientIndex();
+ EmberAfStatus status = EMBER_ZCL_STATUS_ACTION_DENIED;
+ uint8_t clientIndex = findClientIndex();
- emberAfPollControlClusterPrintln("RX: FastPollStop");
+ emberAfPollControlClusterPrintln("RX: FastPollStop");
- // clientIndex will always be less than EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS
- if (clientIndex != NULL_INDEX
- && clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS) {
- if (state == POLLING) {
- uint8_t endpoint = emberAfCurrentEndpoint();
- status = EMBER_ZCL_STATUS_SUCCESS;
- clients[clientIndex].bindingIndex = NULL_INDEX;
+ // clientIndex will always be less than EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS
+ if (clientIndex != NULL_INDEX && clientIndex < EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_MAX_CLIENTS)
+ {
+ if (state == POLLING)
+ {
+ uint8_t endpoint = emberAfCurrentEndpoint();
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ clients[clientIndex].bindingIndex = NULL_INDEX;
- // Calling the tick directly in the polling state will cause the fast
- // poll mode to stop.
- if (!outstandingFastPollRequests(endpoint)) {
- emberAfPollControlClusterServerTickCallback(endpoint);
- }
- } else {
- status = EMBER_ZCL_STATUS_TIMEOUT;
+ // Calling the tick directly in the polling state will cause the fast
+ // poll mode to stop.
+ if (!outstandingFastPollRequests(endpoint))
+ {
+ emberAfPollControlClusterServerTickCallback(endpoint);
+ }
+ }
+ else
+ {
+ status = EMBER_ZCL_STATUS_TIMEOUT;
+ }
}
- }
- emberAfSendImmediateDefaultResponse(status);
- return true;
+ emberAfSendImmediateDefaultResponse(status);
+ return true;
}
bool emberAfPollControlClusterSetLongPollIntervalCallback(uint32_t newLongPollIntervalQs)
{
#ifdef EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_ACCEPT_SET_LONG_POLL_INTERVAL_COMMAND
- EmberAfStatus status;
- uint8_t endpoint = emberAfCurrentEndpoint();
+ EmberAfStatus status;
+ uint8_t endpoint = emberAfCurrentEndpoint();
- emberAfPollControlClusterPrintln("RX: SetLongPollInterval 0x%4x",
- newLongPollIntervalQs);
+ emberAfPollControlClusterPrintln("RX: SetLongPollInterval 0x%4x", newLongPollIntervalQs);
- // Trying to write the attribute will trigger the PreAttributeChanged
- // callback, which will handle validation. If the write is successful, the
- // AttributeChanged callback will fire, which will handle setting the new
- // long poll interval.
- status = writeServerAttribute(endpoint,
- ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID,
- "long poll interval",
- (uint8_t *)&newLongPollIntervalQs,
- ZCL_INT32U_ATTRIBUTE_TYPE);
+ // Trying to write the attribute will trigger the PreAttributeChanged
+ // callback, which will handle validation. If the write is successful, the
+ // AttributeChanged callback will fire, which will handle setting the new
+ // long poll interval.
+ status = writeServerAttribute(endpoint, ZCL_LONG_POLL_INTERVAL_ATTRIBUTE_ID, "long poll interval",
+ (uint8_t *) &newLongPollIntervalQs, ZCL_INT32U_ATTRIBUTE_TYPE);
- emberAfSendImmediateDefaultResponse(status);
- return true;
+ emberAfSendImmediateDefaultResponse(status);
+ return true;
#else
- return false;
+ return false;
#endif
}
bool emberAfPollControlClusterSetShortPollIntervalCallback(uint16_t newShortPollIntervalQs)
{
#ifdef EMBER_AF_PLUGIN_POLL_CONTROL_SERVER_ACCEPT_SET_SHORT_POLL_INTERVAL_COMMAND
- EmberAfStatus status;
- uint8_t endpoint = emberAfCurrentEndpoint();
+ EmberAfStatus status;
+ uint8_t endpoint = emberAfCurrentEndpoint();
- emberAfPollControlClusterPrintln("RX: SetShortPollInterval 0x%2x",
- newShortPollIntervalQs);
+ emberAfPollControlClusterPrintln("RX: SetShortPollInterval 0x%2x", newShortPollIntervalQs);
- // Trying to write the attribute will trigger the PreAttributeChanged
- // callback, which will handle validation. If the write is successful, the
- // AttributeChanged callback will fire, which will handle setting the new
- // short poll interval.
- status = writeServerAttribute(endpoint,
- ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID,
- "short poll interval",
- (uint8_t *)&newShortPollIntervalQs,
- ZCL_INT16U_ATTRIBUTE_TYPE);
+ // Trying to write the attribute will trigger the PreAttributeChanged
+ // callback, which will handle validation. If the write is successful, the
+ // AttributeChanged callback will fire, which will handle setting the new
+ // short poll interval.
+ status = writeServerAttribute(endpoint, ZCL_SHORT_POLL_INTERVAL_ATTRIBUTE_ID, "short poll interval",
+ (uint8_t *) &newShortPollIntervalQs, ZCL_INT16U_ATTRIBUTE_TYPE);
- emberAfSendImmediateDefaultResponse(status);
- return true;
+ emberAfSendImmediateDefaultResponse(status);
+ return true;
#else
- return false;
+ return false;
#endif
}
void emAfPluginPollControlServerResetAttributesCallback(uint8_t endpointId)
{
- // EMAPPFWKV2-1437: when we reset our attributes, we need to re-sync with
- // the consumers of our attribute values. For example, the consumers of
- // emberAfSetLongPollIntervalQsCallback and
- // emberAfSetShortPollIntervalQsCallback will want to know that the poll
- // intervals might have changed. Therefore, we simply call the init function
- // to read the attribute values and notify interested parties.
- emberAfPollControlClusterServerInitCallback(endpointId);
+ // EMAPPFWKV2-1437: when we reset our attributes, we need to re-sync with
+ // the consumers of our attribute values. For example, the consumers of
+ // emberAfSetLongPollIntervalQsCallback and
+ // emberAfSetShortPollIntervalQsCallback will want to know that the poll
+ // intervals might have changed. Therefore, we simply call the init function
+ // to read the attribute values and notify interested parties.
+ emberAfPollControlClusterServerInitCallback(endpointId);
}
void emberAfPluginPollControlServerStackStatusCallback(EmberStatus status)
{
- // Reset failure count if just joining network
- if (status == EMBER_NETWORK_UP) {
- trustCenterCheckInFailureCount = 0;
- }
+ // Reset failure count if just joining network
+ if (status == EMBER_NETWORK_UP)
+ {
+ trustCenterCheckInFailureCount = 0;
+ }
}
void emberAfPluginPollControlServerSetIgnoreNonTrustCenter(bool ignoreNonTc)
{
- ignoreNonTrustCenter = ignoreNonTc;
+ ignoreNonTrustCenter = ignoreNonTc;
}
bool emberAfPluginPollControlServerGetIgnoreNonTrustCenter(void)
{
- return ignoreNonTrustCenter;
+ return ignoreNonTrustCenter;
}
diff --git a/src/app/clusters/poll-control-server/poll-control-server.h b/src/app/clusters/poll-control-server/poll-control-server.h
index 6443b2b..cf74033 100644
--- a/src/app/clusters/poll-control-server/poll-control-server.h
+++ b/src/app/clusters/poll-control-server/poll-control-server.h
@@ -31,11 +31,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief APIs and defines for the Poll Control Server plugin.
+ * @brief APIs and defines for the Poll Control Server
+ *plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// Callback triggered after multiple failed trust center poll control checkins
void emberAfPluginPollControlServerCheckInTimeoutCallback(void);
diff --git a/src/app/clusters/reporting/reporting-cli.c b/src/app/clusters/reporting/reporting-cli.c
index 8fb2005..bd89c60 100644
--- a/src/app/clusters/reporting/reporting-cli.c
+++ b/src/app/clusters/reporting/reporting-cli.c
@@ -31,15 +31,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the Reporting plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
-#include "app/util/serial/command-interpreter2.h"
#include "app/framework/util/attribute-storage.h"
+#include "app/util/serial/command-interpreter2.h"
#include "reporting.h"
void emAfPluginReportingCliPrint(void);
@@ -50,92 +50,91 @@
#if !defined(EMBER_AF_GENERATE_CLI)
EmberCommandEntry emberAfPluginReportingCommands[] = {
- emberCommandEntryAction("print", emAfPluginReportingCliPrint, "", "Print the reporting table"),
- emberCommandEntryAction("clear", emAfPluginReportingCliClear, "", "Clear the reporting tabel"),
- emberCommandEntryAction("remove", emAfPluginReportingCliRemove, "u", "Remove an entry from the reporting table"),
- emberCommandEntryAction("add", emAfPluginReportingCliAdd, "uvvuvvw", "Add an entry to the reporting table"),
- emberCommandEntryAction("clear-last-report-time", emAfPluginReportingCliClearLastReportTime, "", "Clear last report time of attributes."),
- emberCommandEntryTerminator(),
+ emberCommandEntryAction("print", emAfPluginReportingCliPrint, "", "Print the reporting table"),
+ emberCommandEntryAction("clear", emAfPluginReportingCliClear, "", "Clear the reporting tabel"),
+ emberCommandEntryAction("remove", emAfPluginReportingCliRemove, "u", "Remove an entry from the reporting table"),
+ emberCommandEntryAction("add", emAfPluginReportingCliAdd, "uvvuvvw", "Add an entry to the reporting table"),
+ emberCommandEntryAction("clear-last-report-time", emAfPluginReportingCliClearLastReportTime, "",
+ "Clear last report time of attributes."),
+ emberCommandEntryTerminator(),
};
#endif // EMBER_AF_GENERATE_CLI
// plugin reporting print
void emAfPluginReportingCliPrint(void)
{
- uint8_t i;
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- EmberAfPluginReportingEntry entry;
- emAfPluginReportingGetEntry(i, &entry);
- emberAfReportingPrint("%x:", i);
- if (entry.endpoint != EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID) {
- emberAfReportingPrint("ep %x clus %2x attr %2x svr %c",
- entry.endpoint,
- entry.clusterId,
- entry.attributeId,
- (entry.mask == CLUSTER_MASK_SERVER ? 'y' : 'n'));
- if (entry.manufacturerCode != EMBER_AF_NULL_MANUFACTURER_CODE) {
- emberAfReportingPrint(" mfg %x", entry.manufacturerCode);
- }
- if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED) {
- emberAfReportingPrint(" report min %2x max %2x rpt-chg %4x",
- entry.data.reported.minInterval,
- entry.data.reported.maxInterval,
- entry.data.reported.reportableChange);
+ uint8_t i;
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ EmberAfPluginReportingEntry entry;
+ emAfPluginReportingGetEntry(i, &entry);
+ emberAfReportingPrint("%x:", i);
+ if (entry.endpoint != EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID)
+ {
+ emberAfReportingPrint("ep %x clus %2x attr %2x svr %c", entry.endpoint, entry.clusterId, entry.attributeId,
+ (entry.mask == CLUSTER_MASK_SERVER ? 'y' : 'n'));
+ if (entry.manufacturerCode != EMBER_AF_NULL_MANUFACTURER_CODE)
+ {
+ emberAfReportingPrint(" mfg %x", entry.manufacturerCode);
+ }
+ if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED)
+ {
+ emberAfReportingPrint(" report min %2x max %2x rpt-chg %4x", entry.data.reported.minInterval,
+ entry.data.reported.maxInterval, entry.data.reported.reportableChange);
+ emberAfReportingFlush();
+ }
+ else
+ {
+ emberAfReportingPrint(" receive from %2x ep %x timeout %2x", entry.data.received.source,
+ entry.data.received.endpoint, entry.data.received.timeout);
+ }
+ }
+ emberAfReportingPrintln("");
emberAfReportingFlush();
- } else {
- emberAfReportingPrint(" receive from %2x ep %x timeout %2x",
- entry.data.received.source,
- entry.data.received.endpoint,
- entry.data.received.timeout);
- }
}
- emberAfReportingPrintln("");
- emberAfReportingFlush();
- }
}
// plugin reporting clear
void emAfPluginReportingCliClear(void)
{
- EmberStatus status = emberAfClearReportTableCallback();
- emberAfReportingPrintln("%p 0x%x", "clear", status);
+ EmberStatus status = emberAfClearReportTableCallback();
+ emberAfReportingPrintln("%p 0x%x", "clear", status);
}
// plugin reporting remove <index:1>
void emAfPluginReportingCliRemove(void)
{
- EmberStatus status = emAfPluginReportingRemoveEntry((uint8_t)emberUnsignedCommandArgument(0));
- emberAfReportingPrintln("%p 0x%x", "remove", status);
+ EmberStatus status = emAfPluginReportingRemoveEntry((uint8_t) emberUnsignedCommandArgument(0));
+ emberAfReportingPrintln("%p 0x%x", "remove", status);
}
// plugin reporting add <endpoint:1> <cluster id:2> <attribute id:2> ...
// ... <mask:1> <min interval:2> <max interval:2> <reportable change:4>
void emAfPluginReportingCliAdd(void)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
- EmberAfPluginReportingEntry entry;
- entry.endpoint = (uint8_t)emberUnsignedCommandArgument(0);
- entry.clusterId = (EmberAfClusterId)emberUnsignedCommandArgument(1);
- entry.attributeId = (EmberAfAttributeId)emberUnsignedCommandArgument(2);
- entry.mask = (uint8_t)(emberUnsignedCommandArgument(3) == 0
- ? CLUSTER_MASK_CLIENT
- : CLUSTER_MASK_SERVER);
- entry.manufacturerCode = EMBER_AF_NULL_MANUFACTURER_CODE;
- entry.data.reported.minInterval = (uint16_t)emberUnsignedCommandArgument(4);
- entry.data.reported.maxInterval = (uint16_t)emberUnsignedCommandArgument(5);
- entry.data.reported.reportableChange = emberUnsignedCommandArgument(6);
- UNUSED_VAR(status);
- status = emberAfPluginReportingConfigureReportedAttribute(&entry);
+ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
+ EmberAfPluginReportingEntry entry;
+ entry.endpoint = (uint8_t) emberUnsignedCommandArgument(0);
+ entry.clusterId = (EmberAfClusterId) emberUnsignedCommandArgument(1);
+ entry.attributeId = (EmberAfAttributeId) emberUnsignedCommandArgument(2);
+ entry.mask = (uint8_t)(emberUnsignedCommandArgument(3) == 0 ? CLUSTER_MASK_CLIENT : CLUSTER_MASK_SERVER);
+ entry.manufacturerCode = EMBER_AF_NULL_MANUFACTURER_CODE;
+ entry.data.reported.minInterval = (uint16_t) emberUnsignedCommandArgument(4);
+ entry.data.reported.maxInterval = (uint16_t) emberUnsignedCommandArgument(5);
+ entry.data.reported.reportableChange = emberUnsignedCommandArgument(6);
+ UNUSED_VAR(status);
+ status = emberAfPluginReportingConfigureReportedAttribute(&entry);
- emberAfReportingPrintln("%p 0x%x", "add", status);
+ emberAfReportingPrintln("%p 0x%x", "add", status);
}
// plugin reporting add clear-last-report-time
void emAfPluginReportingCliClearLastReportTime(void)
{
- uint8_t i;
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- emAfPluginReportVolatileData[i].lastReportTimeMs = halCommonGetInt32uMillisecondTick();
- }
- emberAfReportingPrintln("clearing last report time of all attributes");
+ uint8_t i;
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ emAfPluginReportVolatileData[i].lastReportTimeMs = halCommonGetInt32uMillisecondTick();
+ }
+ emberAfReportingPrintln("clearing last report time of all attributes");
}
diff --git a/src/app/clusters/reporting/reporting-default-configuration.c b/src/app/clusters/reporting/reporting-default-configuration.c
index bbc83b3..b71e6b8 100644
--- a/src/app/clusters/reporting/reporting-default-configuration.c
+++ b/src/app/clusters/reporting/reporting-default-configuration.c
@@ -31,68 +31,74 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Default configuration for the Reporting plugin.
+ * @brief Default configuration for the Reporting
+ *plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
-#include "app/framework/util/common.h"
#include "app/framework/util/attribute-storage.h"
+#include "app/framework/util/common.h"
#include "reporting.h"
#define REPORT_FAILED 0xFF
-#if (defined EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE \
- && 0 != EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE)
+#if (defined EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE && \
+ 0 != EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE)
const EmberAfPluginReportingEntry generatedReportingConfigDefaults[] = EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS;
#endif
// Load Default reporting configuration from generated table
void emberAfPluginReportingLoadReportingConfigDefaults(void)
{
-#if (defined EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE \
- && 0 != EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE)
- for (int i = 0; i < EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE; i++) {
- emAfPluginReportingConditionallyAddReportingEntry((EmberAfPluginReportingEntry *)&generatedReportingConfigDefaults[i]);
- }
+#if (defined EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE && \
+ 0 != EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE)
+ for (int i = 0; i < EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE; i++)
+ {
+ emAfPluginReportingConditionallyAddReportingEntry((EmberAfPluginReportingEntry *) &generatedReportingConfigDefaults[i]);
+ }
#endif
}
// Get default reporting values - returns true if there is default value
// avilable either in the table or a call back to application
-bool emberAfPluginReportingGetReportingConfigDefaults(EmberAfPluginReportingEntry *defaultConfiguration)
+bool emberAfPluginReportingGetReportingConfigDefaults(EmberAfPluginReportingEntry * defaultConfiguration)
{
- // NULL error check - return false.
- if (NULL == defaultConfiguration) {
- return false;
- }
- // When there is a table table available - search and read the values,
- // if default config value found, retrun true to the caller to use it
-#if ((defined EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE) \
- && (0 != EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE))
- for (int i = 0; i < EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE; i++) {
- // All of the serach parameters match then copy the default config.
- if ((defaultConfiguration->endpoint == generatedReportingConfigDefaults[i].endpoint)
- && (defaultConfiguration->clusterId == generatedReportingConfigDefaults[i].clusterId)
- && (defaultConfiguration->attributeId == generatedReportingConfigDefaults[i].attributeId)
- && (defaultConfiguration->mask == generatedReportingConfigDefaults[i].mask)
- && (defaultConfiguration->manufacturerCode == generatedReportingConfigDefaults[i].manufacturerCode)) {
- defaultConfiguration->direction = EMBER_ZCL_REPORTING_DIRECTION_REPORTED;
- defaultConfiguration->data = generatedReportingConfigDefaults[i].data;
- return true;
+ // NULL error check - return false.
+ if (NULL == defaultConfiguration)
+ {
+ return false;
}
- }
+ // When there is a table table available - search and read the values,
+ // if default config value found, retrun true to the caller to use it
+#if ((defined EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE) && \
+ (0 != EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE))
+ for (int i = 0; i < EMBER_AF_GENERATED_REPORTING_CONFIG_DEFAULTS_TABLE_SIZE; i++)
+ {
+ // All of the serach parameters match then copy the default config.
+ if ((defaultConfiguration->endpoint == generatedReportingConfigDefaults[i].endpoint) &&
+ (defaultConfiguration->clusterId == generatedReportingConfigDefaults[i].clusterId) &&
+ (defaultConfiguration->attributeId == generatedReportingConfigDefaults[i].attributeId) &&
+ (defaultConfiguration->mask == generatedReportingConfigDefaults[i].mask) &&
+ (defaultConfiguration->manufacturerCode == generatedReportingConfigDefaults[i].manufacturerCode))
+ {
+ defaultConfiguration->direction = EMBER_ZCL_REPORTING_DIRECTION_REPORTED;
+ defaultConfiguration->data = generatedReportingConfigDefaults[i].data;
+ return true;
+ }
+ }
#endif
- // At this point - There is no entry in the generated deafult table,
- // so the application need to be called to get default reporting values
- // The application should provide the default values because , in BDB an
- // implemented reportable attribute will reset its reporting configuration
- // when receives a special case of minInterval and maxInterval for which
- // function gets called.
- if (emberAfPluginReportingGetDefaultReportingConfigCallback(defaultConfiguration)) {
- return true;
- }
- return false;
+ // At this point - There is no entry in the generated deafult table,
+ // so the application need to be called to get default reporting values
+ // The application should provide the default values because , in BDB an
+ // implemented reportable attribute will reset its reporting configuration
+ // when receives a special case of minInterval and maxInterval for which
+ // function gets called.
+ if (emberAfPluginReportingGetDefaultReportingConfigCallback(defaultConfiguration))
+ {
+ return true;
+ }
+ return false;
}
diff --git a/src/app/clusters/reporting/reporting-tokens.h b/src/app/clusters/reporting/reporting-tokens.h
index e259770..3af6d87 100644
--- a/src/app/clusters/reporting/reporting-tokens.h
+++ b/src/app/clusters/reporting/reporting-tokens.h
@@ -31,19 +31,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Tokens for the Reporting plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-#define CREATOR_REPORT_TABLE (0x8725)
+#define CREATOR_REPORT_TABLE (0x8725)
// This key is used for an indexed token and the subsequent 0x7F keys are also reserved
#define NVM3KEY_REPORT_TABLE (NVM3KEY_DOMAIN_ZIGBEE | 0x4000)
#ifdef DEFINETYPES
// Include or define any typedef for tokens here
-#endif //DEFINETYPES
+#endif // DEFINETYPES
#ifdef DEFINETOKENS
// Define the actual token storage information here
@@ -57,10 +57,7 @@
#define REPORT_TABLE_SIZE (EMBER_AF_PLUGIN_REPORTING_TABLE_SIZE)
#endif
-DEFINE_INDEXED_TOKEN(REPORT_TABLE,
- EmberAfPluginReportingEntry,
- REPORT_TABLE_SIZE,
- { EMBER_ZCL_REPORTING_DIRECTION_REPORTED,
- EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID })
+DEFINE_INDEXED_TOKEN(REPORT_TABLE, EmberAfPluginReportingEntry, REPORT_TABLE_SIZE,
+ { EMBER_ZCL_REPORTING_DIRECTION_REPORTED, EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID })
-#endif //DEFINETOKENS
+#endif // DEFINETOKENS
diff --git a/src/app/clusters/reporting/reporting.c b/src/app/clusters/reporting/reporting.c
index 3503f2c..aaf0847 100644
--- a/src/app/clusters/reporting/reporting.c
+++ b/src/app/clusters/reporting/reporting.c
@@ -31,17 +31,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Reporting plugin, which sends asynchronous reports
- * when a ZCL attribute's value has changed.
+ * @brief Routines for the Reporting plugin, which
+ *sends asynchronous reports when a ZCL attribute's
+ *value has changed.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-#include "app/framework/include/af.h"
-#include "app/framework/util/common.h"
-#include "app/framework/util/attribute-storage.h"
#include "reporting.h"
+#include "app/framework/include/af.h"
+#include "app/framework/util/attribute-storage.h"
+#include "app/framework/util/common.h"
#ifdef ATTRIBUTE_LARGEST
#define READ_DATA_SIZE ATTRIBUTE_LARGEST
@@ -55,35 +56,25 @@
static void scheduleTick(void);
static void removeConfiguration(uint8_t index);
static void removeConfigurationAndScheduleTick(uint8_t index);
-static EmberAfStatus configureReceivedAttribute(const EmberAfClusterCommand *cmd,
- EmberAfAttributeId attributeId,
- uint8_t mask,
+static EmberAfStatus configureReceivedAttribute(const EmberAfClusterCommand * cmd, EmberAfAttributeId attributeId, uint8_t mask,
uint16_t timeout);
-static void putReportableChangeInResp(const EmberAfPluginReportingEntry *entry,
- EmberAfAttributeType dataType);
-static void retrySendReport(EmberOutgoingMessageType type,
- uint16_t indexOrDestination,
- EmberApsFrame *apsFrame,
- uint16_t msgLen,
- uint8_t *message,
- EmberStatus status);
-static uint32_t computeStringHash(uint8_t *data, uint8_t length);
+static void putReportableChangeInResp(const EmberAfPluginReportingEntry * entry, EmberAfAttributeType dataType);
+static void retrySendReport(EmberOutgoingMessageType type, uint16_t indexOrDestination, EmberApsFrame * apsFrame, uint16_t msgLen,
+ uint8_t * message, EmberStatus status);
+static uint32_t computeStringHash(uint8_t * data, uint8_t length);
EmberEventControl emberAfPluginReportingTickEventControl;
EmAfPluginReportVolatileData emAfPluginReportVolatileData[REPORT_TABLE_SIZE];
-static void retrySendReport(EmberOutgoingMessageType type,
- uint16_t indexOrDestination,
- EmberApsFrame *apsFrame,
- uint16_t msgLen,
- uint8_t *message,
- EmberStatus status)
+static void retrySendReport(EmberOutgoingMessageType type, uint16_t indexOrDestination, EmberApsFrame * apsFrame, uint16_t msgLen,
+ uint8_t * message, EmberStatus status)
{
- // Retry once, and do so by unicasting without a pointer to this callback
- if (status != EMBER_SUCCESS) {
- emberAfSendUnicast(type, indexOrDestination, apsFrame, msgLen, message);
- }
+ // Retry once, and do so by unicasting without a pointer to this callback
+ if (status != EMBER_SUCCESS)
+ {
+ emberAfSendUnicast(type, indexOrDestination, apsFrame, msgLen, message);
+ }
}
// Implementation based on public domain Fowler/Noll/Vo FNV-1a hash function:
@@ -95,951 +86,939 @@
// reportable changes. The strings themselves are longer than the storage size.
#define FNV1_OFFSET_BASIS (2166136261)
#define FNV1_PRIME (16777619)
-static uint32_t computeStringHash(uint8_t *data, uint8_t length)
+static uint32_t computeStringHash(uint8_t * data, uint8_t length)
{
- // FNV-1a, 32-bit hash
- uint32_t hash = FNV1_OFFSET_BASIS;
- for (int i = 0; i < length; ++i) {
- hash ^= data[i];
- hash *= FNV1_PRIME; // Or, hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
- }
- return hash;
+ // FNV-1a, 32-bit hash
+ uint32_t hash = FNV1_OFFSET_BASIS;
+ for (int i = 0; i < length; ++i)
+ {
+ hash ^= data[i];
+ hash *= FNV1_PRIME; // Or, hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
+ }
+ return hash;
}
#ifdef EZSP_HOST
static EmberAfPluginReportingEntry table[REPORT_TABLE_SIZE];
-void emAfPluginReportingGetEntry(uint8_t index, EmberAfPluginReportingEntry *result)
+void emAfPluginReportingGetEntry(uint8_t index, EmberAfPluginReportingEntry * result)
{
- MEMMOVE(result, &table[index], sizeof(EmberAfPluginReportingEntry));
+ MEMMOVE(result, &table[index], sizeof(EmberAfPluginReportingEntry));
}
-void emAfPluginReportingSetEntry(uint8_t index, EmberAfPluginReportingEntry *value)
+void emAfPluginReportingSetEntry(uint8_t index, EmberAfPluginReportingEntry * value)
{
- MEMMOVE(&table[index], value, sizeof(EmberAfPluginReportingEntry));
+ MEMMOVE(&table[index], value, sizeof(EmberAfPluginReportingEntry));
}
#else
-void emAfPluginReportingGetEntry(uint8_t index, EmberAfPluginReportingEntry *result)
+void emAfPluginReportingGetEntry(uint8_t index, EmberAfPluginReportingEntry * result)
{
- halCommonGetIndexedToken(result, TOKEN_REPORT_TABLE, index);
+ halCommonGetIndexedToken(result, TOKEN_REPORT_TABLE, index);
}
-void emAfPluginReportingSetEntry(uint8_t index, EmberAfPluginReportingEntry *value)
+void emAfPluginReportingSetEntry(uint8_t index, EmberAfPluginReportingEntry * value)
{
- halCommonSetIndexedToken(TOKEN_REPORT_TABLE, index, value);
+ halCommonSetIndexedToken(TOKEN_REPORT_TABLE, index, value);
}
#endif
void emberAfPluginReportingStackStatusCallback(EmberStatus status)
{
- if (status == EMBER_NETWORK_UP) {
- // Load default reporting configurations
- emberAfPluginReportingLoadReportingConfigDefaults();
+ if (status == EMBER_NETWORK_UP)
+ {
+ // Load default reporting configurations
+ emberAfPluginReportingLoadReportingConfigDefaults();
- scheduleTick();
- }
+ scheduleTick();
+ }
}
void emberAfPluginReportingInitCallback(void)
{
- // On device initialization, any attributes that have been set up to report
- // should generate an attribute report.
- for (int i = 0; i < REPORT_TABLE_SIZE; i++) {
- EmberAfPluginReportingEntry entry;
- emAfPluginReportingGetEntry(i, &entry);
- if (entry.endpoint != EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID
- && entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED) {
- emAfPluginReportVolatileData[i].reportableChange = true;
+ // On device initialization, any attributes that have been set up to report
+ // should generate an attribute report.
+ for (int i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ EmberAfPluginReportingEntry entry;
+ emAfPluginReportingGetEntry(i, &entry);
+ if (entry.endpoint != EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID &&
+ entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED)
+ {
+ emAfPluginReportVolatileData[i].reportableChange = true;
+ }
}
- }
- scheduleTick();
+ scheduleTick();
}
void emberAfPluginReportingTickEventHandler(void)
{
- EmberApsFrame *apsFrame = NULL;
- EmberAfStatus status;
- EmberAfAttributeType dataType;
- uint16_t manufacturerCode = 0;
- uint8_t readData[READ_DATA_SIZE];
- uint8_t i;
- uint16_t dataSize;
- bool clientToServer = false;
- EmberBindingTableEntry bindingEntry;
- uint8_t index, reportSize = 0, currentPayloadMaxLength = 0, smallestPayloadMaxLength = 0;
+ EmberApsFrame * apsFrame = NULL;
+ EmberAfStatus status;
+ EmberAfAttributeType dataType;
+ uint16_t manufacturerCode = 0;
+ uint8_t readData[READ_DATA_SIZE];
+ uint8_t i;
+ uint16_t dataSize;
+ bool clientToServer = false;
+ EmberBindingTableEntry bindingEntry;
+ uint8_t index, reportSize = 0, currentPayloadMaxLength = 0, smallestPayloadMaxLength = 0;
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- EmberAfPluginReportingEntry entry;
- uint32_t elapsedMs;
- emAfPluginReportingGetEntry(i, &entry);
- // We will only send reports for active reported attributes and only if a
- // reportable change has occurred and the minimum interval has elapsed or
- // if the maximum interval is set and has elapsed.
- elapsedMs = elapsedTimeInt32u(emAfPluginReportVolatileData[i].lastReportTimeMs,
- halCommonGetInt32uMillisecondTick());
- if (entry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID
- || entry.direction != EMBER_ZCL_REPORTING_DIRECTION_REPORTED
- || (elapsedMs
- < entry.data.reported.minInterval * MILLISECOND_TICKS_PER_SECOND)
- || (!emAfPluginReportVolatileData[i].reportableChange
- && (entry.data.reported.maxInterval == 0
- || (elapsedMs
- < (entry.data.reported.maxInterval
- * MILLISECOND_TICKS_PER_SECOND))))) {
- continue;
- }
-
- status = emAfReadAttribute(entry.endpoint,
- entry.clusterId,
- entry.attributeId,
- entry.mask,
- entry.manufacturerCode,
- (uint8_t *)&readData,
- READ_DATA_SIZE,
- &dataType);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfReportingPrintln("ERR: reading cluster 0x%2x attribute 0x%2x: 0x%x",
- entry.clusterId,
- entry.attributeId,
- status);
- continue;
- }
- if (emberAfIsLongStringAttributeType(dataType)) {
- // LONG string types are rarely used and even more rarely (never?)
- // reported; ignore and leave ensuing handling of other types unchanged.
- emberAfReportingPrintln("ERR: reporting of LONG string attribute type not supported: cluster 0x%2x attribute 0x%2x",
- entry.clusterId,
- entry.attributeId);
- continue;
- }
-
- // find size of current report
- dataSize = emberAfAttributeValueSize(dataType, readData);
- reportSize = sizeof(entry.attributeId) + sizeof(dataType) + dataSize;
-
- // If we have already started a report for a different attribute or
- // destination, or if the current entry is too big for current report, send it and create a new one.
- if (apsFrame != NULL
- && (!(entry.endpoint == apsFrame->sourceEndpoint
- && entry.clusterId == apsFrame->clusterId
- && emberAfClusterIsClient(&entry) == clientToServer
- && entry.manufacturerCode == manufacturerCode)
- || (appResponseLength + reportSize > smallestPayloadMaxLength))) {
- if (appResponseLength + reportSize > smallestPayloadMaxLength) {
- emberAfReportingPrintln("Reporting Entry Full - creating new report");
- }
- conditionallySendReport(apsFrame->sourceEndpoint, apsFrame->clusterId);
- apsFrame = NULL;
- }
-
- // If we haven't made the message header, make it.
- if (apsFrame == NULL) {
- apsFrame = emberAfGetCommandApsFrame();
- clientToServer = emberAfClusterIsClient(&entry);
- // The manufacturer-specfic version of the fill API only creates a
- // manufacturer-specfic command if the manufacturer code is set. For
- // non-manufacturer-specfic reports, the manufacturer code is unset, so
- // we can get away with using this API for both cases.
- emberAfFillExternalManufacturerSpecificBuffer((clientToServer
- ? (ZCL_GLOBAL_COMMAND
- | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS)
- : (ZCL_GLOBAL_COMMAND
- | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS)),
- entry.clusterId,
- entry.manufacturerCode,
- ZCL_REPORT_ATTRIBUTES_COMMAND_ID,
- "");
- apsFrame->sourceEndpoint = entry.endpoint;
- apsFrame->options = EMBER_AF_DEFAULT_APS_OPTIONS;
- manufacturerCode = entry.manufacturerCode;
-
- // EMAPPFWKV2-1327: Reporting plugin does not account for reporting too many attributes
- // in the same ZCL:ReportAttributes message
-
- // find smallest maximum payload that the destination can receive for this cluster and source endpoint
- smallestPayloadMaxLength = MAX_INT8U_VALUE;
- for (index = 0; index < EMBER_BINDING_TABLE_SIZE; index++) {
- status = (EmberAfStatus)emberGetBinding(index, &bindingEntry);
- if (status == (EmberAfStatus)EMBER_SUCCESS && bindingEntry.local == entry.endpoint && bindingEntry.clusterId == entry.clusterId) {
- currentPayloadMaxLength = emberAfMaximumApsPayloadLength(bindingEntry.type, bindingEntry.networkIndex, apsFrame);
- if (currentPayloadMaxLength < smallestPayloadMaxLength) {
- smallestPayloadMaxLength = currentPayloadMaxLength;
- }
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ EmberAfPluginReportingEntry entry;
+ uint32_t elapsedMs;
+ emAfPluginReportingGetEntry(i, &entry);
+ // We will only send reports for active reported attributes and only if a
+ // reportable change has occurred and the minimum interval has elapsed or
+ // if the maximum interval is set and has elapsed.
+ elapsedMs = elapsedTimeInt32u(emAfPluginReportVolatileData[i].lastReportTimeMs, halCommonGetInt32uMillisecondTick());
+ if (entry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID ||
+ entry.direction != EMBER_ZCL_REPORTING_DIRECTION_REPORTED ||
+ (elapsedMs < entry.data.reported.minInterval * MILLISECOND_TICKS_PER_SECOND) ||
+ (!emAfPluginReportVolatileData[i].reportableChange &&
+ (entry.data.reported.maxInterval == 0 ||
+ (elapsedMs < (entry.data.reported.maxInterval * MILLISECOND_TICKS_PER_SECOND)))))
+ {
+ continue;
}
- }
- }
- // Payload is [attribute id:2] [type:1] [data:N].
- emberAfPutInt16uInResp(entry.attributeId);
- emberAfPutInt8uInResp(dataType);
+ status = emAfReadAttribute(entry.endpoint, entry.clusterId, entry.attributeId, entry.mask, entry.manufacturerCode,
+ (uint8_t *) &readData, READ_DATA_SIZE, &dataType);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfReportingPrintln("ERR: reading cluster 0x%2x attribute 0x%2x: 0x%x", entry.clusterId, entry.attributeId, status);
+ continue;
+ }
+ if (emberAfIsLongStringAttributeType(dataType))
+ {
+ // LONG string types are rarely used and even more rarely (never?)
+ // reported; ignore and leave ensuing handling of other types unchanged.
+ emberAfReportingPrintln("ERR: reporting of LONG string attribute type not supported: cluster 0x%2x attribute 0x%2x",
+ entry.clusterId, entry.attributeId);
+ continue;
+ }
+
+ // find size of current report
+ dataSize = emberAfAttributeValueSize(dataType, readData);
+ reportSize = sizeof(entry.attributeId) + sizeof(dataType) + dataSize;
+
+ // If we have already started a report for a different attribute or
+ // destination, or if the current entry is too big for current report, send it and create a new one.
+ if (apsFrame != NULL &&
+ (!(entry.endpoint == apsFrame->sourceEndpoint && entry.clusterId == apsFrame->clusterId &&
+ emberAfClusterIsClient(&entry) == clientToServer && entry.manufacturerCode == manufacturerCode) ||
+ (appResponseLength + reportSize > smallestPayloadMaxLength)))
+ {
+ if (appResponseLength + reportSize > smallestPayloadMaxLength)
+ {
+ emberAfReportingPrintln("Reporting Entry Full - creating new report");
+ }
+ conditionallySendReport(apsFrame->sourceEndpoint, apsFrame->clusterId);
+ apsFrame = NULL;
+ }
+
+ // If we haven't made the message header, make it.
+ if (apsFrame == NULL)
+ {
+ apsFrame = emberAfGetCommandApsFrame();
+ clientToServer = emberAfClusterIsClient(&entry);
+ // The manufacturer-specfic version of the fill API only creates a
+ // manufacturer-specfic command if the manufacturer code is set. For
+ // non-manufacturer-specfic reports, the manufacturer code is unset, so
+ // we can get away with using this API for both cases.
+ emberAfFillExternalManufacturerSpecificBuffer(
+ (clientToServer
+ ? (ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS)
+ : (ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS)),
+ entry.clusterId, entry.manufacturerCode, ZCL_REPORT_ATTRIBUTES_COMMAND_ID, "");
+ apsFrame->sourceEndpoint = entry.endpoint;
+ apsFrame->options = EMBER_AF_DEFAULT_APS_OPTIONS;
+ manufacturerCode = entry.manufacturerCode;
+
+ // EMAPPFWKV2-1327: Reporting plugin does not account for reporting too many attributes
+ // in the same ZCL:ReportAttributes message
+
+ // find smallest maximum payload that the destination can receive for this cluster and source endpoint
+ smallestPayloadMaxLength = MAX_INT8U_VALUE;
+ for (index = 0; index < EMBER_BINDING_TABLE_SIZE; index++)
+ {
+ status = (EmberAfStatus) emberGetBinding(index, &bindingEntry);
+ if (status == (EmberAfStatus) EMBER_SUCCESS && bindingEntry.local == entry.endpoint &&
+ bindingEntry.clusterId == entry.clusterId)
+ {
+ currentPayloadMaxLength =
+ emberAfMaximumApsPayloadLength(bindingEntry.type, bindingEntry.networkIndex, apsFrame);
+ if (currentPayloadMaxLength < smallestPayloadMaxLength)
+ {
+ smallestPayloadMaxLength = currentPayloadMaxLength;
+ }
+ }
+ }
+ }
+
+ // Payload is [attribute id:2] [type:1] [data:N].
+ emberAfPutInt16uInResp(entry.attributeId);
+ emberAfPutInt8uInResp(dataType);
#if (BIGENDIAN_CPU)
- if (isThisDataTypeSentLittleEndianOTA(dataType)) {
- uint8_t i;
- for (i = 0; i < dataSize; i++) {
- emberAfPutInt8uInResp(readData[dataSize - i - 1]);
- }
- } else {
- emberAfPutBlockInResp(readData, dataSize);
- }
+ if (isThisDataTypeSentLittleEndianOTA(dataType))
+ {
+ uint8_t i;
+ for (i = 0; i < dataSize; i++)
+ {
+ emberAfPutInt8uInResp(readData[dataSize - i - 1]);
+ }
+ }
+ else
+ {
+ emberAfPutBlockInResp(readData, dataSize);
+ }
#else
- emberAfPutBlockInResp(readData, dataSize);
+ emberAfPutBlockInResp(readData, dataSize);
#endif
- // Store the last reported time and value so that we can track intervals
- // and changes. We only track changes for data types that are small enough
- // for us to compare. For CHAR and OCTET strings, we substitute a 32-bit hash.
- emAfPluginReportVolatileData[i].reportableChange = false;
- emAfPluginReportVolatileData[i].lastReportTimeMs = halCommonGetInt32uMillisecondTick();
- uint32_t stringHash = 0;
- uint8_t *copyData = readData;
- uint8_t copySize = dataSize;
- if (dataType == ZCL_OCTET_STRING_ATTRIBUTE_TYPE || dataType == ZCL_CHAR_STRING_ATTRIBUTE_TYPE) {
- // dataSize was set above to count the string's length byte, in addition to string length.
- // Compute hash on string value only.
- stringHash = computeStringHash(readData + 1, dataSize - 1);
- copyData = (uint8_t *)&stringHash;
- copySize = sizeof(stringHash);
- }
- if (copySize <= sizeof(emAfPluginReportVolatileData[i].lastReportValue)) {
- emAfPluginReportVolatileData[i].lastReportValue = 0;
+ // Store the last reported time and value so that we can track intervals
+ // and changes. We only track changes for data types that are small enough
+ // for us to compare. For CHAR and OCTET strings, we substitute a 32-bit hash.
+ emAfPluginReportVolatileData[i].reportableChange = false;
+ emAfPluginReportVolatileData[i].lastReportTimeMs = halCommonGetInt32uMillisecondTick();
+ uint32_t stringHash = 0;
+ uint8_t * copyData = readData;
+ uint8_t copySize = dataSize;
+ if (dataType == ZCL_OCTET_STRING_ATTRIBUTE_TYPE || dataType == ZCL_CHAR_STRING_ATTRIBUTE_TYPE)
+ {
+ // dataSize was set above to count the string's length byte, in addition to string length.
+ // Compute hash on string value only.
+ stringHash = computeStringHash(readData + 1, dataSize - 1);
+ copyData = (uint8_t *) &stringHash;
+ copySize = sizeof(stringHash);
+ }
+ if (copySize <= sizeof(emAfPluginReportVolatileData[i].lastReportValue))
+ {
+ emAfPluginReportVolatileData[i].lastReportValue = 0;
#if (BIGENDIAN_CPU)
- MEMMOVE(((uint8_t *)&emAfPluginReportVolatileData[i].lastReportValue
- + sizeof(emAfPluginReportVolatileData[i].lastReportValue)
- - copySize),
- copyData,
- copySize);
+ MEMMOVE(((uint8_t *) &emAfPluginReportVolatileData[i].lastReportValue +
+ sizeof(emAfPluginReportVolatileData[i].lastReportValue) - copySize),
+ copyData, copySize);
#else
- MEMMOVE(&emAfPluginReportVolatileData[i].lastReportValue, copyData, copySize);
+ MEMMOVE(&emAfPluginReportVolatileData[i].lastReportValue, copyData, copySize);
#endif
+ }
}
- }
- if (apsFrame != NULL) {
- conditionallySendReport(apsFrame->sourceEndpoint, apsFrame->clusterId);
- }
- scheduleTick();
+ if (apsFrame != NULL)
+ {
+ conditionallySendReport(apsFrame->sourceEndpoint, apsFrame->clusterId);
+ }
+ scheduleTick();
}
static void conditionallySendReport(uint8_t endpoint, EmberAfClusterId clusterId)
{
- EmberStatus status;
- if (emberAfIsDeviceEnabled(endpoint)
- || clusterId == ZCL_IDENTIFY_CLUSTER_ID) {
- status = emberAfSendCommandUnicastToBindingsWithCallback((EmberAfMessageSentFunction)(&retrySendReport));
+ EmberStatus status;
+ if (emberAfIsDeviceEnabled(endpoint) || clusterId == ZCL_IDENTIFY_CLUSTER_ID)
+ {
+ status = emberAfSendCommandUnicastToBindingsWithCallback((EmberAfMessageSentFunction)(&retrySendReport));
- // If the callback table is full, attempt to send the message with no
- // callback. Note that this could lead to a message failing to transmit
- // with no notification to the user for any number of reasons (ex: hitting
- // the message queue limit), but is better than not sending the message at
- // all because the system hits its callback queue limit.
- if (status == EMBER_TABLE_FULL) {
- emberAfSendCommandUnicastToBindings();
- }
+ // If the callback table is full, attempt to send the message with no
+ // callback. Note that this could lead to a message failing to transmit
+ // with no notification to the user for any number of reasons (ex: hitting
+ // the message queue limit), but is better than not sending the message at
+ // all because the system hits its callback queue limit.
+ if (status == EMBER_TABLE_FULL)
+ {
+ emberAfSendCommandUnicastToBindings();
+ }
#ifdef EMBER_AF_PLUGIN_REPORTING_ENABLE_GROUP_BOUND_REPORTS
- emberAfSendCommandMulticastToBindings();
+ emberAfSendCommandMulticastToBindings();
#endif // EMBER_AF_PLUGIN_REPORTING_ENABLE_GROUP_BOUND_REPORTS
- }
+ }
}
-bool emberAfConfigureReportingCommandCallback(const EmberAfClusterCommand *cmd)
+bool emberAfConfigureReportingCommandCallback(const EmberAfClusterCommand * cmd)
{
- EmberStatus sendStatus;
- uint16_t bufIndex = cmd->payloadStartIndex;
- uint8_t frameControl, mask;
- bool failures = false;
+ EmberStatus sendStatus;
+ uint16_t bufIndex = cmd->payloadStartIndex;
+ uint8_t frameControl, mask;
+ bool failures = false;
- emberAfReportingPrint("%p: ", "CFG_RPT");
- emberAfReportingDebugExec(emberAfDecodeAndPrintClusterWithMfgCode(cmd->apsFrame->clusterId, cmd->mfgCode));
- emberAfReportingPrintln("");
- emberAfReportingFlush();
+ emberAfReportingPrint("%p: ", "CFG_RPT");
+ emberAfReportingDebugExec(emberAfDecodeAndPrintClusterWithMfgCode(cmd->apsFrame->clusterId, cmd->mfgCode));
+ emberAfReportingPrintln("");
+ emberAfReportingFlush();
- if (cmd->direction == ZCL_DIRECTION_CLIENT_TO_SERVER) {
- frameControl = (ZCL_GLOBAL_COMMAND
- | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
- mask = CLUSTER_MASK_SERVER;
- } else {
- frameControl = (ZCL_GLOBAL_COMMAND
- | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
- mask = CLUSTER_MASK_CLIENT;
- }
+ if (cmd->direction == ZCL_DIRECTION_CLIENT_TO_SERVER)
+ {
+ frameControl = (ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
+ mask = CLUSTER_MASK_SERVER;
+ }
+ else
+ {
+ frameControl = (ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
+ mask = CLUSTER_MASK_CLIENT;
+ }
- // The manufacturer-specfic version of the fill API only creates a
- // manufacturer-specfic command if the manufacturer code is set. For non-
- // manufacturer-specfic reports, the manufacturer code is unset, so we can
- // get away with using this API for both cases.
- emberAfFillExternalManufacturerSpecificBuffer(frameControl,
- cmd->apsFrame->clusterId,
- cmd->mfgCode,
- ZCL_CONFIGURE_REPORTING_RESPONSE_COMMAND_ID,
- "");
+ // The manufacturer-specfic version of the fill API only creates a
+ // manufacturer-specfic command if the manufacturer code is set. For non-
+ // manufacturer-specfic reports, the manufacturer code is unset, so we can
+ // get away with using this API for both cases.
+ emberAfFillExternalManufacturerSpecificBuffer(frameControl, cmd->apsFrame->clusterId, cmd->mfgCode,
+ ZCL_CONFIGURE_REPORTING_RESPONSE_COMMAND_ID, "");
- // Each record in the command has at least a one-byte direction and a two-
- // byte attribute id. Additional fields are present depending on the value
- // of the direction field.
- while (bufIndex + 3 < cmd->bufLen) {
- EmberAfAttributeId attributeId;
- EmberAfReportingDirection direction;
- EmberAfStatus status;
+ // Each record in the command has at least a one-byte direction and a two-
+ // byte attribute id. Additional fields are present depending on the value
+ // of the direction field.
+ while (bufIndex + 3 < cmd->bufLen)
+ {
+ EmberAfAttributeId attributeId;
+ EmberAfReportingDirection direction;
+ EmberAfStatus status;
- direction = (EmberAfReportingDirection)emberAfGetInt8u(cmd->buffer,
- bufIndex,
- cmd->bufLen);
- bufIndex++;
- attributeId = (EmberAfAttributeId)emberAfGetInt16u(cmd->buffer,
- bufIndex,
- cmd->bufLen);
- bufIndex += 2;
-
- emberAfReportingPrintln(" - direction:%x, attr:%2x", direction, attributeId);
-
- switch (direction) {
- case EMBER_ZCL_REPORTING_DIRECTION_REPORTED:
- {
- EmberAfAttributeMetadata* metadata;
- EmberAfAttributeType dataType;
- uint16_t minInterval, maxInterval;
- uint32_t reportableChange = 0;
- EmberAfPluginReportingEntry newEntry;
-
- dataType = (EmberAfAttributeType)emberAfGetInt8u(cmd->buffer,
- bufIndex,
- cmd->bufLen);
+ direction = (EmberAfReportingDirection) emberAfGetInt8u(cmd->buffer, bufIndex, cmd->bufLen);
bufIndex++;
- minInterval = emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
- bufIndex += 2;
- maxInterval = emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
+ attributeId = (EmberAfAttributeId) emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
bufIndex += 2;
- emberAfReportingPrintln(" type:%x, min:%2x, max:%2x",
- dataType,
- minInterval,
- maxInterval);
- emberAfReportingFlush();
+ emberAfReportingPrintln(" - direction:%x, attr:%2x", direction, attributeId);
- if (emberAfGetAttributeAnalogOrDiscreteType(dataType)
- == EMBER_AF_DATA_TYPE_ANALOG) {
- uint8_t dataSize = emberAfGetDataSize(dataType);
- reportableChange = emberAfGetInt(cmd->buffer,
- bufIndex,
- cmd->bufLen,
- dataSize);
+ switch (direction)
+ {
+ case EMBER_ZCL_REPORTING_DIRECTION_REPORTED: {
+ EmberAfAttributeMetadata * metadata;
+ EmberAfAttributeType dataType;
+ uint16_t minInterval, maxInterval;
+ uint32_t reportableChange = 0;
+ EmberAfPluginReportingEntry newEntry;
- emberAfReportingPrint(" change:");
- emberAfReportingPrintBuffer(cmd->buffer + bufIndex, dataSize, false);
- emberAfReportingPrintln("");
+ dataType = (EmberAfAttributeType) emberAfGetInt8u(cmd->buffer, bufIndex, cmd->bufLen);
+ bufIndex++;
+ minInterval = emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
+ bufIndex += 2;
+ maxInterval = emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
+ bufIndex += 2;
- bufIndex += dataSize;
+ emberAfReportingPrintln(" type:%x, min:%2x, max:%2x", dataType, minInterval, maxInterval);
+ emberAfReportingFlush();
+
+ if (emberAfGetAttributeAnalogOrDiscreteType(dataType) == EMBER_AF_DATA_TYPE_ANALOG)
+ {
+ uint8_t dataSize = emberAfGetDataSize(dataType);
+ reportableChange = emberAfGetInt(cmd->buffer, bufIndex, cmd->bufLen, dataSize);
+
+ emberAfReportingPrint(" change:");
+ emberAfReportingPrintBuffer(cmd->buffer + bufIndex, dataSize, false);
+ emberAfReportingPrintln("");
+
+ bufIndex += dataSize;
+ }
+
+ // emberAfPluginReportingConfigureReportedAttribute handles non-
+ // existent attributes, but does not verify the attribute data type, so
+ // we need to check it here.
+ metadata = emberAfLocateAttributeMetadata(cmd->apsFrame->destinationEndpoint, cmd->apsFrame->clusterId, attributeId,
+ mask, cmd->mfgCode);
+ if (metadata != NULL && metadata->attributeType != dataType)
+ {
+ status = EMBER_ZCL_STATUS_INVALID_DATA_TYPE;
+ }
+ else
+ {
+ // Add a reporting entry for a reported attribute. The reports will
+ // be sent from us to the source of the Configure Reporting command.
+ newEntry.endpoint = cmd->apsFrame->destinationEndpoint;
+ newEntry.clusterId = cmd->apsFrame->clusterId;
+ newEntry.attributeId = attributeId;
+ newEntry.mask = mask;
+ newEntry.manufacturerCode = cmd->mfgCode;
+ newEntry.data.reported.minInterval = minInterval;
+ newEntry.data.reported.maxInterval = maxInterval;
+ newEntry.data.reported.reportableChange = reportableChange;
+ status = emberAfPluginReportingConfigureReportedAttribute(&newEntry);
+ }
+ break;
+ }
+ case EMBER_ZCL_REPORTING_DIRECTION_RECEIVED: {
+ uint16_t timeout = emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
+ bufIndex += 2;
+
+ emberAfReportingPrintln(" timeout:%2x", timeout);
+
+ // Add a reporting entry from a received attribute. The reports
+ // will be sent to us from the source of the Configure Reporting
+ // command.
+ status = configureReceivedAttribute(cmd, attributeId, mask, timeout);
+ break;
+ }
+ default:
+ // This will abort the processing (see below).
+ status = EMBER_ZCL_STATUS_INVALID_FIELD;
+ break;
}
- // emberAfPluginReportingConfigureReportedAttribute handles non-
- // existent attributes, but does not verify the attribute data type, so
- // we need to check it here.
- metadata = emberAfLocateAttributeMetadata(cmd->apsFrame->destinationEndpoint,
- cmd->apsFrame->clusterId,
- attributeId,
- mask,
- cmd->mfgCode);
- if (metadata != NULL && metadata->attributeType != dataType) {
- status = EMBER_ZCL_STATUS_INVALID_DATA_TYPE;
- } else {
- // Add a reporting entry for a reported attribute. The reports will
- // be sent from us to the source of the Configure Reporting command.
- newEntry.endpoint = cmd->apsFrame->destinationEndpoint;
- newEntry.clusterId = cmd->apsFrame->clusterId;
- newEntry.attributeId = attributeId;
- newEntry.mask = mask;
- newEntry.manufacturerCode = cmd->mfgCode;
- newEntry.data.reported.minInterval = minInterval;
- newEntry.data.reported.maxInterval = maxInterval;
- newEntry.data.reported.reportableChange = reportableChange;
- status = emberAfPluginReportingConfigureReportedAttribute(&newEntry);
+ // If a report cannot be configured, the status, direction, and
+ // attribute are added to the response. If the failure was due to an
+ // invalid field, we have to abort after this record because we don't
+ // know how to interpret the rest of the data in the request.
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfPutInt8uInResp(status);
+ emberAfPutInt8uInResp(direction);
+ emberAfPutInt16uInResp(attributeId);
+ failures = true;
+ if (status == EMBER_ZCL_STATUS_INVALID_FIELD)
+ {
+ break;
+ }
}
- break;
- }
- case EMBER_ZCL_REPORTING_DIRECTION_RECEIVED:
- {
- uint16_t timeout = emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
- bufIndex += 2;
-
- emberAfReportingPrintln(" timeout:%2x", timeout);
-
- // Add a reporting entry from a received attribute. The reports
- // will be sent to us from the source of the Configure Reporting
- // command.
- status = configureReceivedAttribute(cmd,
- attributeId,
- mask,
- timeout);
- break;
- }
- default:
- // This will abort the processing (see below).
- status = EMBER_ZCL_STATUS_INVALID_FIELD;
- break;
}
- // If a report cannot be configured, the status, direction, and
- // attribute are added to the response. If the failure was due to an
- // invalid field, we have to abort after this record because we don't
- // know how to interpret the rest of the data in the request.
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfPutInt8uInResp(status);
- emberAfPutInt8uInResp(direction);
- emberAfPutInt16uInResp(attributeId);
- failures = true;
- if (status == EMBER_ZCL_STATUS_INVALID_FIELD) {
- break;
- }
+ // We just respond with SUCCESS if we made it through without failures.
+ if (!failures)
+ {
+ emberAfPutInt8uInResp(EMBER_ZCL_STATUS_SUCCESS);
}
- }
- // We just respond with SUCCESS if we made it through without failures.
- if (!failures) {
- emberAfPutInt8uInResp(EMBER_ZCL_STATUS_SUCCESS);
- }
-
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfReportingPrintln("Reporting: failed to send %s response: 0x%x",
- "configure_reporting",
- sendStatus);
- }
- return true;
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfReportingPrintln("Reporting: failed to send %s response: 0x%x", "configure_reporting", sendStatus);
+ }
+ return true;
}
-bool emberAfReadReportingConfigurationCommandCallback(const EmberAfClusterCommand *cmd)
+bool emberAfReadReportingConfigurationCommandCallback(const EmberAfClusterCommand * cmd)
{
- EmberStatus sendStatus;
- uint16_t bufIndex = cmd->payloadStartIndex;
- uint8_t frameControl, mask;
+ EmberStatus sendStatus;
+ uint16_t bufIndex = cmd->payloadStartIndex;
+ uint8_t frameControl, mask;
- emberAfReportingPrint("%p: ", "READ_RPT_CFG");
- emberAfReportingDebugExec(emberAfDecodeAndPrintClusterWithMfgCode(cmd->apsFrame->clusterId, cmd->mfgCode));
- emberAfReportingPrintln("");
- emberAfReportingFlush();
+ emberAfReportingPrint("%p: ", "READ_RPT_CFG");
+ emberAfReportingDebugExec(emberAfDecodeAndPrintClusterWithMfgCode(cmd->apsFrame->clusterId, cmd->mfgCode));
+ emberAfReportingPrintln("");
+ emberAfReportingFlush();
- if (cmd->direction == ZCL_DIRECTION_CLIENT_TO_SERVER) {
- frameControl = (ZCL_GLOBAL_COMMAND
- | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
- mask = CLUSTER_MASK_SERVER;
- } else {
- frameControl = (ZCL_GLOBAL_COMMAND
- | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
- mask = CLUSTER_MASK_CLIENT;
- }
+ if (cmd->direction == ZCL_DIRECTION_CLIENT_TO_SERVER)
+ {
+ frameControl = (ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
+ mask = CLUSTER_MASK_SERVER;
+ }
+ else
+ {
+ frameControl = (ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER | EMBER_AF_DEFAULT_RESPONSE_POLICY_REQUESTS);
+ mask = CLUSTER_MASK_CLIENT;
+ }
- // The manufacturer-specfic version of the fill API only creates a
- // manufacturer-specfic command if the manufacturer code is set. For non-
- // manufacturer-specfic reports, the manufacturer code is unset, so we can
- // get away with using this API for both cases.
- emberAfFillExternalManufacturerSpecificBuffer(frameControl,
- cmd->apsFrame->clusterId,
- cmd->mfgCode,
- ZCL_READ_REPORTING_CONFIGURATION_RESPONSE_COMMAND_ID,
- "");
+ // The manufacturer-specfic version of the fill API only creates a
+ // manufacturer-specfic command if the manufacturer code is set. For non-
+ // manufacturer-specfic reports, the manufacturer code is unset, so we can
+ // get away with using this API for both cases.
+ emberAfFillExternalManufacturerSpecificBuffer(frameControl, cmd->apsFrame->clusterId, cmd->mfgCode,
+ ZCL_READ_REPORTING_CONFIGURATION_RESPONSE_COMMAND_ID, "");
- // Each record in the command has a one-byte direction and a two-byte
- // attribute id.
- while (bufIndex + 3 <= cmd->bufLen) {
- EmberAfAttributeId attributeId;
- EmberAfAttributeMetadata *metadata = NULL;
- EmberAfPluginReportingEntry entry;
- EmberAfReportingDirection direction;
- uint8_t i;
- bool found = false;
+ // Each record in the command has a one-byte direction and a two-byte
+ // attribute id.
+ while (bufIndex + 3 <= cmd->bufLen)
+ {
+ EmberAfAttributeId attributeId;
+ EmberAfAttributeMetadata * metadata = NULL;
+ EmberAfPluginReportingEntry entry;
+ EmberAfReportingDirection direction;
+ uint8_t i;
+ bool found = false;
- direction = (EmberAfReportingDirection)emberAfGetInt8u(cmd->buffer,
- bufIndex,
- cmd->bufLen);
- bufIndex++;
- attributeId = (EmberAfAttributeId)emberAfGetInt16u(cmd->buffer,
- bufIndex,
- cmd->bufLen);
- bufIndex += 2;
+ direction = (EmberAfReportingDirection) emberAfGetInt8u(cmd->buffer, bufIndex, cmd->bufLen);
+ bufIndex++;
+ attributeId = (EmberAfAttributeId) emberAfGetInt16u(cmd->buffer, bufIndex, cmd->bufLen);
+ bufIndex += 2;
- switch (direction) {
- case EMBER_ZCL_REPORTING_DIRECTION_REPORTED:
- case EMBER_ZCL_REPORTING_DIRECTION_RECEIVED:
- metadata = emberAfLocateAttributeMetadata(cmd->apsFrame->destinationEndpoint,
- cmd->apsFrame->clusterId,
- attributeId,
- mask,
- cmd->mfgCode);
- if (metadata == NULL) {
- emberAfPutInt8uInResp(EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE);
- emberAfPutInt8uInResp(direction);
- emberAfPutInt16uInResp(attributeId);
- continue;
+ switch (direction)
+ {
+ case EMBER_ZCL_REPORTING_DIRECTION_REPORTED:
+ case EMBER_ZCL_REPORTING_DIRECTION_RECEIVED:
+ metadata = emberAfLocateAttributeMetadata(cmd->apsFrame->destinationEndpoint, cmd->apsFrame->clusterId, attributeId,
+ mask, cmd->mfgCode);
+ if (metadata == NULL)
+ {
+ emberAfPutInt8uInResp(EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE);
+ emberAfPutInt8uInResp(direction);
+ emberAfPutInt16uInResp(attributeId);
+ continue;
+ }
+ break;
+ default:
+ emberAfPutInt8uInResp(EMBER_ZCL_STATUS_INVALID_FIELD);
+ emberAfPutInt8uInResp(direction);
+ emberAfPutInt16uInResp(attributeId);
+ continue;
}
- break;
- default:
- emberAfPutInt8uInResp(EMBER_ZCL_STATUS_INVALID_FIELD);
+
+ // 075123r03 seems to suggest that SUCCESS is returned even if reporting
+ // isn't configured for the requested attribute. The individual fields
+ // of the response for this attribute get populated with defaults.
+ // CCB 1854 removes the ambiguity and requires NOT_FOUND to be returned in
+ // the status field and all fields except direction and attribute identifier
+ // to be omitted if there is no report configuration found.
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ emAfPluginReportingGetEntry(i, &entry);
+ if (entry.direction == direction && entry.endpoint == cmd->apsFrame->destinationEndpoint &&
+ entry.clusterId == cmd->apsFrame->clusterId && entry.attributeId == attributeId && entry.mask == mask &&
+ entry.manufacturerCode == cmd->mfgCode &&
+ (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED ||
+ (entry.data.received.source == cmd->source && entry.data.received.endpoint == cmd->apsFrame->sourceEndpoint)))
+ {
+ found = true;
+ break;
+ }
+ }
+ // Attribute supported, reportable, no report configuration was found.
+ if (found == false)
+ {
+ emberAfPutInt8uInResp(EMBER_ZCL_STATUS_NOT_FOUND);
+ emberAfPutInt8uInResp(direction);
+ emberAfPutInt16uInResp(attributeId);
+ continue;
+ }
+ // Attribute supported, reportable, report configuration was found.
+ emberAfPutInt8uInResp(EMBER_ZCL_STATUS_SUCCESS);
emberAfPutInt8uInResp(direction);
emberAfPutInt16uInResp(attributeId);
- continue;
- }
-
- // 075123r03 seems to suggest that SUCCESS is returned even if reporting
- // isn't configured for the requested attribute. The individual fields
- // of the response for this attribute get populated with defaults.
- // CCB 1854 removes the ambiguity and requires NOT_FOUND to be returned in
- // the status field and all fields except direction and attribute identifier
- // to be omitted if there is no report configuration found.
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- emAfPluginReportingGetEntry(i, &entry);
- if (entry.direction == direction
- && entry.endpoint == cmd->apsFrame->destinationEndpoint
- && entry.clusterId == cmd->apsFrame->clusterId
- && entry.attributeId == attributeId
- && entry.mask == mask
- && entry.manufacturerCode == cmd->mfgCode
- && (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED
- || (entry.data.received.source == cmd->source
- && entry.data.received.endpoint == cmd->apsFrame->sourceEndpoint))) {
- found = true;
- break;
- }
- }
- // Attribute supported, reportable, no report configuration was found.
- if (found == false) {
- emberAfPutInt8uInResp(EMBER_ZCL_STATUS_NOT_FOUND);
- emberAfPutInt8uInResp(direction);
- emberAfPutInt16uInResp(attributeId);
- continue;
- }
- // Attribute supported, reportable, report configuration was found.
- emberAfPutInt8uInResp(EMBER_ZCL_STATUS_SUCCESS);
- emberAfPutInt8uInResp(direction);
- emberAfPutInt16uInResp(attributeId);
- switch (direction) {
- case EMBER_ZCL_REPORTING_DIRECTION_REPORTED:
- if (metadata != NULL) {
- emberAfPutInt8uInResp(metadata->attributeType);
- emberAfPutInt16uInResp(entry.data.reported.minInterval);
- emberAfPutInt16uInResp(entry.data.reported.maxInterval);
- if (emberAfGetAttributeAnalogOrDiscreteType(metadata->attributeType)
- == EMBER_AF_DATA_TYPE_ANALOG) {
- putReportableChangeInResp(&entry, metadata->attributeType);
- }
+ switch (direction)
+ {
+ case EMBER_ZCL_REPORTING_DIRECTION_REPORTED:
+ if (metadata != NULL)
+ {
+ emberAfPutInt8uInResp(metadata->attributeType);
+ emberAfPutInt16uInResp(entry.data.reported.minInterval);
+ emberAfPutInt16uInResp(entry.data.reported.maxInterval);
+ if (emberAfGetAttributeAnalogOrDiscreteType(metadata->attributeType) == EMBER_AF_DATA_TYPE_ANALOG)
+ {
+ putReportableChangeInResp(&entry, metadata->attributeType);
+ }
+ }
+ break;
+ case EMBER_ZCL_REPORTING_DIRECTION_RECEIVED:
+ emberAfPutInt16uInResp(entry.data.received.timeout);
+ break;
}
- break;
- case EMBER_ZCL_REPORTING_DIRECTION_RECEIVED:
- emberAfPutInt16uInResp(entry.data.received.timeout);
- break;
}
- }
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfReportingPrintln("Reporting: failed to send %s response: 0x%x",
- "read_reporting_configuration",
- sendStatus);
- }
- return true;
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfReportingPrintln("Reporting: failed to send %s response: 0x%x", "read_reporting_configuration", sendStatus);
+ }
+ return true;
}
EmberStatus emberAfClearReportTableCallback(void)
{
- uint8_t i;
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- removeConfiguration(i);
- }
- emberEventControlSetInactive(emberAfPluginReportingTickEventControl);
- return EMBER_SUCCESS;
+ uint8_t i;
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ removeConfiguration(i);
+ }
+ emberEventControlSetInactive(emberAfPluginReportingTickEventControl);
+ return EMBER_SUCCESS;
}
EmberStatus emAfPluginReportingRemoveEntry(uint8_t index)
{
- EmberStatus status = EMBER_INDEX_OUT_OF_RANGE;
- if (index < REPORT_TABLE_SIZE) {
- removeConfigurationAndScheduleTick(index);
- status = EMBER_SUCCESS;
- }
- return status;
+ EmberStatus status = EMBER_INDEX_OUT_OF_RANGE;
+ if (index < REPORT_TABLE_SIZE)
+ {
+ removeConfigurationAndScheduleTick(index);
+ status = EMBER_SUCCESS;
+ }
+ return status;
}
-void emberAfReportingAttributeChangeCallback(uint8_t endpoint,
- EmberAfClusterId clusterId,
- EmberAfAttributeId attributeId,
- uint8_t mask,
- uint16_t manufacturerCode,
- EmberAfAttributeType type,
- uint8_t *data)
+void emberAfReportingAttributeChangeCallback(uint8_t endpoint, EmberAfClusterId clusterId, EmberAfAttributeId attributeId,
+ uint8_t mask, uint16_t manufacturerCode, EmberAfAttributeType type, uint8_t * data)
{
- uint8_t i;
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- EmberAfPluginReportingEntry entry;
- emAfPluginReportingGetEntry(i, &entry);
- if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED
- && entry.endpoint == endpoint
- && entry.clusterId == clusterId
- && entry.attributeId == attributeId
- && entry.mask == mask
- && entry.manufacturerCode == manufacturerCode) {
- // For CHAR and OCTET strings, the string value may be too long to fit into the
- // lastReportValue field (EmberAfDifferenceType), so instead we save the string's
- // hash, and detect changes in string value based on unequal hash.
- uint32_t stringHash = 0;
- uint8_t dataSize = emberAfGetDataSize(type);
- uint8_t *dataRef = data;
- if (type == ZCL_OCTET_STRING_ATTRIBUTE_TYPE || type == ZCL_CHAR_STRING_ATTRIBUTE_TYPE) {
- stringHash = computeStringHash(data + 1, emberAfStringLength(data));
- dataRef = (uint8_t *)&stringHash;
- dataSize = sizeof(stringHash);
- }
- // If we are reporting this particular attribute, we only care whether
- // the new value meets the reportable change criteria. If it does, we
- // mark the entry as ready to report and reschedule the tick. Whether
- // the tick will be scheduled for immediate or delayed execution depends
- // on the minimum reporting interval. This is handled in the scheduler.
- EmberAfDifferenceType difference
- = emberAfGetDifference(dataRef,
- emAfPluginReportVolatileData[i].lastReportValue,
- dataSize);
- uint8_t analogOrDiscrete = emberAfGetAttributeAnalogOrDiscreteType(type);
- if ((analogOrDiscrete == EMBER_AF_DATA_TYPE_DISCRETE && difference != 0)
- || (analogOrDiscrete == EMBER_AF_DATA_TYPE_ANALOG
- && entry.data.reported.reportableChange <= difference)) {
- emAfPluginReportVolatileData[i].reportableChange = true;
- scheduleTick();
- }
- break;
+ uint8_t i;
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ EmberAfPluginReportingEntry entry;
+ emAfPluginReportingGetEntry(i, &entry);
+ if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED && entry.endpoint == endpoint &&
+ entry.clusterId == clusterId && entry.attributeId == attributeId && entry.mask == mask &&
+ entry.manufacturerCode == manufacturerCode)
+ {
+ // For CHAR and OCTET strings, the string value may be too long to fit into the
+ // lastReportValue field (EmberAfDifferenceType), so instead we save the string's
+ // hash, and detect changes in string value based on unequal hash.
+ uint32_t stringHash = 0;
+ uint8_t dataSize = emberAfGetDataSize(type);
+ uint8_t * dataRef = data;
+ if (type == ZCL_OCTET_STRING_ATTRIBUTE_TYPE || type == ZCL_CHAR_STRING_ATTRIBUTE_TYPE)
+ {
+ stringHash = computeStringHash(data + 1, emberAfStringLength(data));
+ dataRef = (uint8_t *) &stringHash;
+ dataSize = sizeof(stringHash);
+ }
+ // If we are reporting this particular attribute, we only care whether
+ // the new value meets the reportable change criteria. If it does, we
+ // mark the entry as ready to report and reschedule the tick. Whether
+ // the tick will be scheduled for immediate or delayed execution depends
+ // on the minimum reporting interval. This is handled in the scheduler.
+ EmberAfDifferenceType difference =
+ emberAfGetDifference(dataRef, emAfPluginReportVolatileData[i].lastReportValue, dataSize);
+ uint8_t analogOrDiscrete = emberAfGetAttributeAnalogOrDiscreteType(type);
+ if ((analogOrDiscrete == EMBER_AF_DATA_TYPE_DISCRETE && difference != 0) ||
+ (analogOrDiscrete == EMBER_AF_DATA_TYPE_ANALOG && entry.data.reported.reportableChange <= difference))
+ {
+ emAfPluginReportVolatileData[i].reportableChange = true;
+ scheduleTick();
+ }
+ break;
+ }
}
- }
}
-bool emAfPluginReportingDoEntriesMatch(const EmberAfPluginReportingEntry* const entry1,
- const EmberAfPluginReportingEntry* const entry2)
+bool emAfPluginReportingDoEntriesMatch(const EmberAfPluginReportingEntry * const entry1,
+ const EmberAfPluginReportingEntry * const entry2)
{
- // Verify that the reporting parameters of both entries match.
- // If the entries are for EMBER_ZCL_REPORTING_DIRECTION_REPORTED, the
- // reporting configurations do not need to match. If the direction is
- // EMBER_ZCL_REPORTING_DIRECTION_RECEIVED, then the source and destination
- // endpoints need to match.
- if ((entry1->endpoint == entry2->endpoint)
- && (entry1->clusterId == entry2->clusterId)
- && (entry1->attributeId == entry2->attributeId)
- && (entry1->mask == entry2->mask)
- && (entry1->manufacturerCode == entry2->manufacturerCode)
- && (entry1->direction == entry2->direction)
- && ((entry1->direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED)
- || ((entry1->data.received.source == entry2->data.received.source)
- && (entry1->data.received.endpoint
- == entry2->data.received.endpoint)))) {
- return true;
- }
- return false;
+ // Verify that the reporting parameters of both entries match.
+ // If the entries are for EMBER_ZCL_REPORTING_DIRECTION_REPORTED, the
+ // reporting configurations do not need to match. If the direction is
+ // EMBER_ZCL_REPORTING_DIRECTION_RECEIVED, then the source and destination
+ // endpoints need to match.
+ if ((entry1->endpoint == entry2->endpoint) && (entry1->clusterId == entry2->clusterId) &&
+ (entry1->attributeId == entry2->attributeId) && (entry1->mask == entry2->mask) &&
+ (entry1->manufacturerCode == entry2->manufacturerCode) && (entry1->direction == entry2->direction) &&
+ ((entry1->direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED) ||
+ ((entry1->data.received.source == entry2->data.received.source) &&
+ (entry1->data.received.endpoint == entry2->data.received.endpoint))))
+ {
+ return true;
+ }
+ return false;
}
-uint8_t emAfPluginReportingAddEntry(EmberAfPluginReportingEntry* newEntry)
+uint8_t emAfPluginReportingAddEntry(EmberAfPluginReportingEntry * newEntry)
{
- uint8_t i;
- EmberAfPluginReportingEntry oldEntry;
+ uint8_t i;
+ EmberAfPluginReportingEntry oldEntry;
- // If an entry already exists, or exists but with different parameters,
- // overwrite it with the new entry to prevent pollution of the report table
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- emAfPluginReportingGetEntry(i, &oldEntry);
- if (emAfPluginReportingDoEntriesMatch(&oldEntry, newEntry)) {
- emAfPluginReportingSetEntry(i, newEntry);
- return i;
+ // If an entry already exists, or exists but with different parameters,
+ // overwrite it with the new entry to prevent pollution of the report table
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ emAfPluginReportingGetEntry(i, &oldEntry);
+ if (emAfPluginReportingDoEntriesMatch(&oldEntry, newEntry))
+ {
+ emAfPluginReportingSetEntry(i, newEntry);
+ return i;
+ }
}
- }
- // If no pre-existing entries were found, copy the new entry into the lowest
- // indexed free spot in the reporting table
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- emAfPluginReportingGetEntry(i, &oldEntry);
- if (oldEntry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID) {
- emAfPluginReportingSetEntry(i, newEntry);
- return i;
+ // If no pre-existing entries were found, copy the new entry into the lowest
+ // indexed free spot in the reporting table
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ emAfPluginReportingGetEntry(i, &oldEntry);
+ if (oldEntry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID)
+ {
+ emAfPluginReportingSetEntry(i, newEntry);
+ return i;
+ }
}
- }
- // If no free spots were found, return the failure indicator
- return 0xFF;
+ // If no free spots were found, return the failure indicator
+ return 0xFF;
}
static void scheduleTick(void)
{
- uint32_t delayMs = MAX_INT32U_VALUE;
- uint8_t i;
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- EmberAfPluginReportingEntry entry;
- emAfPluginReportingGetEntry(i, &entry);
- if (entry.endpoint != EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID
- && entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED) {
- uint32_t minIntervalMs = (entry.data.reported.minInterval
- * MILLISECOND_TICKS_PER_SECOND);
- uint32_t maxIntervalMs = (entry.data.reported.maxInterval
- * MILLISECOND_TICKS_PER_SECOND);
- uint32_t elapsedMs = elapsedTimeInt32u(emAfPluginReportVolatileData[i].lastReportTimeMs,
- halCommonGetInt32uMillisecondTick());
- uint32_t remainingMs = MAX_INT32U_VALUE;
- if (emAfPluginReportVolatileData[i].reportableChange) {
- remainingMs = (minIntervalMs < elapsedMs
- ? 0
- : minIntervalMs - elapsedMs);
- } else if (maxIntervalMs) {
- remainingMs = (maxIntervalMs < elapsedMs
- ? 0
- : maxIntervalMs - elapsedMs);
- }
- if (remainingMs < delayMs) {
- delayMs = remainingMs;
- }
+ uint32_t delayMs = MAX_INT32U_VALUE;
+ uint8_t i;
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ EmberAfPluginReportingEntry entry;
+ emAfPluginReportingGetEntry(i, &entry);
+ if (entry.endpoint != EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID &&
+ entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED)
+ {
+ uint32_t minIntervalMs = (entry.data.reported.minInterval * MILLISECOND_TICKS_PER_SECOND);
+ uint32_t maxIntervalMs = (entry.data.reported.maxInterval * MILLISECOND_TICKS_PER_SECOND);
+ uint32_t elapsedMs =
+ elapsedTimeInt32u(emAfPluginReportVolatileData[i].lastReportTimeMs, halCommonGetInt32uMillisecondTick());
+ uint32_t remainingMs = MAX_INT32U_VALUE;
+ if (emAfPluginReportVolatileData[i].reportableChange)
+ {
+ remainingMs = (minIntervalMs < elapsedMs ? 0 : minIntervalMs - elapsedMs);
+ }
+ else if (maxIntervalMs)
+ {
+ remainingMs = (maxIntervalMs < elapsedMs ? 0 : maxIntervalMs - elapsedMs);
+ }
+ if (remainingMs < delayMs)
+ {
+ delayMs = remainingMs;
+ }
+ }
}
- }
- if (delayMs != MAX_INT32U_VALUE) {
- emberAfDebugPrintln("sched report event for: 0x%4x", delayMs);
- emberAfEventControlSetDelayMS(&emberAfPluginReportingTickEventControl,
- delayMs);
- } else {
- emberAfDebugPrintln("deactivate report event");
- emberEventControlSetInactive(emberAfPluginReportingTickEventControl);
- }
+ if (delayMs != MAX_INT32U_VALUE)
+ {
+ emberAfDebugPrintln("sched report event for: 0x%4x", delayMs);
+ emberAfEventControlSetDelayMS(&emberAfPluginReportingTickEventControl, delayMs);
+ }
+ else
+ {
+ emberAfDebugPrintln("deactivate report event");
+ emberEventControlSetInactive(emberAfPluginReportingTickEventControl);
+ }
}
static void removeConfiguration(uint8_t index)
{
- EmberAfPluginReportingEntry entry;
- emAfPluginReportingGetEntry(index, &entry);
- entry.endpoint = EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID;
- emAfPluginReportingSetEntry(index, &entry);
- emberAfPluginReportingConfiguredCallback(&entry);
+ EmberAfPluginReportingEntry entry;
+ emAfPluginReportingGetEntry(index, &entry);
+ entry.endpoint = EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID;
+ emAfPluginReportingSetEntry(index, &entry);
+ emberAfPluginReportingConfiguredCallback(&entry);
}
static void removeConfigurationAndScheduleTick(uint8_t index)
{
- removeConfiguration(index);
- scheduleTick();
-}
-
-EmberAfStatus emberAfPluginReportingConfigureReportedAttribute(const EmberAfPluginReportingEntry* newEntry)
-{
- EmberAfAttributeMetadata *metadata;
- EmberAfPluginReportingEntry entry;
- EmberAfStatus status;
- uint8_t i, index = NULL_INDEX;
- bool initialize = true;
-
- // Verify that we support the attribute and that the data type matches.
- metadata = emberAfLocateAttributeMetadata(newEntry->endpoint,
- newEntry->clusterId,
- newEntry->attributeId,
- newEntry->mask,
- newEntry->manufacturerCode);
- if (metadata == NULL) {
- return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
- }
-
- // Verify the minimum and maximum intervals make sense.
- if (newEntry->data.reported.maxInterval != 0
- && (newEntry->data.reported.maxInterval
- < newEntry->data.reported.minInterval)) {
- return EMBER_ZCL_STATUS_INVALID_VALUE;
- }
-
- // Check the table for an entry that matches this request and also watch for
- // empty slots along the way. If a report exists, it will be overwritten
- // with the new configuration. Otherwise, a new entry will be created and
- // initialized.
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- emAfPluginReportingGetEntry(i, &entry);
- if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED
- && entry.endpoint == newEntry->endpoint
- && entry.clusterId == newEntry->clusterId
- && entry.attributeId == newEntry->attributeId
- && entry.mask == newEntry->mask
- && entry.manufacturerCode == newEntry->manufacturerCode) {
- initialize = false;
- index = i;
- break;
- } else if (entry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID
- && index == NULL_INDEX) {
- index = i;
- }
- }
-
- // If the maximum reporting interval is 0xFFFF, the device shall not issue
- // reports for the attribute and the configuration information for that
- // attribute need not be maintained.
- if (newEntry->data.reported.maxInterval == 0xFFFF) {
- if (!initialize) {
- removeConfigurationAndScheduleTick(index);
- }
- return EMBER_ZCL_STATUS_SUCCESS;
- }
- // ZCL v6 Section 2.5.7.1.6 Maximum Reporting Interval Field
- // If this value is set to 0x0000 and the minimum reporting interval field
- // equals 0xffff, then the device SHALL revert back to its default reporting
- // configuration. The reportable change field, if present, SHALL be set to
- // zero.
- // Verify special condition to reset the reporting configuration to defaults
- // if the minimum == 0xFFFF and maximum == 0x0000
- bool reset = false;
- if ((newEntry->data.reported.maxInterval == 0x0000)
- && (newEntry->data.reported.minInterval == 0xFFFF)) {
- // Get the configuration from the default configuration table for this
- MEMMOVE(&entry, newEntry, sizeof(EmberAfPluginReportingEntry));
- if (emberAfPluginReportingGetReportingConfigDefaults(&entry)) {
- // Then it must be initialise with the default config - explicity
- initialize = true;
- reset = true;
- }
- }
-
- if (index == NULL_INDEX) {
- return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
- } else if (initialize) {
- entry.direction = EMBER_ZCL_REPORTING_DIRECTION_REPORTED;
- entry.endpoint = newEntry->endpoint;
- entry.clusterId = newEntry->clusterId;
- entry.attributeId = newEntry->attributeId;
- entry.mask = newEntry->mask;
- entry.manufacturerCode = newEntry->manufacturerCode;
- if (index < REPORT_TABLE_SIZE) {
- emAfPluginReportVolatileData[index].lastReportTimeMs = halCommonGetInt32uMillisecondTick();
- emAfPluginReportVolatileData[index].lastReportValue = 0;
- }
- }
-
- // For new or updated entries, set the intervals and reportable change.
- // Updated entries will retain all other settings configured previously.
- if (false == reset) {
- entry.data.reported.minInterval = newEntry->data.reported.minInterval;
- entry.data.reported.maxInterval = newEntry->data.reported.maxInterval;
- entry.data.reported.reportableChange = newEntry->data.reported.reportableChange;
- }
- // Give the application a chance to review the configuration that we have
- // been building up. If the application rejects it, we just do not save the
- // record. If we were supposed to add a new configuration, it will not be
- // created. If we were supposed to update an existing configuration, we will
- // keep the old one and just discard any changes. So, in either case, life
- // continues unchanged if the application rejects the configuration.
- status = emberAfPluginReportingConfiguredCallback(&entry);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emAfPluginReportingSetEntry(index, &entry);
+ removeConfiguration(index);
scheduleTick();
- }
- return status;
}
-static EmberAfStatus configureReceivedAttribute(const EmberAfClusterCommand *cmd,
- EmberAfAttributeId attributeId,
- uint8_t mask,
+EmberAfStatus emberAfPluginReportingConfigureReportedAttribute(const EmberAfPluginReportingEntry * newEntry)
+{
+ EmberAfAttributeMetadata * metadata;
+ EmberAfPluginReportingEntry entry;
+ EmberAfStatus status;
+ uint8_t i, index = NULL_INDEX;
+ bool initialize = true;
+
+ // Verify that we support the attribute and that the data type matches.
+ metadata = emberAfLocateAttributeMetadata(newEntry->endpoint, newEntry->clusterId, newEntry->attributeId, newEntry->mask,
+ newEntry->manufacturerCode);
+ if (metadata == NULL)
+ {
+ return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE;
+ }
+
+ // Verify the minimum and maximum intervals make sense.
+ if (newEntry->data.reported.maxInterval != 0 && (newEntry->data.reported.maxInterval < newEntry->data.reported.minInterval))
+ {
+ return EMBER_ZCL_STATUS_INVALID_VALUE;
+ }
+
+ // Check the table for an entry that matches this request and also watch for
+ // empty slots along the way. If a report exists, it will be overwritten
+ // with the new configuration. Otherwise, a new entry will be created and
+ // initialized.
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ emAfPluginReportingGetEntry(i, &entry);
+ if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_REPORTED && entry.endpoint == newEntry->endpoint &&
+ entry.clusterId == newEntry->clusterId && entry.attributeId == newEntry->attributeId && entry.mask == newEntry->mask &&
+ entry.manufacturerCode == newEntry->manufacturerCode)
+ {
+ initialize = false;
+ index = i;
+ break;
+ }
+ else if (entry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID && index == NULL_INDEX)
+ {
+ index = i;
+ }
+ }
+
+ // If the maximum reporting interval is 0xFFFF, the device shall not issue
+ // reports for the attribute and the configuration information for that
+ // attribute need not be maintained.
+ if (newEntry->data.reported.maxInterval == 0xFFFF)
+ {
+ if (!initialize)
+ {
+ removeConfigurationAndScheduleTick(index);
+ }
+ return EMBER_ZCL_STATUS_SUCCESS;
+ }
+ // ZCL v6 Section 2.5.7.1.6 Maximum Reporting Interval Field
+ // If this value is set to 0x0000 and the minimum reporting interval field
+ // equals 0xffff, then the device SHALL revert back to its default reporting
+ // configuration. The reportable change field, if present, SHALL be set to
+ // zero.
+ // Verify special condition to reset the reporting configuration to defaults
+ // if the minimum == 0xFFFF and maximum == 0x0000
+ bool reset = false;
+ if ((newEntry->data.reported.maxInterval == 0x0000) && (newEntry->data.reported.minInterval == 0xFFFF))
+ {
+ // Get the configuration from the default configuration table for this
+ MEMMOVE(&entry, newEntry, sizeof(EmberAfPluginReportingEntry));
+ if (emberAfPluginReportingGetReportingConfigDefaults(&entry))
+ {
+ // Then it must be initialise with the default config - explicity
+ initialize = true;
+ reset = true;
+ }
+ }
+
+ if (index == NULL_INDEX)
+ {
+ return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
+ }
+ else if (initialize)
+ {
+ entry.direction = EMBER_ZCL_REPORTING_DIRECTION_REPORTED;
+ entry.endpoint = newEntry->endpoint;
+ entry.clusterId = newEntry->clusterId;
+ entry.attributeId = newEntry->attributeId;
+ entry.mask = newEntry->mask;
+ entry.manufacturerCode = newEntry->manufacturerCode;
+ if (index < REPORT_TABLE_SIZE)
+ {
+ emAfPluginReportVolatileData[index].lastReportTimeMs = halCommonGetInt32uMillisecondTick();
+ emAfPluginReportVolatileData[index].lastReportValue = 0;
+ }
+ }
+
+ // For new or updated entries, set the intervals and reportable change.
+ // Updated entries will retain all other settings configured previously.
+ if (false == reset)
+ {
+ entry.data.reported.minInterval = newEntry->data.reported.minInterval;
+ entry.data.reported.maxInterval = newEntry->data.reported.maxInterval;
+ entry.data.reported.reportableChange = newEntry->data.reported.reportableChange;
+ }
+ // Give the application a chance to review the configuration that we have
+ // been building up. If the application rejects it, we just do not save the
+ // record. If we were supposed to add a new configuration, it will not be
+ // created. If we were supposed to update an existing configuration, we will
+ // keep the old one and just discard any changes. So, in either case, life
+ // continues unchanged if the application rejects the configuration.
+ status = emberAfPluginReportingConfiguredCallback(&entry);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emAfPluginReportingSetEntry(index, &entry);
+ scheduleTick();
+ }
+ return status;
+}
+
+static EmberAfStatus configureReceivedAttribute(const EmberAfClusterCommand * cmd, EmberAfAttributeId attributeId, uint8_t mask,
uint16_t timeout)
{
- EmberAfPluginReportingEntry entry;
- EmberAfStatus status;
- uint8_t i, index = NULL_INDEX;
- bool initialize = true;
+ EmberAfPluginReportingEntry entry;
+ EmberAfStatus status;
+ uint8_t i, index = NULL_INDEX;
+ bool initialize = true;
- // Check the table for an entry that matches this request and also watch for
- // empty slots along the way. If a report exists, it will be overwritten
- // with the new configuration. Otherwise, a new entry will be created and
- // initialized.
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- emAfPluginReportingGetEntry(i, &entry);
- if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_RECEIVED
- && entry.endpoint == cmd->apsFrame->destinationEndpoint
- && entry.clusterId == cmd->apsFrame->clusterId
- && entry.attributeId == attributeId
- && entry.mask == mask
- && entry.manufacturerCode == cmd->mfgCode
- && entry.data.received.source == cmd->source
- && entry.data.received.endpoint == cmd->apsFrame->sourceEndpoint) {
- initialize = false;
- index = i;
- break;
- } else if (entry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID
- && index == NULL_INDEX) {
- index = i;
+ // Check the table for an entry that matches this request and also watch for
+ // empty slots along the way. If a report exists, it will be overwritten
+ // with the new configuration. Otherwise, a new entry will be created and
+ // initialized.
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ emAfPluginReportingGetEntry(i, &entry);
+ if (entry.direction == EMBER_ZCL_REPORTING_DIRECTION_RECEIVED && entry.endpoint == cmd->apsFrame->destinationEndpoint &&
+ entry.clusterId == cmd->apsFrame->clusterId && entry.attributeId == attributeId && entry.mask == mask &&
+ entry.manufacturerCode == cmd->mfgCode && entry.data.received.source == cmd->source &&
+ entry.data.received.endpoint == cmd->apsFrame->sourceEndpoint)
+ {
+ initialize = false;
+ index = i;
+ break;
+ }
+ else if (entry.endpoint == EMBER_AF_PLUGIN_REPORTING_UNUSED_ENDPOINT_ID && index == NULL_INDEX)
+ {
+ index = i;
+ }
}
- }
- if (index == NULL_INDEX) {
- return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
- } else if (initialize) {
- entry.direction = EMBER_ZCL_REPORTING_DIRECTION_RECEIVED;
- entry.endpoint = cmd->apsFrame->destinationEndpoint;
- entry.clusterId = cmd->apsFrame->clusterId;
- entry.attributeId = attributeId;
- entry.mask = mask;
- entry.manufacturerCode = cmd->mfgCode;
- entry.data.received.source = cmd->source;
- entry.data.received.endpoint = cmd->apsFrame->sourceEndpoint;
- }
+ if (index == NULL_INDEX)
+ {
+ return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
+ }
+ else if (initialize)
+ {
+ entry.direction = EMBER_ZCL_REPORTING_DIRECTION_RECEIVED;
+ entry.endpoint = cmd->apsFrame->destinationEndpoint;
+ entry.clusterId = cmd->apsFrame->clusterId;
+ entry.attributeId = attributeId;
+ entry.mask = mask;
+ entry.manufacturerCode = cmd->mfgCode;
+ entry.data.received.source = cmd->source;
+ entry.data.received.endpoint = cmd->apsFrame->sourceEndpoint;
+ }
- // For new or updated entries, set the timeout. Updated entries will retain
- // all other settings configured previously.
- entry.data.received.timeout = timeout;
+ // For new or updated entries, set the timeout. Updated entries will retain
+ // all other settings configured previously.
+ entry.data.received.timeout = timeout;
- // Give the application a chance to review the configuration that we have
- // been building up. If the application rejects it, we just do not save the
- // record. If we were supposed to add a new configuration, it will not be
- // created. If we were supposed to update an existing configuration, we will
- // keep the old one and just discard any changes. So, in either case, life
- // continues unchanged if the application rejects the configuration. If the
- // application accepts the change, the tick does not have to be rescheduled
- // here because we don't do anything with received reports.
- status = emberAfPluginReportingConfiguredCallback(&entry);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emAfPluginReportingSetEntry(index, &entry);
- }
- return status;
+ // Give the application a chance to review the configuration that we have
+ // been building up. If the application rejects it, we just do not save the
+ // record. If we were supposed to add a new configuration, it will not be
+ // created. If we were supposed to update an existing configuration, we will
+ // keep the old one and just discard any changes. So, in either case, life
+ // continues unchanged if the application rejects the configuration. If the
+ // application accepts the change, the tick does not have to be rescheduled
+ // here because we don't do anything with received reports.
+ status = emberAfPluginReportingConfiguredCallback(&entry);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emAfPluginReportingSetEntry(index, &entry);
+ }
+ return status;
}
-static void putReportableChangeInResp(const EmberAfPluginReportingEntry *entry,
- EmberAfAttributeType dataType)
+static void putReportableChangeInResp(const EmberAfPluginReportingEntry * entry, EmberAfAttributeType dataType)
{
- uint8_t bytes = emberAfGetDataSize(dataType);
- if (entry == NULL) { // default, 0xFF...UL or 0x80...L
- for (; bytes > 0; bytes--) {
- uint8_t b = 0xFF;
- if (emberAfIsTypeSigned(dataType)) {
- b = (bytes == 1 ? 0x80 : 0x00);
- }
- emberAfPutInt8uInResp(b);
+ uint8_t bytes = emberAfGetDataSize(dataType);
+ if (entry == NULL)
+ { // default, 0xFF...UL or 0x80...L
+ for (; bytes > 0; bytes--)
+ {
+ uint8_t b = 0xFF;
+ if (emberAfIsTypeSigned(dataType))
+ {
+ b = (bytes == 1 ? 0x80 : 0x00);
+ }
+ emberAfPutInt8uInResp(b);
+ }
}
- } else { // reportable change value
- uint32_t value = entry->data.reported.reportableChange;
- for (; bytes > 0; bytes--) {
- uint8_t b = BYTE_0(value);
- emberAfPutInt8uInResp(b);
- value >>= 8;
+ else
+ { // reportable change value
+ uint32_t value = entry->data.reported.reportableChange;
+ for (; bytes > 0; bytes--)
+ {
+ uint8_t b = BYTE_0(value);
+ emberAfPutInt8uInResp(b);
+ value >>= 8;
+ }
}
- }
}
// Conditionally add reporting entry.
// This is required to support setting up default reporting entries for
// reportable attributes.
-static bool reportEntryDoesNotExist(const EmberAfPluginReportingEntry* newEntry)
+static bool reportEntryDoesNotExist(const EmberAfPluginReportingEntry * newEntry)
{
- uint8_t i;
- EmberAfPluginReportingEntry entry;
+ uint8_t i;
+ EmberAfPluginReportingEntry entry;
- for (i = 0; i < REPORT_TABLE_SIZE; i++) {
- emAfPluginReportingGetEntry(i, &entry);
- if (emAfPluginReportingDoEntriesMatch(&entry, newEntry)) {
- return false;
+ for (i = 0; i < REPORT_TABLE_SIZE; i++)
+ {
+ emAfPluginReportingGetEntry(i, &entry);
+ if (emAfPluginReportingDoEntriesMatch(&entry, newEntry))
+ {
+ return false;
+ }
}
- }
- return true;
+ return true;
}
-uint8_t emAfPluginReportingConditionallyAddReportingEntry(EmberAfPluginReportingEntry* newEntry)
+uint8_t emAfPluginReportingConditionallyAddReportingEntry(EmberAfPluginReportingEntry * newEntry)
{
- if (reportEntryDoesNotExist(newEntry)) {
- return emAfPluginReportingAddEntry(newEntry);
- }
- return 0;
+ if (reportEntryDoesNotExist(newEntry))
+ {
+ return emAfPluginReportingAddEntry(newEntry);
+ }
+ return 0;
}
diff --git a/src/app/clusters/reporting/reporting.h b/src/app/clusters/reporting/reporting.h
index a28edcd..a9f0893 100644
--- a/src/app/clusters/reporting/reporting.h
+++ b/src/app/clusters/reporting/reporting.h
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Definitions for the Reporting plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
// The default reporting will generate a table that is mandatory
// but user may still allocate some table for adding more reporting over
@@ -48,19 +48,20 @@
#endif
#endif
-typedef struct {
- uint32_t lastReportTimeMs;
- EmberAfDifferenceType lastReportValue;
- bool reportableChange;
+typedef struct
+{
+ uint32_t lastReportTimeMs;
+ EmberAfDifferenceType lastReportValue;
+ bool reportableChange;
} EmAfPluginReportVolatileData;
extern EmAfPluginReportVolatileData emAfPluginReportVolatileData[];
-EmberAfStatus emberAfPluginReportingConfigureReportedAttribute(const EmberAfPluginReportingEntry *newEntry);
-void emAfPluginReportingGetEntry(uint8_t index, EmberAfPluginReportingEntry *result);
-void emAfPluginReportingSetEntry(uint8_t index, EmberAfPluginReportingEntry *value);
-uint8_t emAfPluginReportingAddEntry(EmberAfPluginReportingEntry* newEntry);
+EmberAfStatus emberAfPluginReportingConfigureReportedAttribute(const EmberAfPluginReportingEntry * newEntry);
+void emAfPluginReportingGetEntry(uint8_t index, EmberAfPluginReportingEntry * result);
+void emAfPluginReportingSetEntry(uint8_t index, EmberAfPluginReportingEntry * value);
+uint8_t emAfPluginReportingAddEntry(EmberAfPluginReportingEntry * newEntry);
EmberStatus emAfPluginReportingRemoveEntry(uint8_t index);
-bool emAfPluginReportingDoEntriesMatch(const EmberAfPluginReportingEntry* const entry1,
- const EmberAfPluginReportingEntry* const entry2);
-uint8_t emAfPluginReportingConditionallyAddReportingEntry(EmberAfPluginReportingEntry* newEntry);
+bool emAfPluginReportingDoEntriesMatch(const EmberAfPluginReportingEntry * const entry1,
+ const EmberAfPluginReportingEntry * const entry2);
+uint8_t emAfPluginReportingConditionallyAddReportingEntry(EmberAfPluginReportingEntry * newEntry);
void emberAfPluginReportingLoadReportingConfigDefaults(void);
-bool emberAfPluginReportingGetReportingConfigDefaults(EmberAfPluginReportingEntry *defaultConfiguration);
+bool emberAfPluginReportingGetReportingConfigDefaults(EmberAfPluginReportingEntry * defaultConfiguration);
diff --git a/src/app/clusters/scenes-client/scenes-client.c b/src/app/clusters/scenes-client/scenes-client.c
index 4ad5a3d..a191158 100644
--- a/src/app/clusters/scenes-client/scenes-client.c
+++ b/src/app/clusters/scenes-client/scenes-client.c
@@ -31,169 +31,123 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Scenes Client plugin, which implements the client
- * side of the Scenes cluster.
+ * @brief Routines for the Scenes Client plugin, which
+ *implements the client side of the Scenes cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-#include "../../include/af.h"
#include "scenes-client.h"
+#include "../../include/af.h"
-bool emberAfScenesClusterAddSceneResponseCallback(uint8_t status,
- uint16_t groupId,
- uint8_t sceneId)
+bool emberAfScenesClusterAddSceneResponseCallback(uint8_t status, uint16_t groupId, uint8_t sceneId)
{
- return emberAfPluginScenesClientParseAddSceneResponse(emberAfCurrentCommand(),
- status,
- groupId,
- sceneId);
+ return emberAfPluginScenesClientParseAddSceneResponse(emberAfCurrentCommand(), status, groupId, sceneId);
}
-bool emberAfScenesClusterViewSceneResponseCallback(uint8_t status,
- uint16_t groupId,
- uint8_t sceneId,
- uint16_t transitionTime,
- uint8_t *sceneName,
- uint8_t *extensionFieldSets)
+bool emberAfScenesClusterViewSceneResponseCallback(uint8_t status, uint16_t groupId, uint8_t sceneId, uint16_t transitionTime,
+ uint8_t * sceneName, uint8_t * extensionFieldSets)
{
- return emberAfPluginScenesClientParseViewSceneResponse(emberAfCurrentCommand(),
- status,
- groupId,
- sceneId,
- transitionTime,
- sceneName,
- extensionFieldSets);
+ return emberAfPluginScenesClientParseViewSceneResponse(emberAfCurrentCommand(), status, groupId, sceneId, transitionTime,
+ sceneName, extensionFieldSets);
}
-bool emberAfScenesClusterRemoveSceneResponseCallback(uint8_t status,
- uint16_t groupId,
- uint8_t sceneId)
+bool emberAfScenesClusterRemoveSceneResponseCallback(uint8_t status, uint16_t groupId, uint8_t sceneId)
{
- emberAfScenesClusterPrintln("RX: RemoveSceneResponse 0x%x, 0x%2x, 0x%x",
- status,
- groupId,
- sceneId);
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfScenesClusterPrintln("RX: RemoveSceneResponse 0x%x, 0x%2x, 0x%x", status, groupId, sceneId);
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
-bool emberAfScenesClusterRemoveAllScenesResponseCallback(uint8_t status,
- uint16_t groupId)
+bool emberAfScenesClusterRemoveAllScenesResponseCallback(uint8_t status, uint16_t groupId)
{
- emberAfScenesClusterPrintln("RX: RemoveAllScenesResponse 0x%x, 0x%2x",
- status,
- groupId);
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfScenesClusterPrintln("RX: RemoveAllScenesResponse 0x%x, 0x%2x", status, groupId);
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
-bool emberAfScenesClusterStoreSceneResponseCallback(uint8_t status,
- uint16_t groupId,
+bool emberAfScenesClusterStoreSceneResponseCallback(uint8_t status, uint16_t groupId, uint8_t sceneId)
+{
+ emberAfScenesClusterPrintln("RX: StoreSceneResponse 0x%x, 0x%2x, 0x%x", status, groupId, sceneId);
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+}
+
+bool emberAfScenesClusterGetSceneMembershipResponseCallback(uint8_t status, uint8_t capacity, uint16_t groupId, uint8_t sceneCount,
+ uint8_t * sceneList)
+{
+ emberAfScenesClusterPrint("RX: GetSceneMembershipResponse 0x%x, 0x%x, 0x%2x", status, capacity, groupId);
+
+ // Scene count and the scene list only appear in the payload if the status is
+ // SUCCESS.
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ uint8_t i;
+ emberAfScenesClusterPrint(", 0x%x,", sceneCount);
+ for (i = 0; i < sceneCount; i++)
+ {
+ emberAfScenesClusterPrint(" [0x%x]", sceneList[i]);
+ }
+ }
+
+ emberAfScenesClusterPrintln("");
+ emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
+ return true;
+}
+
+bool emberAfPluginScenesClientParseAddSceneResponse(const EmberAfClusterCommand * cmd, uint8_t status, uint16_t groupId,
uint8_t sceneId)
{
- emberAfScenesClusterPrintln("RX: StoreSceneResponse 0x%x, 0x%2x, 0x%x",
- status,
- groupId,
- sceneId);
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ bool enhanced = (cmd->commandId == ZCL_ENHANCED_ADD_SCENE_COMMAND_ID);
+ emberAfScenesClusterPrintln("RX: %pAddSceneResponse 0x%x, 0x%2x, 0x%x", (enhanced ? "Enhanced" : ""), status, groupId, sceneId);
+ emberAfSendDefaultResponse(cmd, EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
-bool emberAfScenesClusterGetSceneMembershipResponseCallback(uint8_t status,
- uint8_t capacity,
- uint16_t groupId,
- uint8_t sceneCount,
- uint8_t *sceneList)
+bool emberAfPluginScenesClientParseViewSceneResponse(const EmberAfClusterCommand * cmd, uint8_t status, uint16_t groupId,
+ uint8_t sceneId, uint16_t transitionTime, const uint8_t * sceneName,
+ const uint8_t * extensionFieldSets)
{
- emberAfScenesClusterPrint("RX: GetSceneMembershipResponse 0x%x, 0x%x, 0x%2x",
- status,
- capacity,
- groupId);
+ bool enhanced = (cmd->commandId == ZCL_ENHANCED_VIEW_SCENE_COMMAND_ID);
- // Scene count and the scene list only appear in the payload if the status is
- // SUCCESS.
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- uint8_t i;
- emberAfScenesClusterPrint(", 0x%x,", sceneCount);
- for (i = 0; i < sceneCount; i++) {
- emberAfScenesClusterPrint(" [0x%x]", sceneList[i]);
+ emberAfScenesClusterPrint("RX: %pViewSceneResponse 0x%x, 0x%2x, 0x%x", (enhanced ? "Enhanced" : ""), status, groupId, sceneId);
+
+ // Transition time, scene name, and the extension field sets only appear in
+ // the payload if the status is SUCCESS.
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ uint16_t extensionFieldSetsLen = (emberAfCurrentCommand()->bufLen -
+ (emberAfCurrentCommand()->payloadStartIndex + sizeof(status) + sizeof(groupId) +
+ sizeof(sceneId) + sizeof(transitionTime) + emberAfStringLength(sceneName) + 1));
+ uint16_t extensionFieldSetsIndex = 0;
+
+ emberAfScenesClusterPrint(", 0x%2x, \"", transitionTime);
+ emberAfScenesClusterPrintString(sceneName);
+ emberAfScenesClusterPrint("\",");
+
+ // Each extension field set contains at least a two-byte cluster id and a
+ // one-byte length.
+ while (extensionFieldSetsIndex + 3 <= extensionFieldSetsLen)
+ {
+ EmberAfClusterId clusterId;
+ uint8_t length;
+ clusterId = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex += 2;
+ length = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex++;
+ emberAfScenesClusterPrint(" [0x%2x 0x%x ", clusterId, length);
+ if (extensionFieldSetsIndex + length <= extensionFieldSetsLen)
+ {
+ emberAfScenesClusterPrintBuffer(extensionFieldSets + extensionFieldSetsIndex, length, false);
+ }
+ emberAfScenesClusterPrint("]");
+ emberAfScenesClusterFlush();
+ extensionFieldSetsIndex += length;
+ }
}
- }
- emberAfScenesClusterPrintln("");
- emberAfSendImmediateDefaultResponse(EMBER_ZCL_STATUS_SUCCESS);
- return true;
-}
-
-bool emberAfPluginScenesClientParseAddSceneResponse(const EmberAfClusterCommand *cmd,
- uint8_t status,
- uint16_t groupId,
- uint8_t sceneId)
-{
- bool enhanced = (cmd->commandId == ZCL_ENHANCED_ADD_SCENE_COMMAND_ID);
- emberAfScenesClusterPrintln("RX: %pAddSceneResponse 0x%x, 0x%2x, 0x%x",
- (enhanced ? "Enhanced" : ""),
- status,
- groupId,
- sceneId);
- emberAfSendDefaultResponse(cmd, EMBER_ZCL_STATUS_SUCCESS);
- return true;
-}
-
-bool emberAfPluginScenesClientParseViewSceneResponse(const EmberAfClusterCommand *cmd,
- uint8_t status,
- uint16_t groupId,
- uint8_t sceneId,
- uint16_t transitionTime,
- const uint8_t *sceneName,
- const uint8_t *extensionFieldSets)
-{
- bool enhanced = (cmd->commandId == ZCL_ENHANCED_VIEW_SCENE_COMMAND_ID);
-
- emberAfScenesClusterPrint("RX: %pViewSceneResponse 0x%x, 0x%2x, 0x%x",
- (enhanced ? "Enhanced" : ""),
- status,
- groupId,
- sceneId);
-
- // Transition time, scene name, and the extension field sets only appear in
- // the payload if the status is SUCCESS.
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- uint16_t extensionFieldSetsLen = (emberAfCurrentCommand()->bufLen
- - (emberAfCurrentCommand()->payloadStartIndex
- + sizeof(status)
- + sizeof(groupId)
- + sizeof(sceneId)
- + sizeof(transitionTime)
- + emberAfStringLength(sceneName) + 1));
- uint16_t extensionFieldSetsIndex = 0;
-
- emberAfScenesClusterPrint(", 0x%2x, \"", transitionTime);
- emberAfScenesClusterPrintString(sceneName);
- emberAfScenesClusterPrint("\",");
-
- // Each extension field set contains at least a two-byte cluster id and a
- // one-byte length.
- while (extensionFieldSetsIndex + 3 <= extensionFieldSetsLen) {
- EmberAfClusterId clusterId;
- uint8_t length;
- clusterId = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex += 2;
- length = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex++;
- emberAfScenesClusterPrint(" [0x%2x 0x%x ", clusterId, length);
- if (extensionFieldSetsIndex + length <= extensionFieldSetsLen) {
- emberAfScenesClusterPrintBuffer(extensionFieldSets + extensionFieldSetsIndex, length, false);
- }
- emberAfScenesClusterPrint("]");
- emberAfScenesClusterFlush();
- extensionFieldSetsIndex += length;
- }
- }
-
- emberAfScenesClusterPrintln("");
- emberAfSendDefaultResponse(cmd, EMBER_ZCL_STATUS_SUCCESS);
- return true;
+ emberAfScenesClusterPrintln("");
+ emberAfSendDefaultResponse(cmd, EMBER_ZCL_STATUS_SUCCESS);
+ return true;
}
diff --git a/src/app/clusters/scenes-client/scenes-client.h b/src/app/clusters/scenes-client/scenes-client.h
index 774fcd2..9080ea2 100644
--- a/src/app/clusters/scenes-client/scenes-client.h
+++ b/src/app/clusters/scenes-client/scenes-client.h
@@ -31,21 +31,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Definitions for the Scenes Client plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-bool emberAfPluginScenesClientParseAddSceneResponse(const EmberAfClusterCommand *cmd,
- uint8_t status,
- uint16_t groupId,
+bool emberAfPluginScenesClientParseAddSceneResponse(const EmberAfClusterCommand * cmd, uint8_t status, uint16_t groupId,
uint8_t sceneId);
-bool emberAfPluginScenesClientParseViewSceneResponse(const EmberAfClusterCommand *cmd,
- uint8_t status,
- uint16_t groupId,
- uint8_t sceneId,
- uint16_t transitionTime,
- const uint8_t *sceneName,
- const uint8_t *extensionFieldSets);
+bool emberAfPluginScenesClientParseViewSceneResponse(const EmberAfClusterCommand * cmd, uint8_t status, uint16_t groupId,
+ uint8_t sceneId, uint16_t transitionTime, const uint8_t * sceneName,
+ const uint8_t * extensionFieldSets);
diff --git a/src/app/clusters/scenes/scenes-cli.c b/src/app/clusters/scenes/scenes-cli.c
index 428af22..5cc4a4e 100644
--- a/src/app/clusters/scenes/scenes-cli.c
+++ b/src/app/clusters/scenes/scenes-cli.c
@@ -31,11 +31,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief CLI for the Scenes plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#include "app/framework/include/af.h"
#include "app/util/serial/command-interpreter2.h"
@@ -45,14 +45,14 @@
#if !defined(EMBER_AF_GENERATE_CLI)
EmberCommandEntry emberAfPluginScenesCommands[] = {
- emberCommandEntryAction("print", emAfPluginScenesServerPrintInfo, "", "Print the scenes table."),
- emberCommandEntryAction("clear", emAfPluginScenesServerClear, "", "Clear the scenes table on every endpoint."),
- emberCommandEntryTerminator(),
+ emberCommandEntryAction("print", emAfPluginScenesServerPrintInfo, "", "Print the scenes table."),
+ emberCommandEntryAction("clear", emAfPluginScenesServerClear, "", "Clear the scenes table on every endpoint."),
+ emberCommandEntryTerminator(),
};
#endif // EMBER_AF_GENERATE_CLI
void emAfPluginScenesServerClear(void)
{
- emberAfCorePrintln("Clearing all scenes.");
- emberAfScenesClusterClearSceneTableCallback(EMBER_BROADCAST_ENDPOINT);
+ emberAfCorePrintln("Clearing all scenes.");
+ emberAfScenesClusterClearSceneTableCallback(EMBER_BROADCAST_ENDPOINT);
}
diff --git a/src/app/clusters/scenes/scenes-tokens.h b/src/app/clusters/scenes/scenes-tokens.h
index 5881681..ab52df3 100644
--- a/src/app/clusters/scenes/scenes-tokens.h
+++ b/src/app/clusters/scenes/scenes-tokens.h
@@ -31,32 +31,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Tokens for the Scenes plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
#ifdef EMBER_AF_PLUGIN_SCENES_USE_TOKENS
-#define CREATOR_SCENES_NUM_ENTRIES (0x8723)
+#define CREATOR_SCENES_NUM_ENTRIES (0x8723)
#define NVM3KEY_SCENES_NUM_ENTRIES (NVM3KEY_DOMAIN_ZIGBEE | 0x8723)
-#define CREATOR_SCENES_TABLE (0x8724)
+#define CREATOR_SCENES_TABLE (0x8724)
// This key is used for an indexed token and the subsequent 0x7F keys are also reserved
-#define NVM3KEY_SCENES_TABLE (NVM3KEY_DOMAIN_ZIGBEE | 0x4080)
+#define NVM3KEY_SCENES_TABLE (NVM3KEY_DOMAIN_ZIGBEE | 0x4080)
#ifdef DEFINETYPES
// Include or define any typedef for tokens here
-#endif //DEFINETYPES
+#endif // DEFINETYPES
#ifdef DEFINETOKENS
// Define the actual token storage information here
DEFINE_BASIC_TOKEN(SCENES_NUM_ENTRIES, uint8_t, 0x00)
-DEFINE_INDEXED_TOKEN(SCENES_TABLE,
- EmberAfSceneTableEntry,
- EMBER_AF_PLUGIN_SCENES_TABLE_SIZE,
+DEFINE_INDEXED_TOKEN(SCENES_TABLE, EmberAfSceneTableEntry, EMBER_AF_PLUGIN_SCENES_TABLE_SIZE,
{ EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID })
-#endif //DEFINETOKENS
+#endif // DEFINETOKENS
#endif // EMBER_AF_PLUGIN_SCENES_USE_TOKENS
diff --git a/src/app/clusters/scenes/scenes.c b/src/app/clusters/scenes/scenes.c
index f26442b..178c7f0 100644
--- a/src/app/clusters/scenes/scenes.c
+++ b/src/app/clusters/scenes/scenes.c
@@ -31,19 +31,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
- * @brief Routines for the Scenes plugin, which implements the server side of
- * the Scenes cluster.
+ * @brief Routines for the Scenes plugin, which
+ *implements the server side of the Scenes cluster.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
+#include "scenes.h"
#include "../../include/af.h"
#include "../../util/common.h"
-#include "scenes.h"
#ifdef EMBER_AF_PLUGIN_ZLL_SCENES_SERVER
- #include "../zll-scenes-server/zll-scenes-server.h"
+#include "../zll-scenes-server/zll-scenes-server.h"
#endif
uint8_t emberAfPluginScenesServerEntriesInUse = 0;
@@ -51,1281 +51,1137 @@
EmberAfSceneTableEntry emberAfPluginScenesServerSceneTable[EMBER_AF_PLUGIN_SCENES_TABLE_SIZE];
#endif
-static bool readServerAttribute(uint8_t endpoint,
- EmberAfClusterId clusterId,
- EmberAfAttributeId attributeId,
- const char * name,
- uint8_t *data,
- uint8_t size)
+static bool readServerAttribute(uint8_t endpoint, EmberAfClusterId clusterId, EmberAfAttributeId attributeId, const char * name,
+ uint8_t * data, uint8_t size)
{
- bool success = false;
- if (emberAfContainsServer(endpoint, clusterId)) {
- EmberAfStatus status = emberAfReadServerAttribute(endpoint,
- clusterId,
- attributeId,
- data,
- size);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- success = true;
- } else {
- emberAfScenesClusterPrintln("ERR: %ping %p 0x%x", "read", name, status);
+ bool success = false;
+ if (emberAfContainsServer(endpoint, clusterId))
+ {
+ EmberAfStatus status = emberAfReadServerAttribute(endpoint, clusterId, attributeId, data, size);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ success = true;
+ }
+ else
+ {
+ emberAfScenesClusterPrintln("ERR: %ping %p 0x%x", "read", name, status);
+ }
}
- }
- return success;
+ return success;
}
-static EmberAfStatus writeServerAttribute(uint8_t endpoint,
- EmberAfClusterId clusterId,
- EmberAfAttributeId attributeId,
- const char * name,
- uint8_t *data,
- EmberAfAttributeType type)
+static EmberAfStatus writeServerAttribute(uint8_t endpoint, EmberAfClusterId clusterId, EmberAfAttributeId attributeId,
+ const char * name, uint8_t * data, EmberAfAttributeType type)
{
- EmberAfStatus status = emberAfWriteServerAttribute(endpoint,
- clusterId,
- attributeId,
- data,
- type);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- emberAfScenesClusterPrintln("ERR: %ping %p 0x%x", "writ", name, status);
- }
- return status;
+ EmberAfStatus status = emberAfWriteServerAttribute(endpoint, clusterId, attributeId, data, type);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfScenesClusterPrintln("ERR: %ping %p 0x%x", "writ", name, status);
+ }
+ return status;
}
void emberAfScenesClusterServerInitCallback(uint8_t endpoint)
{
#ifdef EMBER_AF_PLUGIN_SCENES_NAME_SUPPORT
- {
- // The high bit of Name Support indicates whether scene names are supported.
- uint8_t nameSupport = BIT(7);
- writeServerAttribute(endpoint,
- ZCL_SCENES_CLUSTER_ID,
- ZCL_SCENE_NAME_SUPPORT_ATTRIBUTE_ID,
- "name support",
- (uint8_t *)&nameSupport,
- ZCL_BITMAP8_ATTRIBUTE_TYPE);
- }
+ {
+ // The high bit of Name Support indicates whether scene names are supported.
+ uint8_t nameSupport = BIT(7);
+ writeServerAttribute(endpoint, ZCL_SCENES_CLUSTER_ID, ZCL_SCENE_NAME_SUPPORT_ATTRIBUTE_ID, "name support",
+ (uint8_t *) &nameSupport, ZCL_BITMAP8_ATTRIBUTE_TYPE);
+ }
#endif
#if !defined(EMBER_AF_PLUGIN_SCENES_USE_TOKENS) || defined(EZSP_HOST)
- {
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- EmberAfSceneTableEntry entry;
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
- emberAfPluginScenesServerSaveSceneEntry(entry, i);
+ {
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ EmberAfSceneTableEntry entry;
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
+ emberAfPluginScenesServerSaveSceneEntry(entry, i);
+ }
+ emberAfPluginScenesServerSetNumSceneEntriesInUse(0);
}
- emberAfPluginScenesServerSetNumSceneEntriesInUse(0);
- }
#endif
- emberAfScenesSetSceneCountAttribute(endpoint,
- emberAfPluginScenesServerNumSceneEntriesInUse());
+ emberAfScenesSetSceneCountAttribute(endpoint, emberAfPluginScenesServerNumSceneEntriesInUse());
}
-EmberAfStatus emberAfScenesSetSceneCountAttribute(uint8_t endpoint,
- uint8_t newCount)
+EmberAfStatus emberAfScenesSetSceneCountAttribute(uint8_t endpoint, uint8_t newCount)
{
- return writeServerAttribute(endpoint,
- ZCL_SCENES_CLUSTER_ID,
- ZCL_SCENE_COUNT_ATTRIBUTE_ID,
- "scene count",
- (uint8_t *)&newCount,
- ZCL_INT8U_ATTRIBUTE_TYPE);
-}
-
-EmberAfStatus emberAfScenesMakeValid(uint8_t endpoint,
- uint8_t sceneId,
- uint16_t groupId)
-{
- EmberAfStatus status;
- bool valid = true;
-
- // scene ID
- status = writeServerAttribute(endpoint,
- ZCL_SCENES_CLUSTER_ID,
- ZCL_CURRENT_SCENE_ATTRIBUTE_ID,
- "current scene",
- (uint8_t *)&sceneId,
+ return writeServerAttribute(endpoint, ZCL_SCENES_CLUSTER_ID, ZCL_SCENE_COUNT_ATTRIBUTE_ID, "scene count", (uint8_t *) &newCount,
ZCL_INT8U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- }
+}
- // group ID
- status = writeServerAttribute(endpoint,
- ZCL_SCENES_CLUSTER_ID,
- ZCL_CURRENT_GROUP_ATTRIBUTE_ID,
- "current group",
- (uint8_t *)&groupId,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- if (status != EMBER_ZCL_STATUS_SUCCESS) {
- return status;
- }
+EmberAfStatus emberAfScenesMakeValid(uint8_t endpoint, uint8_t sceneId, uint16_t groupId)
+{
+ EmberAfStatus status;
+ bool valid = true;
- status = writeServerAttribute(endpoint,
- ZCL_SCENES_CLUSTER_ID,
- ZCL_SCENE_VALID_ATTRIBUTE_ID,
- "scene valid",
- (uint8_t *)&valid,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
- return status;
+ // scene ID
+ status = writeServerAttribute(endpoint, ZCL_SCENES_CLUSTER_ID, ZCL_CURRENT_SCENE_ATTRIBUTE_ID, "current scene",
+ (uint8_t *) &sceneId, ZCL_INT8U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+
+ // group ID
+ status = writeServerAttribute(endpoint, ZCL_SCENES_CLUSTER_ID, ZCL_CURRENT_GROUP_ATTRIBUTE_ID, "current group",
+ (uint8_t *) &groupId, ZCL_INT16U_ATTRIBUTE_TYPE);
+ if (status != EMBER_ZCL_STATUS_SUCCESS)
+ {
+ return status;
+ }
+
+ status = writeServerAttribute(endpoint, ZCL_SCENES_CLUSTER_ID, ZCL_SCENE_VALID_ATTRIBUTE_ID, "scene valid", (uint8_t *) &valid,
+ ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ return status;
}
EmberAfStatus emberAfScenesClusterMakeInvalidCallback(uint8_t endpoint)
{
- bool valid = false;
- return writeServerAttribute(endpoint,
- ZCL_SCENES_CLUSTER_ID,
- ZCL_SCENE_VALID_ATTRIBUTE_ID,
- "scene valid",
- (uint8_t *)&valid,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ bool valid = false;
+ return writeServerAttribute(endpoint, ZCL_SCENES_CLUSTER_ID, ZCL_SCENE_VALID_ATTRIBUTE_ID, "scene valid", (uint8_t *) &valid,
+ ZCL_BOOLEAN_ATTRIBUTE_TYPE);
}
void emAfPluginScenesServerPrintInfo(void)
{
- uint8_t i;
- EmberAfSceneTableEntry entry;
- emberAfCorePrintln("using 0x%x out of 0x%x table slots",
- emberAfPluginScenesServerNumSceneEntriesInUse(),
- EMBER_AF_PLUGIN_SCENES_TABLE_SIZE);
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- emberAfCorePrint("%x: ", i);
- if (entry.endpoint != EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID) {
- emberAfCorePrint("ep %x grp %2x scene %x tt %d",
- entry.endpoint,
- entry.groupId,
- entry.sceneId,
- entry.transitionTime);
- emberAfCorePrint(".%d", entry.transitionTime100ms);
+ uint8_t i;
+ EmberAfSceneTableEntry entry;
+ emberAfCorePrintln("using 0x%x out of 0x%x table slots", emberAfPluginScenesServerNumSceneEntriesInUse(),
+ EMBER_AF_PLUGIN_SCENES_TABLE_SIZE);
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ emberAfCorePrint("%x: ", i);
+ if (entry.endpoint != EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID)
+ {
+ emberAfCorePrint("ep %x grp %2x scene %x tt %d", entry.endpoint, entry.groupId, entry.sceneId, entry.transitionTime);
+ emberAfCorePrint(".%d", entry.transitionTime100ms);
#ifdef EMBER_AF_PLUGIN_SCENES_NAME_SUPPORT
- emberAfCorePrint(" name(%x)\"", emberAfStringLength(entry.name));
- emberAfCorePrintString(entry.name);
- emberAfCorePrint("\"");
+ emberAfCorePrint(" name(%x)\"", emberAfStringLength(entry.name));
+ emberAfCorePrintString(entry.name);
+ emberAfCorePrint("\"");
#endif
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
- emberAfCorePrint(" on/off %x", entry.onOffValue);
+ emberAfCorePrint(" on/off %x", entry.onOffValue);
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
- emberAfCorePrint(" lvl %x", entry.currentLevelValue);
+ emberAfCorePrint(" lvl %x", entry.currentLevelValue);
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
- emberAfCorePrint(" therm %2x %2x %x",
- entry.occupiedCoolingSetpointValue,
- entry.occupiedHeatingSetpointValue,
- entry.systemModeValue);
+ emberAfCorePrint(" therm %2x %2x %x", entry.occupiedCoolingSetpointValue, entry.occupiedHeatingSetpointValue,
+ entry.systemModeValue);
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
- emberAfCorePrint(" color %2x %2x",
- entry.currentXValue,
- entry.currentYValue);
- emberAfCorePrint(" %2x %x %x %x %2x",
- entry.enhancedCurrentHueValue,
- entry.currentSaturationValue,
- entry.colorLoopActiveValue,
- entry.colorLoopDirectionValue,
- entry.colorLoopTimeValue,
- entry.colorTemperatureMiredsValue);
- emberAfCoreFlush();
-#endif //ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+ emberAfCorePrint(" color %2x %2x", entry.currentXValue, entry.currentYValue);
+ emberAfCorePrint(" %2x %x %x %x %2x", entry.enhancedCurrentHueValue, entry.currentSaturationValue,
+ entry.colorLoopActiveValue, entry.colorLoopDirectionValue, entry.colorLoopTimeValue,
+ entry.colorTemperatureMiredsValue);
+ emberAfCoreFlush();
+#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
- emberAfCorePrint(" door %x", entry.lockStateValue);
+ emberAfCorePrint(" door %x", entry.lockStateValue);
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
- emberAfCorePrint(" window %x %x",
- entry.currentPositionLiftPercentageValue,
- entry.currentPositionTiltPercentageValue);
+ emberAfCorePrint(" window %x %x", entry.currentPositionLiftPercentageValue, entry.currentPositionTiltPercentageValue);
#endif
+ }
+ emberAfCorePrintln("");
}
- emberAfCorePrintln("");
- }
}
-bool emberAfScenesClusterAddSceneCallback(uint16_t groupId,
- uint8_t sceneId,
- uint16_t transitionTime,
- uint8_t *sceneName,
- uint8_t *extensionFieldSets)
+bool emberAfScenesClusterAddSceneCallback(uint16_t groupId, uint8_t sceneId, uint16_t transitionTime, uint8_t * sceneName,
+ uint8_t * extensionFieldSets)
{
- return emberAfPluginScenesServerParseAddScene(emberAfCurrentCommand(),
- groupId,
- sceneId,
- transitionTime,
- sceneName,
- extensionFieldSets);
+ return emberAfPluginScenesServerParseAddScene(emberAfCurrentCommand(), groupId, sceneId, transitionTime, sceneName,
+ extensionFieldSets);
}
bool emberAfScenesClusterViewSceneCallback(uint16_t groupId, uint8_t sceneId)
{
- return emberAfPluginScenesServerParseViewScene(emberAfCurrentCommand(),
- groupId,
- sceneId);
+ return emberAfPluginScenesServerParseViewScene(emberAfCurrentCommand(), groupId, sceneId);
}
bool emberAfScenesClusterRemoveSceneCallback(uint16_t groupId, uint8_t sceneId)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
- EmberStatus sendStatus;
+ EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
+ EmberStatus sendStatus;
- emberAfScenesClusterPrintln("RX: RemoveScene 0x%2x, 0x%x", groupId, sceneId);
+ emberAfScenesClusterPrintln("RX: RemoveScene 0x%2x, 0x%x", groupId, sceneId);
- // If a group id is specified but this endpoint isn't in it, take no action.
- if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID
- && !emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(),
- groupId)) {
- status = EMBER_ZCL_STATUS_INVALID_FIELD;
- } else {
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- EmberAfSceneTableEntry entry;
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == emberAfCurrentEndpoint()
- && entry.groupId == groupId
- && entry.sceneId == sceneId) {
- entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
- emberAfPluginScenesServerSaveSceneEntry(entry, i);
- emberAfPluginScenesServerDecrNumSceneEntriesInUse();
- emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(),
- emberAfPluginScenesServerNumSceneEntriesInUse());
- status = EMBER_ZCL_STATUS_SUCCESS;
- break;
- }
+ // If a group id is specified but this endpoint isn't in it, take no action.
+ if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID &&
+ !emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(), groupId))
+ {
+ status = EMBER_ZCL_STATUS_INVALID_FIELD;
}
- }
-
- // Remove Scene commands are only responded to when they are addressed to a
- // single device.
- if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST
- || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY) {
- emberAfFillCommandScenesClusterRemoveSceneResponse(status,
- groupId,
- sceneId);
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x",
- "remove_scene",
- sendStatus);
+ else
+ {
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ EmberAfSceneTableEntry entry;
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId && entry.sceneId == sceneId)
+ {
+ entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
+ emberAfPluginScenesServerSaveSceneEntry(entry, i);
+ emberAfPluginScenesServerDecrNumSceneEntriesInUse();
+ emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ break;
+ }
+ }
}
- }
- return true;
+
+ // Remove Scene commands are only responded to when they are addressed to a
+ // single device.
+ if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
+ {
+ emberAfFillCommandScenesClusterRemoveSceneResponse(status, groupId, sceneId);
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "remove_scene", sendStatus);
+ }
+ }
+ return true;
}
bool emberAfScenesClusterRemoveAllScenesCallback(uint16_t groupId)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_INVALID_FIELD;
- EmberStatus sendStatus;
+ EmberAfStatus status = EMBER_ZCL_STATUS_INVALID_FIELD;
+ EmberStatus sendStatus;
- emberAfScenesClusterPrintln("RX: RemoveAllScenes 0x%2x", groupId);
+ emberAfScenesClusterPrintln("RX: RemoveAllScenes 0x%2x", groupId);
- if (groupId == ZCL_SCENES_GLOBAL_SCENE_GROUP_ID
- || emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(),
- groupId)) {
- uint8_t i;
- status = EMBER_ZCL_STATUS_SUCCESS;
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- EmberAfSceneTableEntry entry;
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == emberAfCurrentEndpoint()
- && entry.groupId == groupId) {
- entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
- emberAfPluginScenesServerSaveSceneEntry(entry, i);
- emberAfPluginScenesServerDecrNumSceneEntriesInUse();
- }
+ if (groupId == ZCL_SCENES_GLOBAL_SCENE_GROUP_ID ||
+ emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(), groupId))
+ {
+ uint8_t i;
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ EmberAfSceneTableEntry entry;
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId)
+ {
+ entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
+ emberAfPluginScenesServerSaveSceneEntry(entry, i);
+ emberAfPluginScenesServerDecrNumSceneEntriesInUse();
+ }
+ }
+ emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
}
- emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(),
- emberAfPluginScenesServerNumSceneEntriesInUse());
- }
- // Remove All Scenes commands are only responded to when they are addressed
- // to a single device.
- if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST
- || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY) {
- emberAfFillCommandScenesClusterRemoveAllScenesResponse(status, groupId);
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x",
- "remove_all_scenes",
- sendStatus);
+ // Remove All Scenes commands are only responded to when they are addressed
+ // to a single device.
+ if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
+ {
+ emberAfFillCommandScenesClusterRemoveAllScenesResponse(status, groupId);
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "remove_all_scenes", sendStatus);
+ }
}
- }
- return true;
+ return true;
}
bool emberAfScenesClusterStoreSceneCallback(uint16_t groupId, uint8_t sceneId)
{
- EmberAfStatus status;
- EmberStatus sendStatus;
- emberAfScenesClusterPrintln("RX: StoreScene 0x%2x, 0x%x", groupId, sceneId);
- status = emberAfScenesClusterStoreCurrentSceneCallback(emberAfCurrentEndpoint(),
- groupId,
- sceneId);
+ EmberAfStatus status;
+ EmberStatus sendStatus;
+ emberAfScenesClusterPrintln("RX: StoreScene 0x%2x, 0x%x", groupId, sceneId);
+ status = emberAfScenesClusterStoreCurrentSceneCallback(emberAfCurrentEndpoint(), groupId, sceneId);
- // Store Scene commands are only responded to when they are addressed to a
- // single device.
- if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST
- || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY) {
- emberAfFillCommandScenesClusterStoreSceneResponse(status, groupId, sceneId);
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x",
- "store_scene",
- sendStatus);
+ // Store Scene commands are only responded to when they are addressed to a
+ // single device.
+ if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY)
+ {
+ emberAfFillCommandScenesClusterStoreSceneResponse(status, groupId, sceneId);
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "store_scene", sendStatus);
+ }
}
- }
- return true;
+ return true;
}
-bool emberAfScenesClusterRecallSceneCallback(uint16_t groupId,
- uint8_t sceneId,
- uint16_t transitionTime)
+bool emberAfScenesClusterRecallSceneCallback(uint16_t groupId, uint8_t sceneId, uint16_t transitionTime)
{
- // NOTE: TransitionTime field in the RecallScene command is currently
- // ignored. Per Zigbee Alliance ZCL 7 (07-5123-07):
- //
- // "The transition time determines how long the tranition takes from the
- // old cluster state to the new cluster state. It is recommended that, where
- // possible (e.g., it is not possible for attributes with Boolean type),
- // a gradual transition SHOULD take place from the old to the new state
- // over this time. However, the exact transition is manufacturer dependent."
- //
- // The manufacturer-dependent implementation here is to immediately set
- // all attributes to their scene-specified values, without regard to the
- // value of TransitionTime.
+ // NOTE: TransitionTime field in the RecallScene command is currently
+ // ignored. Per Zigbee Alliance ZCL 7 (07-5123-07):
+ //
+ // "The transition time determines how long the tranition takes from the
+ // old cluster state to the new cluster state. It is recommended that, where
+ // possible (e.g., it is not possible for attributes with Boolean type),
+ // a gradual transition SHOULD take place from the old to the new state
+ // over this time. However, the exact transition is manufacturer dependent."
+ //
+ // The manufacturer-dependent implementation here is to immediately set
+ // all attributes to their scene-specified values, without regard to the
+ // value of TransitionTime.
- EmberAfStatus status;
- EmberStatus sendStatus;
- emberAfScenesClusterPrintln("RX: RecallScene 0x%2x, 0x%x", groupId, sceneId);
- status = emberAfScenesClusterRecallSavedSceneCallback(emberAfCurrentEndpoint(),
- groupId,
- sceneId);
+ EmberAfStatus status;
+ EmberStatus sendStatus;
+ emberAfScenesClusterPrintln("RX: RecallScene 0x%2x, 0x%x", groupId, sceneId);
+ status = emberAfScenesClusterRecallSavedSceneCallback(emberAfCurrentEndpoint(), groupId, sceneId);
#ifdef EMBER_AF_PLUGIN_ZLL_SCENES_SERVER
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- emberAfPluginZllScenesServerRecallSceneZllExtensions(emberAfCurrentEndpoint());
- }
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ emberAfPluginZllScenesServerRecallSceneZllExtensions(emberAfCurrentEndpoint());
+ }
#endif
- sendStatus = emberAfSendImmediateDefaultResponse(status);
- if (EMBER_SUCCESS != sendStatus) {
- emberAfScenesClusterPrintln("Scenes: failed to send %s: 0x%x",
- "default_response",
- sendStatus);
- }
- return true;
+ sendStatus = emberAfSendImmediateDefaultResponse(status);
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfScenesClusterPrintln("Scenes: failed to send %s: 0x%x", "default_response", sendStatus);
+ }
+ return true;
}
bool emberAfScenesClusterGetSceneMembershipCallback(uint16_t groupId)
{
- EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
- EmberStatus sendStatus;
- uint8_t sceneCount = 0;
+ EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS;
+ EmberStatus sendStatus;
+ uint8_t sceneCount = 0;
- emberAfScenesClusterPrintln("RX: GetSceneMembership 0x%2x", groupId);
+ emberAfScenesClusterPrintln("RX: GetSceneMembership 0x%2x", groupId);
- if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID
- && !emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(),
- groupId)) {
- status = EMBER_ZCL_STATUS_INVALID_FIELD;
- }
-
- // The status, capacity, and group id are always included in the response, but
- // the scene count and scene list are only included if the group id matched.
- emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND
- | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_RESPONSES),
- ZCL_SCENES_CLUSTER_ID,
- ZCL_GET_SCENE_MEMBERSHIP_RESPONSE_COMMAND_ID,
- "uuv",
- status,
- (EMBER_AF_PLUGIN_SCENES_TABLE_SIZE
- - emberAfPluginScenesServerNumSceneEntriesInUse()), // capacity
- groupId);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- uint8_t i, sceneList[EMBER_AF_PLUGIN_SCENES_TABLE_SIZE];
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- EmberAfSceneTableEntry entry;
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == emberAfCurrentEndpoint()
- && entry.groupId == groupId) {
- sceneList[sceneCount] = entry.sceneId;
- sceneCount++;
- }
+ if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID &&
+ !emberAfGroupsClusterEndpointInGroupCallback(emberAfCurrentEndpoint(), groupId))
+ {
+ status = EMBER_ZCL_STATUS_INVALID_FIELD;
}
- emberAfPutInt8uInResp(sceneCount);
- for (i = 0; i < sceneCount; i++) {
- emberAfPutInt8uInResp(sceneList[i]);
- }
- }
- // Get Scene Membership commands are only responded to when they are
- // addressed to a single device or when an entry in the table matches.
- if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST
- || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY
- || sceneCount != 0) {
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x",
- "get_scene_membership",
- sendStatus);
+ // The status, capacity, and group id are always included in the response, but
+ // the scene count and scene list are only included if the group id matched.
+ emberAfFillExternalBuffer(
+ (ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT | EMBER_AF_DEFAULT_RESPONSE_POLICY_RESPONSES),
+ ZCL_SCENES_CLUSTER_ID, ZCL_GET_SCENE_MEMBERSHIP_RESPONSE_COMMAND_ID, "uuv", status,
+ (EMBER_AF_PLUGIN_SCENES_TABLE_SIZE - emberAfPluginScenesServerNumSceneEntriesInUse()), // capacity
+ groupId);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ uint8_t i, sceneList[EMBER_AF_PLUGIN_SCENES_TABLE_SIZE];
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ EmberAfSceneTableEntry entry;
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == emberAfCurrentEndpoint() && entry.groupId == groupId)
+ {
+ sceneList[sceneCount] = entry.sceneId;
+ sceneCount++;
+ }
+ }
+ emberAfPutInt8uInResp(sceneCount);
+ for (i = 0; i < sceneCount; i++)
+ {
+ emberAfPutInt8uInResp(sceneList[i]);
+ }
}
- }
- return true;
+
+ // Get Scene Membership commands are only responded to when they are
+ // addressed to a single device or when an entry in the table matches.
+ if (emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST || emberAfCurrentCommand()->type == EMBER_INCOMING_UNICAST_REPLY ||
+ sceneCount != 0)
+ {
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "get_scene_membership", sendStatus);
+ }
+ }
+ return true;
}
-EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(uint8_t endpoint,
- uint16_t groupId,
- uint8_t sceneId)
+EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(uint8_t endpoint, uint16_t groupId, uint8_t sceneId)
{
- EmberAfSceneTableEntry entry;
- uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;
+ EmberAfSceneTableEntry entry;
+ uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;
- // If a group id is specified but this endpoint isn't in it, take no action.
- if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID
- && !emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId)) {
- return EMBER_ZCL_STATUS_INVALID_FIELD;
- }
-
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == endpoint
- && entry.groupId == groupId
- && entry.sceneId == sceneId) {
- index = i;
- break;
- } else if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX
- && entry.endpoint == EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID) {
- index = i;
+ // If a group id is specified but this endpoint isn't in it, take no action.
+ if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID && !emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId))
+ {
+ return EMBER_ZCL_STATUS_INVALID_FIELD;
}
- }
- // If the target index is still zero, the table is full.
- if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX) {
- return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
- }
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
+ {
+ index = i;
+ break;
+ }
+ else if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX && entry.endpoint == EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID)
+ {
+ index = i;
+ }
+ }
- emberAfPluginScenesServerRetrieveSceneEntry(entry, index);
+ // If the target index is still zero, the table is full.
+ if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX)
+ {
+ return EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
+ }
- // When creating a new entry or refreshing an existing one, the extension
- // fields are updated with the current state of other clusters on the device.
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, index);
+
+ // When creating a new entry or refreshing an existing one, the extension
+ // fields are updated with the current state of other clusters on the device.
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
- entry.hasOnOffValue = readServerAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- "on/off",
- (uint8_t *)&entry.onOffValue,
- sizeof(entry.onOffValue));
+ entry.hasOnOffValue = readServerAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, "on/off",
+ (uint8_t *) &entry.onOffValue, sizeof(entry.onOffValue));
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
- entry.hasCurrentLevelValue = readServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- "current level",
- (uint8_t *)&entry.currentLevelValue,
- sizeof(entry.currentLevelValue));
+ entry.hasCurrentLevelValue =
+ readServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, "current level",
+ (uint8_t *) &entry.currentLevelValue, sizeof(entry.currentLevelValue));
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
- entry.hasOccupiedCoolingSetpointValue = readServerAttribute(endpoint,
- ZCL_THERMOSTAT_CLUSTER_ID,
- ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID,
- "occupied cooling setpoint",
- (uint8_t *)&entry.occupiedCoolingSetpointValue,
- sizeof(entry.occupiedCoolingSetpointValue));
- entry.hasOccupiedHeatingSetpointValue = readServerAttribute(endpoint,
- ZCL_THERMOSTAT_CLUSTER_ID,
- ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID,
- "occupied heating setpoint",
- (uint8_t *)&entry.occupiedHeatingSetpointValue,
- sizeof(entry.occupiedHeatingSetpointValue));
- entry.hasSystemModeValue = readServerAttribute(endpoint,
- ZCL_THERMOSTAT_CLUSTER_ID,
- ZCL_SYSTEM_MODE_ATTRIBUTE_ID,
- "system mode",
- (uint8_t *)&entry.systemModeValue,
- sizeof(entry.systemModeValue));
+ entry.hasOccupiedCoolingSetpointValue = readServerAttribute(
+ endpoint, ZCL_THERMOSTAT_CLUSTER_ID, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID, "occupied cooling setpoint",
+ (uint8_t *) &entry.occupiedCoolingSetpointValue, sizeof(entry.occupiedCoolingSetpointValue));
+ entry.hasOccupiedHeatingSetpointValue = readServerAttribute(
+ endpoint, ZCL_THERMOSTAT_CLUSTER_ID, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID, "occupied heating setpoint",
+ (uint8_t *) &entry.occupiedHeatingSetpointValue, sizeof(entry.occupiedHeatingSetpointValue));
+ entry.hasSystemModeValue = readServerAttribute(endpoint, ZCL_THERMOSTAT_CLUSTER_ID, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, "system mode",
+ (uint8_t *) &entry.systemModeValue, sizeof(entry.systemModeValue));
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
- entry.hasCurrentXValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
- "current x",
- (uint8_t *)&entry.currentXValue,
- sizeof(entry.currentXValue));
- entry.hasCurrentYValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
- "current y",
- (uint8_t *)&entry.currentYValue,
- sizeof(entry.currentYValue));
- entry.hasEnhancedCurrentHueValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_ENHANCED_CURRENT_HUE_ATTRIBUTE_ID,
- "enhanced current hue",
- (uint8_t *)&entry.enhancedCurrentHueValue,
- sizeof(entry.enhancedCurrentHueValue));
- entry.hasCurrentSaturationValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
- "current saturation",
- (uint8_t *)&entry.currentSaturationValue,
- sizeof(entry.currentSaturationValue));
- entry.hasColorLoopActiveValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_LOOP_ACTIVE_ATTRIBUTE_ID,
- "color loop active",
- (uint8_t *)&entry.colorLoopActiveValue,
- sizeof(entry.colorLoopActiveValue));
- entry.hasColorLoopDirectionValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_LOOP_DIRECTION_ATTRIBUTE_ID,
- "color loop direction",
- (uint8_t *)&entry.colorLoopDirectionValue,
- sizeof(entry.colorLoopDirectionValue));
- entry.hasColorLoopTimeValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_LOOP_TIME_ATTRIBUTE_ID,
- "color loop time",
- (uint8_t *)&entry.colorLoopTimeValue,
- sizeof(entry.colorLoopTimeValue));
- entry.hasColorTemperatureMiredsValue = readServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
- "color temp mireds",
- (uint8_t *)&entry.colorTemperatureMiredsValue,
- sizeof(entry.colorTemperatureMiredsValue));
-#endif //ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+ entry.hasCurrentXValue = readServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
+ "current x", (uint8_t *) &entry.currentXValue, sizeof(entry.currentXValue));
+ entry.hasCurrentYValue = readServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
+ "current y", (uint8_t *) &entry.currentYValue, sizeof(entry.currentYValue));
+ entry.hasEnhancedCurrentHueValue = readServerAttribute(
+ endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_ENHANCED_CURRENT_HUE_ATTRIBUTE_ID, "enhanced current hue",
+ (uint8_t *) &entry.enhancedCurrentHueValue, sizeof(entry.enhancedCurrentHueValue));
+ entry.hasCurrentSaturationValue =
+ readServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
+ "current saturation", (uint8_t *) &entry.currentSaturationValue, sizeof(entry.currentSaturationValue));
+ entry.hasColorLoopActiveValue =
+ readServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_LOOP_ACTIVE_ATTRIBUTE_ID,
+ "color loop active", (uint8_t *) &entry.colorLoopActiveValue, sizeof(entry.colorLoopActiveValue));
+ entry.hasColorLoopDirectionValue = readServerAttribute(
+ endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_LOOP_DIRECTION_ATTRIBUTE_ID, "color loop direction",
+ (uint8_t *) &entry.colorLoopDirectionValue, sizeof(entry.colorLoopDirectionValue));
+ entry.hasColorLoopTimeValue =
+ readServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_LOOP_TIME_ATTRIBUTE_ID,
+ "color loop time", (uint8_t *) &entry.colorLoopTimeValue, sizeof(entry.colorLoopTimeValue));
+ entry.hasColorTemperatureMiredsValue = readServerAttribute(
+ endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID, "color temp mireds",
+ (uint8_t *) &entry.colorTemperatureMiredsValue, sizeof(entry.colorTemperatureMiredsValue));
+#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
- entry.hasLockStateValue = readServerAttribute(endpoint,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- "lock state",
- (uint8_t *)&entry.lockStateValue,
- sizeof(entry.lockStateValue));
+ entry.hasLockStateValue = readServerAttribute(endpoint, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_LOCK_STATE_ATTRIBUTE_ID, "lock state",
+ (uint8_t *) &entry.lockStateValue, sizeof(entry.lockStateValue));
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
- entry.hasCurrentPositionLiftPercentageValue = readServerAttribute(endpoint,
- ZCL_WINDOW_COVERING_CLUSTER_ID,
- ZCL_CURRENT_LIFT_PERCENTAGE_ATTRIBUTE_ID,
- "current position lift percentage",
- (uint8_t *)&entry.currentPositionLiftPercentageValue,
- sizeof(entry.currentPositionLiftPercentageValue));
- entry.hasCurrentPositionTiltPercentageValue = readServerAttribute(endpoint,
- ZCL_WINDOW_COVERING_CLUSTER_ID,
- ZCL_CURRENT_TILT_PERCENTAGE_ATTRIBUTE_ID,
- "current position tilt percentage",
- (uint8_t *)&entry.currentPositionTiltPercentageValue,
- sizeof(entry.currentPositionTiltPercentageValue));
+ entry.hasCurrentPositionLiftPercentageValue = readServerAttribute(
+ endpoint, ZCL_WINDOW_COVERING_CLUSTER_ID, ZCL_CURRENT_LIFT_PERCENTAGE_ATTRIBUTE_ID, "current position lift percentage",
+ (uint8_t *) &entry.currentPositionLiftPercentageValue, sizeof(entry.currentPositionLiftPercentageValue));
+ entry.hasCurrentPositionTiltPercentageValue = readServerAttribute(
+ endpoint, ZCL_WINDOW_COVERING_CLUSTER_ID, ZCL_CURRENT_TILT_PERCENTAGE_ATTRIBUTE_ID, "current position tilt percentage",
+ (uint8_t *) &entry.currentPositionTiltPercentageValue, sizeof(entry.currentPositionTiltPercentageValue));
#endif
- // When creating a new entry, the name is set to the null string (i.e., the
- // length is set to zero) and the transition time is set to zero. The scene
- // count must be increased and written to the attribute table when adding a
- // new scene. Otherwise, these fields and the count are left alone.
- if (i != index) {
- entry.endpoint = endpoint;
- entry.groupId = groupId;
- entry.sceneId = sceneId;
+ // When creating a new entry, the name is set to the null string (i.e., the
+ // length is set to zero) and the transition time is set to zero. The scene
+ // count must be increased and written to the attribute table when adding a
+ // new scene. Otherwise, these fields and the count are left alone.
+ if (i != index)
+ {
+ entry.endpoint = endpoint;
+ entry.groupId = groupId;
+ entry.sceneId = sceneId;
#ifdef EMBER_AF_PLUGIN_SCENES_NAME_SUPPORT
- entry.name[0] = 0;
+ entry.name[0] = 0;
#endif
- entry.transitionTime = 0;
- entry.transitionTime100ms = 0;
- emberAfPluginScenesServerIncrNumSceneEntriesInUse();
- emberAfScenesSetSceneCountAttribute(endpoint,
- emberAfPluginScenesServerNumSceneEntriesInUse());
- }
+ entry.transitionTime = 0;
+ entry.transitionTime100ms = 0;
+ emberAfPluginScenesServerIncrNumSceneEntriesInUse();
+ emberAfScenesSetSceneCountAttribute(endpoint, emberAfPluginScenesServerNumSceneEntriesInUse());
+ }
- // Save the scene entry and mark is as valid by storing its scene and group
- // ids in the attribute table and setting valid to true.
- emberAfPluginScenesServerSaveSceneEntry(entry, index);
- emberAfScenesMakeValid(endpoint, sceneId, groupId);
- return EMBER_ZCL_STATUS_SUCCESS;
+ // Save the scene entry and mark is as valid by storing its scene and group
+ // ids in the attribute table and setting valid to true.
+ emberAfPluginScenesServerSaveSceneEntry(entry, index);
+ emberAfScenesMakeValid(endpoint, sceneId, groupId);
+ return EMBER_ZCL_STATUS_SUCCESS;
}
-EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(uint8_t endpoint,
- uint16_t groupId,
- uint8_t sceneId)
+EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(uint8_t endpoint, uint16_t groupId, uint8_t sceneId)
{
- if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID
- && !emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId)) {
- return EMBER_ZCL_STATUS_INVALID_FIELD;
- } else {
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- EmberAfSceneTableEntry entry;
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == endpoint
- && entry.groupId == groupId
- && entry.sceneId == sceneId) {
+ if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID && !emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId))
+ {
+ return EMBER_ZCL_STATUS_INVALID_FIELD;
+ }
+ else
+ {
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ EmberAfSceneTableEntry entry;
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
+ {
#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
- if (entry.hasOnOffValue) {
- writeServerAttribute(endpoint,
- ZCL_ON_OFF_CLUSTER_ID,
- ZCL_ON_OFF_ATTRIBUTE_ID,
- "on/off",
- (uint8_t *)&entry.onOffValue,
- ZCL_BOOLEAN_ATTRIBUTE_TYPE);
- }
+ if (entry.hasOnOffValue)
+ {
+ writeServerAttribute(endpoint, ZCL_ON_OFF_CLUSTER_ID, ZCL_ON_OFF_ATTRIBUTE_ID, "on/off",
+ (uint8_t *) &entry.onOffValue, ZCL_BOOLEAN_ATTRIBUTE_TYPE);
+ }
#endif
#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
- if (entry.hasCurrentLevelValue) {
- writeServerAttribute(endpoint,
- ZCL_LEVEL_CONTROL_CLUSTER_ID,
- ZCL_CURRENT_LEVEL_ATTRIBUTE_ID,
- "current level",
- (uint8_t *)&entry.currentLevelValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
+ if (entry.hasCurrentLevelValue)
+ {
+ writeServerAttribute(endpoint, ZCL_LEVEL_CONTROL_CLUSTER_ID, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, "current level",
+ (uint8_t *) &entry.currentLevelValue, ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
#endif
#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
- if (entry.hasOccupiedCoolingSetpointValue) {
- writeServerAttribute(endpoint,
- ZCL_THERMOSTAT_CLUSTER_ID,
- ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID,
- "occupied cooling setpoint",
- (uint8_t *)&entry.occupiedCoolingSetpointValue,
- ZCL_INT16S_ATTRIBUTE_TYPE);
- }
- if (entry.hasOccupiedHeatingSetpointValue) {
- writeServerAttribute(endpoint,
- ZCL_THERMOSTAT_CLUSTER_ID,
- ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID,
- "occupied heating setpoint",
- (uint8_t *)&entry.occupiedHeatingSetpointValue,
- ZCL_INT16S_ATTRIBUTE_TYPE);
- }
- if (entry.hasSystemModeValue) {
- writeServerAttribute(endpoint,
- ZCL_THERMOSTAT_CLUSTER_ID,
- ZCL_SYSTEM_MODE_ATTRIBUTE_ID,
- "system mode",
- (uint8_t *)&entry.systemModeValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
+ if (entry.hasOccupiedCoolingSetpointValue)
+ {
+ writeServerAttribute(endpoint, ZCL_THERMOSTAT_CLUSTER_ID, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID,
+ "occupied cooling setpoint", (uint8_t *) &entry.occupiedCoolingSetpointValue,
+ ZCL_INT16S_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasOccupiedHeatingSetpointValue)
+ {
+ writeServerAttribute(endpoint, ZCL_THERMOSTAT_CLUSTER_ID, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID,
+ "occupied heating setpoint", (uint8_t *) &entry.occupiedHeatingSetpointValue,
+ ZCL_INT16S_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasSystemModeValue)
+ {
+ writeServerAttribute(endpoint, ZCL_THERMOSTAT_CLUSTER_ID, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, "system mode",
+ (uint8_t *) &entry.systemModeValue, ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
#endif
#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
- if (entry.hasCurrentXValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
- "current x",
- (uint8_t *)&entry.currentXValue,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- }
- if (entry.hasCurrentYValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
- "current y",
- (uint8_t *)&entry.currentYValue,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- }
+ if (entry.hasCurrentXValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID,
+ "current x", (uint8_t *) &entry.currentXValue, ZCL_INT16U_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasCurrentYValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID,
+ "current y", (uint8_t *) &entry.currentYValue, ZCL_INT16U_ATTRIBUTE_TYPE);
+ }
- if (entry.hasEnhancedCurrentHueValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_ENHANCED_CURRENT_HUE_ATTRIBUTE_ID,
- "enhanced current hue",
- (uint8_t *)&entry.enhancedCurrentHueValue,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- }
- if (entry.hasCurrentSaturationValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
- "current saturation",
- (uint8_t *)&entry.currentSaturationValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
- if (entry.hasColorLoopActiveValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_LOOP_ACTIVE_ATTRIBUTE_ID,
- "color loop active",
- (uint8_t *)&entry.colorLoopActiveValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
- if (entry.hasColorLoopDirectionValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_LOOP_DIRECTION_ATTRIBUTE_ID,
- "color loop direction",
- (uint8_t *)&entry.colorLoopDirectionValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
- if (entry.hasColorLoopTimeValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_LOOP_TIME_ATTRIBUTE_ID,
- "color loop time",
- (uint8_t *)&entry.colorLoopTimeValue,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- }
- if (entry.hasColorTemperatureMiredsValue) {
- writeServerAttribute(endpoint,
- ZCL_COLOR_CONTROL_CLUSTER_ID,
- ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
- "color temp mireds",
- (uint8_t *)&entry.colorTemperatureMiredsValue,
- ZCL_INT16U_ATTRIBUTE_TYPE);
- }
-#endif //ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+ if (entry.hasEnhancedCurrentHueValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID,
+ ZCL_COLOR_CONTROL_ENHANCED_CURRENT_HUE_ATTRIBUTE_ID, "enhanced current hue",
+ (uint8_t *) &entry.enhancedCurrentHueValue, ZCL_INT16U_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasCurrentSaturationValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
+ "current saturation", (uint8_t *) &entry.currentSaturationValue, ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasColorLoopActiveValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_LOOP_ACTIVE_ATTRIBUTE_ID,
+ "color loop active", (uint8_t *) &entry.colorLoopActiveValue, ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasColorLoopDirectionValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID,
+ ZCL_COLOR_CONTROL_COLOR_LOOP_DIRECTION_ATTRIBUTE_ID, "color loop direction",
+ (uint8_t *) &entry.colorLoopDirectionValue, ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasColorLoopTimeValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_LOOP_TIME_ATTRIBUTE_ID,
+ "color loop time", (uint8_t *) &entry.colorLoopTimeValue, ZCL_INT16U_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasColorTemperatureMiredsValue)
+ {
+ writeServerAttribute(endpoint, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID,
+ "color temp mireds", (uint8_t *) &entry.colorTemperatureMiredsValue,
+ ZCL_INT16U_ATTRIBUTE_TYPE);
+ }
+#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
- if (entry.hasLockStateValue) {
- writeServerAttribute(endpoint,
- ZCL_DOOR_LOCK_CLUSTER_ID,
- ZCL_LOCK_STATE_ATTRIBUTE_ID,
- "lock state",
- (uint8_t *)&entry.lockStateValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
+ if (entry.hasLockStateValue)
+ {
+ writeServerAttribute(endpoint, ZCL_DOOR_LOCK_CLUSTER_ID, ZCL_LOCK_STATE_ATTRIBUTE_ID, "lock state",
+ (uint8_t *) &entry.lockStateValue, ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
#endif
#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
- if (entry.hasCurrentPositionLiftPercentageValue) {
- writeServerAttribute(endpoint,
- ZCL_WINDOW_COVERING_CLUSTER_ID,
- ZCL_CURRENT_LIFT_PERCENTAGE_ATTRIBUTE_ID,
- "current position lift percentage",
- (uint8_t *)&entry.currentPositionLiftPercentageValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
- if (entry.hasCurrentPositionTiltPercentageValue) {
- writeServerAttribute(endpoint,
- ZCL_WINDOW_COVERING_CLUSTER_ID,
- ZCL_CURRENT_TILT_PERCENTAGE_ATTRIBUTE_ID,
- "current position tilt percentage",
- (uint8_t *)&entry.currentPositionTiltPercentageValue,
- ZCL_INT8U_ATTRIBUTE_TYPE);
- }
+ if (entry.hasCurrentPositionLiftPercentageValue)
+ {
+ writeServerAttribute(endpoint, ZCL_WINDOW_COVERING_CLUSTER_ID, ZCL_CURRENT_LIFT_PERCENTAGE_ATTRIBUTE_ID,
+ "current position lift percentage", (uint8_t *) &entry.currentPositionLiftPercentageValue,
+ ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
+ if (entry.hasCurrentPositionTiltPercentageValue)
+ {
+ writeServerAttribute(endpoint, ZCL_WINDOW_COVERING_CLUSTER_ID, ZCL_CURRENT_TILT_PERCENTAGE_ATTRIBUTE_ID,
+ "current position tilt percentage", (uint8_t *) &entry.currentPositionTiltPercentageValue,
+ ZCL_INT8U_ATTRIBUTE_TYPE);
+ }
#endif
- emberAfScenesMakeValid(endpoint, sceneId, groupId);
- return EMBER_ZCL_STATUS_SUCCESS;
- }
+ emberAfScenesMakeValid(endpoint, sceneId, groupId);
+ return EMBER_ZCL_STATUS_SUCCESS;
+ }
+ }
}
- }
- return EMBER_ZCL_STATUS_NOT_FOUND;
+ return EMBER_ZCL_STATUS_NOT_FOUND;
}
void emberAfScenesClusterClearSceneTableCallback(uint8_t endpoint)
{
- uint8_t i, networkIndex = emberGetCurrentNetwork();
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- EmberAfSceneTableEntry entry;
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint != EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID
- && (endpoint == entry.endpoint
- || (endpoint == EMBER_BROADCAST_ENDPOINT
- && (networkIndex
- == emberAfNetworkIndexFromEndpoint(entry.endpoint))))) {
- entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
- emberAfPluginScenesServerSaveSceneEntry(entry, i);
- }
- }
- emberAfPluginScenesServerSetNumSceneEntriesInUse(0);
- if (endpoint == EMBER_BROADCAST_ENDPOINT) {
- for (i = 0; i < emberAfEndpointCount(); i++) {
- if (emberAfNetworkIndexFromEndpointIndex(i) == networkIndex) {
- emberAfScenesSetSceneCountAttribute(emberAfEndpointFromIndex(i), 0);
- }
- }
- } else {
- emberAfScenesSetSceneCountAttribute(endpoint, 0);
- }
-}
-
-bool emberAfPluginScenesServerParseAddScene(const EmberAfClusterCommand *cmd,
- uint16_t groupId,
- uint8_t sceneId,
- uint16_t transitionTime,
- uint8_t *sceneName,
- uint8_t *extensionFieldSets)
-{
- EmberAfSceneTableEntry entry;
- EmberAfStatus status;
- EmberStatus sendStatus;
- bool enhanced = (cmd->commandId == ZCL_ENHANCED_ADD_SCENE_COMMAND_ID);
- uint16_t extensionFieldSetsLen = (cmd->bufLen
- - (cmd->payloadStartIndex
- + sizeof(groupId)
- + sizeof(sceneId)
- + sizeof(transitionTime)
- + emberAfStringLength(sceneName) + 1));
- uint16_t extensionFieldSetsIndex = 0;
- uint8_t endpoint = cmd->apsFrame->destinationEndpoint;
- uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;
-
- emberAfScenesClusterPrint("RX: %pAddScene 0x%2x, 0x%x, 0x%2x, \"",
- (enhanced ? "Enhanced" : ""),
- groupId,
- sceneId,
- transitionTime);
- emberAfScenesClusterPrintString(sceneName);
- emberAfScenesClusterPrint("\", ");
- emberAfScenesClusterPrintBuffer(extensionFieldSets, extensionFieldSetsLen, false);
- emberAfScenesClusterPrintln("");
-
- // Add Scene commands can only reference groups to which we belong.
- if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID
- && !emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId)) {
- status = EMBER_ZCL_STATUS_INVALID_FIELD;
- goto kickout;
- }
-
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == endpoint
- && entry.groupId == groupId
- && entry.sceneId == sceneId) {
- index = i;
- break;
- } else if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX
- && entry.endpoint == EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID) {
- index = i;
- }
- }
-
- // If the target index is still zero, the table is full.
- if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX) {
- status = EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
- goto kickout;
- }
-
- emberAfPluginScenesServerRetrieveSceneEntry(entry, index);
-
- // The transition time is specified in seconds in the regular version of the
- // command and tenths of a second in the enhanced version.
- if (enhanced) {
- entry.transitionTime = transitionTime / 10;
- entry.transitionTime100ms = (uint8_t)(transitionTime - entry.transitionTime * 10);
- } else {
- entry.transitionTime = transitionTime;
- entry.transitionTime100ms = 0;
- }
-
-#ifdef EMBER_AF_PLUGIN_SCENES_NAME_SUPPORT
- emberAfCopyString(entry.name, sceneName, ZCL_SCENES_CLUSTER_MAXIMUM_NAME_LENGTH);
-#endif
-
- // When adding a new scene, wipe out all of the extensions before parsing the
- // extension field sets data.
- if (i != index) {
-#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
- entry.hasOnOffValue = false;
-#endif
-#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
- entry.hasCurrentLevelValue = false;
-#endif
-#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
- entry.hasOccupiedCoolingSetpointValue = false;
- entry.hasOccupiedHeatingSetpointValue = false;
- entry.hasSystemModeValue = false;
-#endif
-#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
- entry.hasCurrentXValue = false;
- entry.hasCurrentYValue = false;
- entry.hasEnhancedCurrentHueValue = false;
- entry.hasCurrentSaturationValue = false;
- entry.hasColorLoopActiveValue = false;
- entry.hasColorLoopDirectionValue = false;
- entry.hasColorLoopTimeValue = false;
- entry.hasColorTemperatureMiredsValue = false;
-#endif //ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
-#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
- entry.hasLockStateValue = false;
-#endif
-#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
- entry.hasCurrentPositionLiftPercentageValue = false;
- entry.hasCurrentPositionTiltPercentageValue = false;
-#endif
- }
-
- while (extensionFieldSetsIndex < extensionFieldSetsLen) {
- EmberAfClusterId clusterId;
- uint8_t length;
-
- // Each extension field set must contain a two-byte cluster id and a one-
- // byte length. Otherwise, the command is malformed.
- if (extensionFieldSetsLen < extensionFieldSetsIndex + 3) {
- status = EMBER_ZCL_STATUS_MALFORMED_COMMAND;
- goto kickout;
- }
-
- clusterId = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex += 2;
- length = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex++;
-
- // If the length is off, the command is also malformed.
- if (length == 0) {
- continue;
- } else if (extensionFieldSetsLen < extensionFieldSetsIndex + length) {
- status = EMBER_ZCL_STATUS_MALFORMED_COMMAND;
- goto kickout;
- }
-
- switch (clusterId) {
-#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
- case ZCL_ON_OFF_CLUSTER_ID:
- // We only know of one extension for the On/Off cluster and it is just one
- // byte, which means we can skip some logic for this cluster. If other
- // extensions are added in this cluster, more logic will be needed here.
- entry.hasOnOffValue = true;
- entry.onOffValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- break;
-#endif
-#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
- case ZCL_LEVEL_CONTROL_CLUSTER_ID:
- // We only know of one extension for the Level Control cluster and it is
- // just one byte, which means we can skip some logic for this cluster. If
- // other extensions are added in this cluster, more logic will be needed
- // here.
- entry.hasCurrentLevelValue = true;
- entry.currentLevelValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- break;
-#endif
-#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
- case ZCL_THERMOSTAT_CLUSTER_ID:
- if (length < 2) {
- break;
+ uint8_t i, networkIndex = emberGetCurrentNetwork();
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ EmberAfSceneTableEntry entry;
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint != EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID &&
+ (endpoint == entry.endpoint ||
+ (endpoint == EMBER_BROADCAST_ENDPOINT && (networkIndex == emberAfNetworkIndexFromEndpoint(entry.endpoint)))))
+ {
+ entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
+ emberAfPluginScenesServerSaveSceneEntry(entry, i);
}
- entry.hasOccupiedCoolingSetpointValue = true;
- entry.occupiedCoolingSetpointValue = (int16_t)emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex += 2;
- length -= 2;
- if (length < 2) {
- break;
- }
- entry.hasOccupiedHeatingSetpointValue = true;
- entry.occupiedHeatingSetpointValue = (int16_t)emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex += 2;
- length -= 2;
- if (length < 1) {
- break;
- }
- entry.hasSystemModeValue = true;
- entry.systemModeValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- // If additional Thermostat extensions are added, adjust the index and
- // length variables here.
- break;
-#endif
-#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
- case ZCL_COLOR_CONTROL_CLUSTER_ID:
- if (length < 2) {
- break;
- }
- entry.hasCurrentXValue = true;
- entry.currentXValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex += 2;
- length -= 2;
- if (length < 2) {
- break;
- }
- entry.hasCurrentYValue = true;
- entry.currentYValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- if (enhanced) {
- extensionFieldSetsIndex += 2;
- length -= 2;
- if (length < 2) {
- break;
- }
- entry.hasEnhancedCurrentHueValue = true;
- entry.enhancedCurrentHueValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex += 2;
- length -= 2;
- if (length < 1) {
- break;
- }
- entry.hasCurrentSaturationValue = true;
- entry.currentSaturationValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex++;
- length--;
- if (length < 1) {
- break;
- }
- entry.hasColorLoopActiveValue = true;
- entry.colorLoopActiveValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex++;
- length--;
- if (length < 1) {
- break;
- }
- entry.hasColorLoopDirectionValue = true;
- entry.colorLoopDirectionValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex++;
- length--;
- if (length < 2) {
- break;
- }
- entry.hasColorLoopTimeValue = true;
- entry.colorLoopTimeValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex += 2;
- length -= 2;
- if (length < 2) {
- break;
- }
- entry.hasColorTemperatureMiredsValue = true;
- entry.colorTemperatureMiredsValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- }
- // If additional Color Control extensions are added, adjust the index and
- // length variables here.
- break;
-#endif //ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
-#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
- case ZCL_DOOR_LOCK_CLUSTER_ID:
- // We only know of one extension for the Door Lock cluster and it is just
- // one byte, which means we can skip some logic for this cluster. If
- // other extensions are added in this cluster, more logic will be needed
- // here.
- entry.hasLockStateValue = true;
- entry.lockStateValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- break;
-#endif
-#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
- case ZCL_WINDOW_COVERING_CLUSTER_ID:
- // If we're here, we know we have at least one byte, so we can skip the
- // length check for the first field.
- entry.hasCurrentPositionLiftPercentageValue = true;
- entry.currentPositionLiftPercentageValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- extensionFieldSetsIndex++;
- length--;
- if (length < 1) {
- break;
- }
- entry.hasCurrentPositionTiltPercentageValue = true;
- entry.currentPositionTiltPercentageValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
- // If additional Window Covering extensions are added, adjust the index
- // and length variables here.
- break;
-#endif
- default:
- break;
}
-
- extensionFieldSetsIndex += length;
- }
-
- // If we got this far, we either added a new entry or updated an existing one.
- // If we added, store the basic data and increment the scene count. In either
- // case, save the entry.
- if (i != index) {
- entry.endpoint = endpoint;
- entry.groupId = groupId;
- entry.sceneId = sceneId;
- emberAfPluginScenesServerIncrNumSceneEntriesInUse();
- emberAfScenesSetSceneCountAttribute(endpoint,
- emberAfPluginScenesServerNumSceneEntriesInUse());
- }
- emberAfPluginScenesServerSaveSceneEntry(entry, index);
- status = EMBER_ZCL_STATUS_SUCCESS;
-
- kickout:
- // Add Scene commands are only responded to when they are addressed to a
- // single device.
- if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST
- && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY) {
- return true;
- }
- emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND
- | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT),
- ZCL_SCENES_CLUSTER_ID,
- (enhanced
- ? ZCL_ENHANCED_ADD_SCENE_RESPONSE_COMMAND_ID
- : ZCL_ADD_SCENE_RESPONSE_COMMAND_ID),
- "uvu",
- status,
- groupId,
- sceneId);
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x",
- "add_scene",
- sendStatus);
- }
- return true;
-}
-
-bool emberAfPluginScenesServerParseViewScene(const EmberAfClusterCommand *cmd,
- uint16_t groupId,
- uint8_t sceneId)
-{
- EmberAfSceneTableEntry entry;
- EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
- EmberStatus sendStatus;
- bool enhanced = (cmd->commandId == ZCL_ENHANCED_VIEW_SCENE_COMMAND_ID);
- uint8_t endpoint = cmd->apsFrame->destinationEndpoint;
-
- emberAfScenesClusterPrintln("RX: %pViewScene 0x%2x, 0x%x",
- (enhanced ? "Enhanced" : ""),
- groupId,
- sceneId);
-
- // View Scene commands can only reference groups which we belong to.
- if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID
- && !emberAfGroupsClusterEndpointInGroupCallback(endpoint,
- groupId)) {
- status = EMBER_ZCL_STATUS_INVALID_FIELD;
- } else {
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == endpoint
- && entry.groupId == groupId
- && entry.sceneId == sceneId) {
- status = EMBER_ZCL_STATUS_SUCCESS;
- break;
- }
- }
- }
-
- // The status, group id, and scene id are always included in the response, but
- // the transition time, name, and extension fields are only included if the
- // scene was found.
- emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND
- | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT
- | EMBER_AF_DEFAULT_RESPONSE_POLICY_RESPONSES),
- ZCL_SCENES_CLUSTER_ID,
- (enhanced
- ? ZCL_ENHANCED_VIEW_SCENE_RESPONSE_COMMAND_ID
- : ZCL_VIEW_SCENE_RESPONSE_COMMAND_ID),
- "uvu",
- status,
- groupId,
- sceneId);
- if (status == EMBER_ZCL_STATUS_SUCCESS) {
- // The transition time is returned in seconds in the regular version of the
- // command and tenths of a second in the enhanced version.
- emberAfPutInt16uInResp(enhanced
- ? entry.transitionTime * 10 + entry.transitionTime100ms
- : entry.transitionTime);
-#ifdef EMBER_AF_PLUGIN_SCENES_NAME_SUPPORT
- emberAfPutStringInResp(entry.name);
-#else
- emberAfPutInt8uInResp(0); // name length
-#endif
-#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
- if (entry.hasOnOffValue) {
- emberAfPutInt16uInResp(ZCL_ON_OFF_CLUSTER_ID);
- emberAfPutInt8uInResp(1); // length
- emberAfPutInt8uInResp(entry.onOffValue);
- }
-#endif
-#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
- if (entry.hasCurrentLevelValue) {
- emberAfPutInt16uInResp(ZCL_LEVEL_CONTROL_CLUSTER_ID);
- emberAfPutInt8uInResp(1); // length
- emberAfPutInt8uInResp(entry.currentLevelValue);
- }
-#endif
-#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
- if (entry.hasOccupiedCoolingSetpointValue) {
- uint8_t *length;
- emberAfPutInt16uInResp(ZCL_THERMOSTAT_CLUSTER_ID);
- length = &appResponseData[appResponseLength];
- emberAfPutInt8uInResp(0); // temporary length
- emberAfPutInt16uInResp(entry.occupiedCoolingSetpointValue);
- *length += 2;
- if (entry.hasOccupiedHeatingSetpointValue) {
- emberAfPutInt16uInResp(entry.occupiedHeatingSetpointValue);
- *length += 2;
- if (entry.hasSystemModeValue) {
- emberAfPutInt8uInResp(entry.systemModeValue);
- (*length)++;
- }
- }
- }
-#endif
-#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
- if (entry.hasCurrentXValue) {
- uint8_t *length;
- emberAfPutInt16uInResp(ZCL_COLOR_CONTROL_CLUSTER_ID);
- length = &appResponseData[appResponseLength];
- emberAfPutInt8uInResp(0); // temporary length
- emberAfPutInt16uInResp(entry.currentXValue);
- *length += 2;
- if (entry.hasCurrentYValue) {
- emberAfPutInt16uInResp(entry.currentYValue);
- *length += 2;
- if (enhanced) {
- if (entry.hasEnhancedCurrentHueValue) {
- emberAfPutInt16uInResp(entry.enhancedCurrentHueValue);
- *length += 2;
- if (entry.hasCurrentSaturationValue) {
- emberAfPutInt8uInResp(entry.currentSaturationValue);
- (*length)++;
- if (entry.hasColorLoopActiveValue) {
- emberAfPutInt8uInResp(entry.colorLoopActiveValue);
- (*length)++;
- if (entry.hasColorLoopDirectionValue) {
- emberAfPutInt8uInResp(entry.colorLoopDirectionValue);
- (*length)++;
- if (entry.hasColorLoopTimeValue) {
- emberAfPutInt16uInResp(entry.colorLoopTimeValue);
- *length += 2;
- if (entry.hasColorTemperatureMiredsValue) {
- emberAfPutInt16uInResp(entry.colorTemperatureMiredsValue);
- *length += 2;
- }
- }
- }
- }
+ emberAfPluginScenesServerSetNumSceneEntriesInUse(0);
+ if (endpoint == EMBER_BROADCAST_ENDPOINT)
+ {
+ for (i = 0; i < emberAfEndpointCount(); i++)
+ {
+ if (emberAfNetworkIndexFromEndpointIndex(i) == networkIndex)
+ {
+ emberAfScenesSetSceneCountAttribute(emberAfEndpointFromIndex(i), 0);
}
- }
}
- }
}
-#endif //ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
-#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
- if (entry.hasLockStateValue) {
- emberAfPutInt16uInResp(ZCL_DOOR_LOCK_CLUSTER_ID);
- emberAfPutInt8uInResp(1); // length
- emberAfPutInt8uInResp(entry.lockStateValue);
+ else
+ {
+ emberAfScenesSetSceneCountAttribute(endpoint, 0);
}
-#endif
-#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
- if (entry.hasCurrentPositionLiftPercentageValue) {
- uint8_t *length;
- emberAfPutInt16uInResp(ZCL_WINDOW_COVERING_CLUSTER_ID);
- length = &appResponseData[appResponseLength];
- emberAfPutInt8uInResp(0); // temporary length
- emberAfPutInt8uInResp(entry.currentPositionLiftPercentageValue);
- (*length)++;
- if (entry.hasCurrentPositionTiltPercentageValue) {
- emberAfPutInt8uInResp(entry.currentPositionTiltPercentageValue);
- (*length)++;
- }
- }
-#endif
- }
-
- // View Scene commands are only responded to when they are addressed to a
- // single device.
- if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST
- && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY) {
- return true;
- }
- sendStatus = emberAfSendResponse();
- if (EMBER_SUCCESS != sendStatus) {
- emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x",
- "view_scene",
- sendStatus);
- }
- return true;
}
-void emberAfScenesClusterRemoveScenesInGroupCallback(uint8_t endpoint,
- uint16_t groupId)
+bool emberAfPluginScenesServerParseAddScene(const EmberAfClusterCommand * cmd, uint16_t groupId, uint8_t sceneId,
+ uint16_t transitionTime, uint8_t * sceneName, uint8_t * extensionFieldSets)
{
- uint8_t i;
- for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++) {
EmberAfSceneTableEntry entry;
- emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
- if (entry.endpoint == endpoint
- && entry.groupId == groupId) {
- entry.groupId = ZCL_SCENES_GLOBAL_SCENE_GROUP_ID;
- entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
- emberAfPluginScenesServerSaveSceneEntry(entry, i);
- emberAfPluginScenesServerDecrNumSceneEntriesInUse();
- emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(),
- emberAfPluginScenesServerNumSceneEntriesInUse());
+ EmberAfStatus status;
+ EmberStatus sendStatus;
+ bool enhanced = (cmd->commandId == ZCL_ENHANCED_ADD_SCENE_COMMAND_ID);
+ uint16_t extensionFieldSetsLen = (cmd->bufLen -
+ (cmd->payloadStartIndex + sizeof(groupId) + sizeof(sceneId) + sizeof(transitionTime) +
+ emberAfStringLength(sceneName) + 1));
+ uint16_t extensionFieldSetsIndex = 0;
+ uint8_t endpoint = cmd->apsFrame->destinationEndpoint;
+ uint8_t i, index = EMBER_AF_SCENE_TABLE_NULL_INDEX;
+
+ emberAfScenesClusterPrint("RX: %pAddScene 0x%2x, 0x%x, 0x%2x, \"", (enhanced ? "Enhanced" : ""), groupId, sceneId,
+ transitionTime);
+ emberAfScenesClusterPrintString(sceneName);
+ emberAfScenesClusterPrint("\", ");
+ emberAfScenesClusterPrintBuffer(extensionFieldSets, extensionFieldSetsLen, false);
+ emberAfScenesClusterPrintln("");
+
+ // Add Scene commands can only reference groups to which we belong.
+ if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID && !emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId))
+ {
+ status = EMBER_ZCL_STATUS_INVALID_FIELD;
+ goto kickout;
}
- }
+
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
+ {
+ index = i;
+ break;
+ }
+ else if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX && entry.endpoint == EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID)
+ {
+ index = i;
+ }
+ }
+
+ // If the target index is still zero, the table is full.
+ if (index == EMBER_AF_SCENE_TABLE_NULL_INDEX)
+ {
+ status = EMBER_ZCL_STATUS_INSUFFICIENT_SPACE;
+ goto kickout;
+ }
+
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, index);
+
+ // The transition time is specified in seconds in the regular version of the
+ // command and tenths of a second in the enhanced version.
+ if (enhanced)
+ {
+ entry.transitionTime = transitionTime / 10;
+ entry.transitionTime100ms = (uint8_t)(transitionTime - entry.transitionTime * 10);
+ }
+ else
+ {
+ entry.transitionTime = transitionTime;
+ entry.transitionTime100ms = 0;
+ }
+
+#ifdef EMBER_AF_PLUGIN_SCENES_NAME_SUPPORT
+ emberAfCopyString(entry.name, sceneName, ZCL_SCENES_CLUSTER_MAXIMUM_NAME_LENGTH);
+#endif
+
+ // When adding a new scene, wipe out all of the extensions before parsing the
+ // extension field sets data.
+ if (i != index)
+ {
+#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
+ entry.hasOnOffValue = false;
+#endif
+#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
+ entry.hasCurrentLevelValue = false;
+#endif
+#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
+ entry.hasOccupiedCoolingSetpointValue = false;
+ entry.hasOccupiedHeatingSetpointValue = false;
+ entry.hasSystemModeValue = false;
+#endif
+#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+ entry.hasCurrentXValue = false;
+ entry.hasCurrentYValue = false;
+ entry.hasEnhancedCurrentHueValue = false;
+ entry.hasCurrentSaturationValue = false;
+ entry.hasColorLoopActiveValue = false;
+ entry.hasColorLoopDirectionValue = false;
+ entry.hasColorLoopTimeValue = false;
+ entry.hasColorTemperatureMiredsValue = false;
+#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
+ entry.hasLockStateValue = false;
+#endif
+#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
+ entry.hasCurrentPositionLiftPercentageValue = false;
+ entry.hasCurrentPositionTiltPercentageValue = false;
+#endif
+ }
+
+ while (extensionFieldSetsIndex < extensionFieldSetsLen)
+ {
+ EmberAfClusterId clusterId;
+ uint8_t length;
+
+ // Each extension field set must contain a two-byte cluster id and a one-
+ // byte length. Otherwise, the command is malformed.
+ if (extensionFieldSetsLen < extensionFieldSetsIndex + 3)
+ {
+ status = EMBER_ZCL_STATUS_MALFORMED_COMMAND;
+ goto kickout;
+ }
+
+ clusterId = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex += 2;
+ length = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex++;
+
+ // If the length is off, the command is also malformed.
+ if (length == 0)
+ {
+ continue;
+ }
+ else if (extensionFieldSetsLen < extensionFieldSetsIndex + length)
+ {
+ status = EMBER_ZCL_STATUS_MALFORMED_COMMAND;
+ goto kickout;
+ }
+
+ switch (clusterId)
+ {
+#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
+ case ZCL_ON_OFF_CLUSTER_ID:
+ // We only know of one extension for the On/Off cluster and it is just one
+ // byte, which means we can skip some logic for this cluster. If other
+ // extensions are added in this cluster, more logic will be needed here.
+ entry.hasOnOffValue = true;
+ entry.onOffValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ break;
+#endif
+#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
+ case ZCL_LEVEL_CONTROL_CLUSTER_ID:
+ // We only know of one extension for the Level Control cluster and it is
+ // just one byte, which means we can skip some logic for this cluster. If
+ // other extensions are added in this cluster, more logic will be needed
+ // here.
+ entry.hasCurrentLevelValue = true;
+ entry.currentLevelValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ break;
+#endif
+#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
+ case ZCL_THERMOSTAT_CLUSTER_ID:
+ if (length < 2)
+ {
+ break;
+ }
+ entry.hasOccupiedCoolingSetpointValue = true;
+ entry.occupiedCoolingSetpointValue =
+ (int16_t) emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex += 2;
+ length -= 2;
+ if (length < 2)
+ {
+ break;
+ }
+ entry.hasOccupiedHeatingSetpointValue = true;
+ entry.occupiedHeatingSetpointValue =
+ (int16_t) emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex += 2;
+ length -= 2;
+ if (length < 1)
+ {
+ break;
+ }
+ entry.hasSystemModeValue = true;
+ entry.systemModeValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ // If additional Thermostat extensions are added, adjust the index and
+ // length variables here.
+ break;
+#endif
+#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+ case ZCL_COLOR_CONTROL_CLUSTER_ID:
+ if (length < 2)
+ {
+ break;
+ }
+ entry.hasCurrentXValue = true;
+ entry.currentXValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex += 2;
+ length -= 2;
+ if (length < 2)
+ {
+ break;
+ }
+ entry.hasCurrentYValue = true;
+ entry.currentYValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ if (enhanced)
+ {
+ extensionFieldSetsIndex += 2;
+ length -= 2;
+ if (length < 2)
+ {
+ break;
+ }
+ entry.hasEnhancedCurrentHueValue = true;
+ entry.enhancedCurrentHueValue =
+ emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex += 2;
+ length -= 2;
+ if (length < 1)
+ {
+ break;
+ }
+ entry.hasCurrentSaturationValue = true;
+ entry.currentSaturationValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex++;
+ length--;
+ if (length < 1)
+ {
+ break;
+ }
+ entry.hasColorLoopActiveValue = true;
+ entry.colorLoopActiveValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex++;
+ length--;
+ if (length < 1)
+ {
+ break;
+ }
+ entry.hasColorLoopDirectionValue = true;
+ entry.colorLoopDirectionValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex++;
+ length--;
+ if (length < 2)
+ {
+ break;
+ }
+ entry.hasColorLoopTimeValue = true;
+ entry.colorLoopTimeValue = emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex += 2;
+ length -= 2;
+ if (length < 2)
+ {
+ break;
+ }
+ entry.hasColorTemperatureMiredsValue = true;
+ entry.colorTemperatureMiredsValue =
+ emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ }
+ // If additional Color Control extensions are added, adjust the index and
+ // length variables here.
+ break;
+#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
+ case ZCL_DOOR_LOCK_CLUSTER_ID:
+ // We only know of one extension for the Door Lock cluster and it is just
+ // one byte, which means we can skip some logic for this cluster. If
+ // other extensions are added in this cluster, more logic will be needed
+ // here.
+ entry.hasLockStateValue = true;
+ entry.lockStateValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ break;
+#endif
+#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
+ case ZCL_WINDOW_COVERING_CLUSTER_ID:
+ // If we're here, we know we have at least one byte, so we can skip the
+ // length check for the first field.
+ entry.hasCurrentPositionLiftPercentageValue = true;
+ entry.currentPositionLiftPercentageValue =
+ emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ extensionFieldSetsIndex++;
+ length--;
+ if (length < 1)
+ {
+ break;
+ }
+ entry.hasCurrentPositionTiltPercentageValue = true;
+ entry.currentPositionTiltPercentageValue =
+ emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen);
+ // If additional Window Covering extensions are added, adjust the index
+ // and length variables here.
+ break;
+#endif
+ default:
+ break;
+ }
+
+ extensionFieldSetsIndex += length;
+ }
+
+ // If we got this far, we either added a new entry or updated an existing one.
+ // If we added, store the basic data and increment the scene count. In either
+ // case, save the entry.
+ if (i != index)
+ {
+ entry.endpoint = endpoint;
+ entry.groupId = groupId;
+ entry.sceneId = sceneId;
+ emberAfPluginScenesServerIncrNumSceneEntriesInUse();
+ emberAfScenesSetSceneCountAttribute(endpoint, emberAfPluginScenesServerNumSceneEntriesInUse());
+ }
+ emberAfPluginScenesServerSaveSceneEntry(entry, index);
+ status = EMBER_ZCL_STATUS_SUCCESS;
+
+kickout:
+ // Add Scene commands are only responded to when they are addressed to a
+ // single device.
+ if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
+ {
+ return true;
+ }
+ emberAfFillExternalBuffer((ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT), ZCL_SCENES_CLUSTER_ID,
+ (enhanced ? ZCL_ENHANCED_ADD_SCENE_RESPONSE_COMMAND_ID : ZCL_ADD_SCENE_RESPONSE_COMMAND_ID), "uvu",
+ status, groupId, sceneId);
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "add_scene", sendStatus);
+ }
+ return true;
+}
+
+bool emberAfPluginScenesServerParseViewScene(const EmberAfClusterCommand * cmd, uint16_t groupId, uint8_t sceneId)
+{
+ EmberAfSceneTableEntry entry;
+ EmberAfStatus status = EMBER_ZCL_STATUS_NOT_FOUND;
+ EmberStatus sendStatus;
+ bool enhanced = (cmd->commandId == ZCL_ENHANCED_VIEW_SCENE_COMMAND_ID);
+ uint8_t endpoint = cmd->apsFrame->destinationEndpoint;
+
+ emberAfScenesClusterPrintln("RX: %pViewScene 0x%2x, 0x%x", (enhanced ? "Enhanced" : ""), groupId, sceneId);
+
+ // View Scene commands can only reference groups which we belong to.
+ if (groupId != ZCL_SCENES_GLOBAL_SCENE_GROUP_ID && !emberAfGroupsClusterEndpointInGroupCallback(endpoint, groupId))
+ {
+ status = EMBER_ZCL_STATUS_INVALID_FIELD;
+ }
+ else
+ {
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == endpoint && entry.groupId == groupId && entry.sceneId == sceneId)
+ {
+ status = EMBER_ZCL_STATUS_SUCCESS;
+ break;
+ }
+ }
+ }
+
+ // The status, group id, and scene id are always included in the response, but
+ // the transition time, name, and extension fields are only included if the
+ // scene was found.
+ emberAfFillExternalBuffer(
+ (ZCL_CLUSTER_SPECIFIC_COMMAND | ZCL_FRAME_CONTROL_SERVER_TO_CLIENT | EMBER_AF_DEFAULT_RESPONSE_POLICY_RESPONSES),
+ ZCL_SCENES_CLUSTER_ID, (enhanced ? ZCL_ENHANCED_VIEW_SCENE_RESPONSE_COMMAND_ID : ZCL_VIEW_SCENE_RESPONSE_COMMAND_ID), "uvu",
+ status, groupId, sceneId);
+ if (status == EMBER_ZCL_STATUS_SUCCESS)
+ {
+ // The transition time is returned in seconds in the regular version of the
+ // command and tenths of a second in the enhanced version.
+ emberAfPutInt16uInResp(enhanced ? entry.transitionTime * 10 + entry.transitionTime100ms : entry.transitionTime);
+#ifdef EMBER_AF_PLUGIN_SCENES_NAME_SUPPORT
+ emberAfPutStringInResp(entry.name);
+#else
+ emberAfPutInt8uInResp(0); // name length
+#endif
+#ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER
+ if (entry.hasOnOffValue)
+ {
+ emberAfPutInt16uInResp(ZCL_ON_OFF_CLUSTER_ID);
+ emberAfPutInt8uInResp(1); // length
+ emberAfPutInt8uInResp(entry.onOffValue);
+ }
+#endif
+#ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER
+ if (entry.hasCurrentLevelValue)
+ {
+ emberAfPutInt16uInResp(ZCL_LEVEL_CONTROL_CLUSTER_ID);
+ emberAfPutInt8uInResp(1); // length
+ emberAfPutInt8uInResp(entry.currentLevelValue);
+ }
+#endif
+#ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER
+ if (entry.hasOccupiedCoolingSetpointValue)
+ {
+ uint8_t * length;
+ emberAfPutInt16uInResp(ZCL_THERMOSTAT_CLUSTER_ID);
+ length = &appResponseData[appResponseLength];
+ emberAfPutInt8uInResp(0); // temporary length
+ emberAfPutInt16uInResp(entry.occupiedCoolingSetpointValue);
+ *length += 2;
+ if (entry.hasOccupiedHeatingSetpointValue)
+ {
+ emberAfPutInt16uInResp(entry.occupiedHeatingSetpointValue);
+ *length += 2;
+ if (entry.hasSystemModeValue)
+ {
+ emberAfPutInt8uInResp(entry.systemModeValue);
+ (*length)++;
+ }
+ }
+ }
+#endif
+#ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+ if (entry.hasCurrentXValue)
+ {
+ uint8_t * length;
+ emberAfPutInt16uInResp(ZCL_COLOR_CONTROL_CLUSTER_ID);
+ length = &appResponseData[appResponseLength];
+ emberAfPutInt8uInResp(0); // temporary length
+ emberAfPutInt16uInResp(entry.currentXValue);
+ *length += 2;
+ if (entry.hasCurrentYValue)
+ {
+ emberAfPutInt16uInResp(entry.currentYValue);
+ *length += 2;
+ if (enhanced)
+ {
+ if (entry.hasEnhancedCurrentHueValue)
+ {
+ emberAfPutInt16uInResp(entry.enhancedCurrentHueValue);
+ *length += 2;
+ if (entry.hasCurrentSaturationValue)
+ {
+ emberAfPutInt8uInResp(entry.currentSaturationValue);
+ (*length)++;
+ if (entry.hasColorLoopActiveValue)
+ {
+ emberAfPutInt8uInResp(entry.colorLoopActiveValue);
+ (*length)++;
+ if (entry.hasColorLoopDirectionValue)
+ {
+ emberAfPutInt8uInResp(entry.colorLoopDirectionValue);
+ (*length)++;
+ if (entry.hasColorLoopTimeValue)
+ {
+ emberAfPutInt16uInResp(entry.colorLoopTimeValue);
+ *length += 2;
+ if (entry.hasColorTemperatureMiredsValue)
+ {
+ emberAfPutInt16uInResp(entry.colorTemperatureMiredsValue);
+ *length += 2;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER
+#ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER
+ if (entry.hasLockStateValue)
+ {
+ emberAfPutInt16uInResp(ZCL_DOOR_LOCK_CLUSTER_ID);
+ emberAfPutInt8uInResp(1); // length
+ emberAfPutInt8uInResp(entry.lockStateValue);
+ }
+#endif
+#ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER
+ if (entry.hasCurrentPositionLiftPercentageValue)
+ {
+ uint8_t * length;
+ emberAfPutInt16uInResp(ZCL_WINDOW_COVERING_CLUSTER_ID);
+ length = &appResponseData[appResponseLength];
+ emberAfPutInt8uInResp(0); // temporary length
+ emberAfPutInt8uInResp(entry.currentPositionLiftPercentageValue);
+ (*length)++;
+ if (entry.hasCurrentPositionTiltPercentageValue)
+ {
+ emberAfPutInt8uInResp(entry.currentPositionTiltPercentageValue);
+ (*length)++;
+ }
+ }
+#endif
+ }
+
+ // View Scene commands are only responded to when they are addressed to a
+ // single device.
+ if (emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST && emberAfCurrentCommand()->type != EMBER_INCOMING_UNICAST_REPLY)
+ {
+ return true;
+ }
+ sendStatus = emberAfSendResponse();
+ if (EMBER_SUCCESS != sendStatus)
+ {
+ emberAfScenesClusterPrintln("Scenes: failed to send %s response: 0x%x", "view_scene", sendStatus);
+ }
+ return true;
+}
+
+void emberAfScenesClusterRemoveScenesInGroupCallback(uint8_t endpoint, uint16_t groupId)
+{
+ uint8_t i;
+ for (i = 0; i < EMBER_AF_PLUGIN_SCENES_TABLE_SIZE; i++)
+ {
+ EmberAfSceneTableEntry entry;
+ emberAfPluginScenesServerRetrieveSceneEntry(entry, i);
+ if (entry.endpoint == endpoint && entry.groupId == groupId)
+ {
+ entry.groupId = ZCL_SCENES_GLOBAL_SCENE_GROUP_ID;
+ entry.endpoint = EMBER_AF_SCENE_TABLE_UNUSED_ENDPOINT_ID;
+ emberAfPluginScenesServerSaveSceneEntry(entry, i);
+ emberAfPluginScenesServerDecrNumSceneEntriesInUse();
+ emberAfScenesSetSceneCountAttribute(emberAfCurrentEndpoint(), emberAfPluginScenesServerNumSceneEntriesInUse());
+ }
+ }
}
diff --git a/src/app/clusters/scenes/scenes.h b/src/app/clusters/scenes/scenes.h
index f95f7ff..41b9e50 100644
--- a/src/app/clusters/scenes/scenes.h
+++ b/src/app/clusters/scenes/scenes.h
@@ -31,17 +31,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/***************************************************************************//**
+/****************************************************************************
* @file
* @brief Definitions for the Scenes plugin.
*******************************************************************************
- ******************************************************************************/
+ ******************************************************************************/
-EmberAfStatus emberAfScenesSetSceneCountAttribute(uint8_t endpoint,
- uint8_t newCount);
-EmberAfStatus emberAfScenesMakeValid(uint8_t endpoint,
- uint8_t sceneId,
- uint16_t groupId);
+EmberAfStatus emberAfScenesSetSceneCountAttribute(uint8_t endpoint, uint8_t newCount);
+EmberAfStatus emberAfScenesMakeValid(uint8_t endpoint, uint8_t sceneId, uint16_t groupId);
// DEPRECATED.
#define emberAfScenesMakeInvalid emberAfScenesClusterMakeInvalidCallback
@@ -51,47 +48,32 @@
extern uint8_t emberAfPluginScenesServerEntriesInUse;
#if defined(EMBER_AF_PLUGIN_SCENES_USE_TOKENS) && !defined(EZSP_HOST)
// In this case, we use token storage
- #define emberAfPluginScenesServerRetrieveSceneEntry(entry, i) \
- halCommonGetIndexedToken(&entry, TOKEN_SCENES_TABLE, i)
- #define emberAfPluginScenesServerSaveSceneEntry(entry, i) \
- halCommonSetIndexedToken(TOKEN_SCENES_TABLE, i, &entry)
- #define emberAfPluginScenesServerNumSceneEntriesInUse() \
- (halCommonGetToken(&emberAfPluginScenesServerEntriesInUse, TOKEN_SCENES_NUM_ENTRIES), \
- emberAfPluginScenesServerEntriesInUse)
- #define emberAfPluginScenesServerSetNumSceneEntriesInUse(x) \
- (emberAfPluginScenesServerEntriesInUse = (x), \
- halCommonSetToken(TOKEN_SCENES_NUM_ENTRIES, &emberAfPluginScenesServerEntriesInUse))
- #define emberAfPluginScenesServerIncrNumSceneEntriesInUse() \
- ((halCommonGetToken(&emberAfPluginScenesServerEntriesInUse, TOKEN_SCENES_NUM_ENTRIES), \
- ++emberAfPluginScenesServerEntriesInUse), \
- halCommonSetToken(TOKEN_SCENES_NUM_ENTRIES, &emberAfPluginScenesServerEntriesInUse))
- #define emberAfPluginScenesServerDecrNumSceneEntriesInUse() \
- ((halCommonGetToken(&emberAfPluginScenesServerEntriesInUse, TOKEN_SCENES_NUM_ENTRIES), \
- --emberAfPluginScenesServerEntriesInUse), \
- halCommonSetToken(TOKEN_SCENES_NUM_ENTRIES, &emberAfPluginScenesServerEntriesInUse))
+#define emberAfPluginScenesServerRetrieveSceneEntry(entry, i) halCommonGetIndexedToken(&entry, TOKEN_SCENES_TABLE, i)
+#define emberAfPluginScenesServerSaveSceneEntry(entry, i) halCommonSetIndexedToken(TOKEN_SCENES_TABLE, i, &entry)
+#define emberAfPluginScenesServerNumSceneEntriesInUse() \
+ (halCommonGetToken(&emberAfPluginScenesServerEntriesInUse, TOKEN_SCENES_NUM_ENTRIES), emberAfPluginScenesServerEntriesInUse)
+#define emberAfPluginScenesServerSetNumSceneEntriesInUse(x) \
+ (emberAfPluginScenesServerEntriesInUse = (x), \
+ halCommonSetToken(TOKEN_SCENES_NUM_ENTRIES, &emberAfPluginScenesServerEntriesInUse))
+#define emberAfPluginScenesServerIncrNumSceneEntriesInUse() \
+ ((halCommonGetToken(&emberAfPluginScenesServerEntriesInUse, TOKEN_SCENES_NUM_ENTRIES), \
+ ++emberAfPluginScenesServerEntriesInUse), \
+ halCommonSetToken(TOKEN_SCENES_NUM_ENTRIES, &emberAfPluginScenesServerEntriesInUse))
+#define emberAfPluginScenesServerDecrNumSceneEntriesInUse() \
+ ((halCommonGetToken(&emberAfPluginScenesServerEntriesInUse, TOKEN_SCENES_NUM_ENTRIES), \
+ --emberAfPluginScenesServerEntriesInUse), \
+ halCommonSetToken(TOKEN_SCENES_NUM_ENTRIES, &emberAfPluginScenesServerEntriesInUse))
#else
// Use normal RAM storage
extern EmberAfSceneTableEntry emberAfPluginScenesServerSceneTable[];
- #define emberAfPluginScenesServerRetrieveSceneEntry(entry, i) \
- (entry = emberAfPluginScenesServerSceneTable[i])
- #define emberAfPluginScenesServerSaveSceneEntry(entry, i) \
- (emberAfPluginScenesServerSceneTable[i] = entry)
- #define emberAfPluginScenesServerNumSceneEntriesInUse() \
- (emberAfPluginScenesServerEntriesInUse)
- #define emberAfPluginScenesServerSetNumSceneEntriesInUse(x) \
- (emberAfPluginScenesServerEntriesInUse = (x))
- #define emberAfPluginScenesServerIncrNumSceneEntriesInUse() \
- (++emberAfPluginScenesServerEntriesInUse)
- #define emberAfPluginScenesServerDecrNumSceneEntriesInUse() \
- (--emberAfPluginScenesServerEntriesInUse)
+#define emberAfPluginScenesServerRetrieveSceneEntry(entry, i) (entry = emberAfPluginScenesServerSceneTable[i])
+#define emberAfPluginScenesServerSaveSceneEntry(entry, i) (emberAfPluginScenesServerSceneTable[i] = entry)
+#define emberAfPluginScenesServerNumSceneEntriesInUse() (emberAfPluginScenesServerEntriesInUse)
+#define emberAfPluginScenesServerSetNumSceneEntriesInUse(x) (emberAfPluginScenesServerEntriesInUse = (x))
+#define emberAfPluginScenesServerIncrNumSceneEntriesInUse() (++emberAfPluginScenesServerEntriesInUse)
+#define emberAfPluginScenesServerDecrNumSceneEntriesInUse() (--emberAfPluginScenesServerEntriesInUse)
#endif // Use tokens
-bool emberAfPluginScenesServerParseAddScene(const EmberAfClusterCommand *cmd,
- uint16_t groupId,
- uint8_t sceneId,
- uint16_t transitionTime,
- uint8_t *sceneName,
- uint8_t *extensionFieldSets);
-bool emberAfPluginScenesServerParseViewScene(const EmberAfClusterCommand *cmd,
- uint16_t groupId,
- uint8_t sceneId);
+bool emberAfPluginScenesServerParseAddScene(const EmberAfClusterCommand * cmd, uint16_t groupId, uint8_t sceneId,
+ uint16_t transitionTime, uint8_t * sceneName, uint8_t * extensionFieldSets);
+bool emberAfPluginScenesServerParseViewScene(const EmberAfClusterCommand * cmd, uint16_t groupId, uint8_t sceneId);