From 17110493be167ac627f0a7349ac0974b9c823bc0 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 26 Jan 2023 19:33:30 -0500 Subject: [PATCH] Stop using non-namespaced attribute ids in core SDK code. (#24649) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Stop using non-namespaced attribute ids in core SDK code. * Also remove now-unused attribute-id.h includes in core code. * Fix clang-tidy else-after-return complaint. * Apply suggestions from code review Co-authored-by: Jonathan Mégevand <77852424+jmeg-sfy@users.noreply.github.com> * One more "target" addition. * Fix restyle issue. Co-authored-by: Jonathan Mégevand <77852424+jmeg-sfy@users.noreply.github.com> --- .github/workflows/lint.yml | 20 +- .../group-key-mgmt-server.cpp | 2 - .../clusters/groups-server/groups-server.cpp | 2 - .../ias-zone-client/ias-zone-client.cpp | 30 +- .../ias-zone-server/ias-zone-server.cpp | 25 +- .../identify-server/identify-server.cpp | 2 - .../mode-select-server/mode-select-server.cpp | 1 - src/app/clusters/scenes/scenes.cpp | 445 ++++++++++-------- .../thermostat-server/thermostat-server.cpp | 2 - ...at-user-interface-configuration-server.cpp | 2 - .../window-covering-server.cpp | 1 - .../window-covering-server.h | 1 - src/app/util/af-types.h | 15 +- src/app/util/attribute-storage.cpp | 34 +- src/app/util/attribute-table.cpp | 24 +- src/app/util/util.cpp | 5 +- 16 files changed, 349 insertions(+), 262 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 00e6f7cb060fe2..85e1110431a181 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -116,7 +116,7 @@ jobs: uses: gaurav-nelson/github-action-markdown-link-check@v1 # git grep exits with 0 if it finds a match, but we want - # to fail (exit nonzero) on match. And we wasnt to exclude this file, + # to fail (exit nonzero) on match. And we want to exclude this file, # to avoid our grep regexp matching itself. - name: Check for incorrect error use in VerifyOrExit if: always() @@ -124,7 +124,7 @@ jobs: git grep -n "VerifyOrExit(.*, [A-Za-z]*_ERROR" -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 # git grep exits with 0 if it finds a match, but we want - # to fail (exit nonzero) on match. And we wasnt to exclude this file, + # to fail (exit nonzero) on match. And we want to exclude this file, # to avoid our grep regexp matching itself. - name: Check for use of PRI*8, which are not supported on some libcs. if: always() @@ -132,7 +132,7 @@ jobs: git grep -n "PRI.8" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)third_party/lwip/repo/lwip/src/include/lwip/arch.h' && exit 1 || exit 0 # git grep exits with 0 if it finds a match, but we want - # to fail (exit nonzero) on match. And we wasnt to exclude this file, + # to fail (exit nonzero) on match. And we want to exclude this file, # to avoid our grep regexp matching itself. - name: Check for use of PRI*16, which are not supported on some libcs. if: always() @@ -140,7 +140,7 @@ jobs: git grep -n "PRI.16" -- './*' ':(exclude).github/workflows/lint.yml' ':(exclude)third_party/lwip/repo/lwip/src/include/lwip/arch.h' && exit 1 || exit 0 # git grep exits with 0 if it finds a match, but we want - # to fail (exit nonzero) on match. And we wasnt to exclude this file, + # to fail (exit nonzero) on match. And we want to exclude this file, # to avoid our grep regexp matching itself. - name: Check for use of %zu, which are not supported on some libcs. if: always() @@ -167,7 +167,7 @@ jobs: scripts/tools/check_test_pics.py src/app/tests/suites/certification/ci-pics-values src/app/tests/suites/certification/PICS.yaml # git grep exits with 0 if it finds a match, but we want - # to fail (exit nonzero) on match. And we wasnt to exclude this file, + # to fail (exit nonzero) on match. And we want to exclude this file, # to avoid our grep regexp matching itself. - name: Check for use of 0x%u and the like, which lead to misleading output. if: always() @@ -175,9 +175,17 @@ jobs: git grep -n '0x%[0-9l.-]*[^0-9lxX".-]' -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 # git grep exits with 0 if it finds a match, but we want - # to fail (exit nonzero) on match. And we wasnt to exclude this file, + # to fail (exit nonzero) on match. And we want to exclude this file, # to avoid our grep regexp matching itself. - name: Check for use of '"0x" PRIu*' and the like, which lead to misleading output. if: always() run: | git grep -n '0x%[0-9-]*" *PRI[^xX]' -- './*' ':(exclude).github/workflows/lint.yml' && exit 1 || exit 0 + + # git grep exits with 0 if it finds a match, but we want + # to fail (exit nonzero) on match. And we want to exclude this file, + # to avoid our grep regexp matching itself. + - name: Check for use of legacy non-namespaced attribute ids. + if: always() + run: | + git grep -n '_ATTRIBUTE_ID' -- src ':(exclude)src/app/zap-templates/templates/app/attribute-id.zapt' && exit 1 || exit 0 diff --git a/src/app/clusters/group-key-mgmt-server/group-key-mgmt-server.cpp b/src/app/clusters/group-key-mgmt-server/group-key-mgmt-server.cpp index fa6e46e8f40fdb..c1ec6fdb7e8255 100644 --- a/src/app/clusters/group-key-mgmt-server/group-key-mgmt-server.cpp +++ b/src/app/clusters/group-key-mgmt-server/group-key-mgmt-server.cpp @@ -16,8 +16,6 @@ */ #include -#include -#include #include #include #include diff --git a/src/app/clusters/groups-server/groups-server.cpp b/src/app/clusters/groups-server/groups-server.cpp index 92788177cee06d..39ba191b37b710 100644 --- a/src/app/clusters/groups-server/groups-server.cpp +++ b/src/app/clusters/groups-server/groups-server.cpp @@ -18,8 +18,6 @@ #include "groups-server.h" #include -#include -#include #include #include #include diff --git a/src/app/clusters/ias-zone-client/ias-zone-client.cpp b/src/app/clusters/ias-zone-client/ias-zone-client.cpp index 11f1b6de3fd0cc..0945d5a836564d 100644 --- a/src/app/clusters/ias-zone-client/ias-zone-client.cpp +++ b/src/app/clusters/ias-zone-client/ias-zone-client.cpp @@ -16,12 +16,14 @@ */ #include "ias-zone-client.h" +#include #include #include #include #include using namespace chip; +using namespace chip::app::Clusters::IasZone; using namespace chip::app::Clusters::IasZone::Commands; //----------------------------------------------------------------------------- @@ -344,9 +346,11 @@ static EmberStatus sendCommand(EmberNodeId destAddress) static void setCieAddress(EmberNodeId destAddress) { +#error "This needs to be fixed to handle 4-byte attribute ids" + uint8_t writeAttributes[] = { - EMBER_LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID), - EMBER_HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID), + EMBER_LOW_BYTE(Attributes::IasCieAddress::Id), + EMBER_HIGH_BYTE(Attributes::IasCieAddress::Id), ZCL_IEEE_ADDRESS_ATTRIBUTE_TYPE, 0, 0, @@ -430,12 +434,14 @@ void emberAfPluginIasZoneClientZdoMessageReceivedCallback(EmberNodeId emberNodeI void readIasZoneServerAttributes(EmberNodeId nodeId) { +#error "This needs to be fixed to handle 4-byte attribute ids" + uint8_t iasZoneAttributeIds[] = { - EMBER_LOW_BYTE(ZCL_ZONE_STATE_ATTRIBUTE_ID), EMBER_HIGH_BYTE(ZCL_ZONE_STATE_ATTRIBUTE_ID), + EMBER_LOW_BYTE(Attributes::ZoneState::Id), EMBER_HIGH_BYTE(Attributes::ZoneState::Id), - EMBER_LOW_BYTE(ZCL_ZONE_TYPE_ATTRIBUTE_ID), EMBER_HIGH_BYTE(ZCL_ZONE_TYPE_ATTRIBUTE_ID), + EMBER_LOW_BYTE(Attributes::ZoneType::Id), EMBER_HIGH_BYTE(Attributes::ZoneType::Id), - EMBER_LOW_BYTE(ZCL_ZONE_STATUS_ATTRIBUTE_ID), EMBER_HIGH_BYTE(ZCL_ZONE_STATUS_ATTRIBUTE_ID), + EMBER_LOW_BYTE(Attributes::ZoneStatus::Id), EMBER_HIGH_BYTE(Attributes::ZoneStatus::Id), }; emberAfFillExternalBuffer((ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), app::Clusters::IasZone::Id, ZCL_READ_ATTRIBUTES_COMMAND_ID, "b", iasZoneAttributeIds, sizeof(iasZoneAttributeIds)); @@ -447,9 +453,11 @@ void readIasZoneServerAttributes(EmberNodeId nodeId) void readIasZoneServerCieAddress(EmberNodeId nodeId) { +#error "This needs to be fixed to handle 4-byte attribute ids" + uint8_t iasZoneAttributeIds[] = { - EMBER_LOW_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID), - EMBER_HIGH_BYTE(ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID), + EMBER_LOW_BYTE(Attributes::IasCieAddress::Id), + EMBER_HIGH_BYTE(Attributes::IasCieAddress::Id), }; emberAfFillExternalBuffer((ZCL_GLOBAL_COMMAND | ZCL_FRAME_CONTROL_CLIENT_TO_SERVER), app::Clusters::IasZone::Id, ZCL_READ_ATTRIBUTES_COMMAND_ID, "b", iasZoneAttributeIds, sizeof(iasZoneAttributeIds)); @@ -495,7 +503,7 @@ void emberAfPluginIasZoneClientReadAttributesResponseCallback(ClusterId clusterI i++; // skip the type of the attribute. We already know what it should be. switch (attributeId) { - case ZCL_ZONE_STATUS_ATTRIBUTE_ID: + case Attributes::ZoneStatus::Id: if ((i + 2) > bufLen) { // Too short, dump the message. @@ -505,7 +513,7 @@ void emberAfPluginIasZoneClientReadAttributesResponseCallback(ClusterId clusterI setServerZoneStatus(currentIndex, zoneStatus); i += 2; break; - case ZCL_ZONE_TYPE_ATTRIBUTE_ID: + case Attributes::ZoneType::Id: if ((i + 2) > bufLen) { // Too short, dump the message. @@ -515,7 +523,7 @@ void emberAfPluginIasZoneClientReadAttributesResponseCallback(ClusterId clusterI setServerZoneType(currentIndex, zoneType); i += 2; break; - case ZCL_ZONE_STATE_ATTRIBUTE_ID: + case Attributes::ZoneState::Id: if ((i + 1) > bufLen) { // Too short, dump the message @@ -525,7 +533,7 @@ void emberAfPluginIasZoneClientReadAttributesResponseCallback(ClusterId clusterI setServerZoneState(currentIndex, zoneState); i++; break; - case ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID: { + case Attributes::IasCieAddress::Id: { uint8_t myIeee[EUI64_SIZE]; emberAfGetEui64(myIeee); if ((i + 8) > bufLen) diff --git a/src/app/clusters/ias-zone-server/ias-zone-server.cpp b/src/app/clusters/ias-zone-server/ias-zone-server.cpp index e64f0f00fe5f45..df593f67bfe470 100644 --- a/src/app/clusters/ias-zone-server/ias-zone-server.cpp +++ b/src/app/clusters/ias-zone-server/ias-zone-server.cpp @@ -17,7 +17,6 @@ #include "ias-zone-server.h" #include -#include #include #include #include @@ -197,7 +196,7 @@ MatterIasZoneClusterServerPreAttributeChangedCallback(const app::ConcreteAttribu // 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 (attributePath.mAttributeId != ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID || emberAfCurrentCommand() == nullptr) + if (attributePath.mAttributeId != Attributes::IasCieAddress::Id || emberAfCurrentCommand() == nullptr) { return Protocols::InteractionModel::Status::Success; } @@ -238,7 +237,7 @@ MatterIasZoneClusterServerPreAttributeChangedCallback(const app::ConcreteAttribu } zeroAddress = true; - emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, (uint8_t *) ieeeAddress, 8); + emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::IasCieAddress::Id, (uint8_t *) ieeeAddress, 8); for (i = 0; i < 8; i++) { if (ieeeAddress[i] != 0) @@ -298,7 +297,7 @@ bool emberAfIasZoneClusterAmIEnrolled(EndpointId endpoint) { EmberAfIasZoneState zoneState = EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED; // Clear this out completely. EmberAfStatus status; - status = emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_STATE_ATTRIBUTE_ID, (unsigned char *) &zoneState, + status = emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::ZoneState::Id, (unsigned char *) &zoneState, 1); // uint8_t size return (status == EMBER_ZCL_STATUS_SUCCESS && zoneState == EMBER_ZCL_IAS_ZONE_STATE_ENROLLED); @@ -308,8 +307,7 @@ static void updateEnrollState(EndpointId endpoint, bool enrolled) { EmberAfIasZoneState zoneState = (enrolled ? EMBER_ZCL_IAS_ZONE_STATE_ENROLLED : EMBER_ZCL_IAS_ZONE_STATE_NOT_ENROLLED); - emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_STATE_ATTRIBUTE_ID, (uint8_t *) &zoneState, - ZCL_INT8U_ATTRIBUTE_TYPE); + emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneState::Id, (uint8_t *) &zoneState, ZCL_INT8U_ATTRIBUTE_TYPE); emberAfIasZoneClusterPrintln("IAS Zone Server State: %pEnrolled", (enrolled ? "" : "NOT ")); } @@ -324,7 +322,7 @@ bool emberAfIasZoneClusterZoneEnrollResponseCallback(app::CommandHandler * comma EmberAfStatus status; endpoint = emberAfCurrentEndpoint(); - status = emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_ID_ATTRIBUTE_ID, &epZoneId, sizeof(uint8_t)); + status = emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id, &epZoneId, sizeof(uint8_t)); if (status == EMBER_ZCL_STATUS_SUCCESS) { if (enrollResponseCode == EMBER_ZCL_IAS_ENROLL_RESPONSE_CODE_SUCCESS) @@ -380,7 +378,7 @@ EmberStatus emberAfPluginIasZoneServerUpdateZoneStatus(EndpointId endpoint, uint #endif EmberStatus sendStatus = EMBER_SUCCESS; - emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_STATUS_ATTRIBUTE_ID, (uint8_t *) &newStatus, + emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneStatus::Id, (uint8_t *) &newStatus, ZCL_INT16U_ATTRIBUTE_TYPE); if (enrollmentMethod == EMBER_ZCL_IAS_ZONE_ENROLLMENT_MODE_TRIP_TO_PAIR) @@ -523,7 +521,7 @@ void emberAfIasZoneClusterServerInitCallback(EndpointId endpoint) #endif zoneType = (EmberAfIasZoneType) EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE; - emberAfWriteAttribute(endpoint, IasZone::Id, ZCL_ZONE_TYPE_ATTRIBUTE_ID, (uint8_t *) &zoneType, ZCL_INT16U_ATTRIBUTE_TYPE); + emberAfWriteAttribute(endpoint, IasZone::Id, Attributes::ZoneType::Id, (uint8_t *) &zoneType, ZCL_INT16U_ATTRIBUTE_TYPE); emberAfPluginIasZoneServerUpdateZoneStatus(endpoint, 0, // status: All alarms cleared @@ -538,7 +536,7 @@ void emberAfIasZoneClusterServerTickCallback(EndpointId endpoint) uint8_t emberAfPluginIasZoneServerGetZoneId(EndpointId endpoint) { uint8_t zoneId = UNDEFINED_ZONE_ID; - emberAfReadServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_ID_ATTRIBUTE_ID, &zoneId, + emberAfReadServerAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id, &zoneId, emberAfGetDataSize(ZCL_INT8U_ATTRIBUTE_TYPE)); return zoneId; } @@ -566,7 +564,7 @@ static bool areZoneServerAttributesNonVolatile(EndpointId endpoint) static void setZoneId(EndpointId endpoint, uint8_t zoneId) { emberAfIasZoneClusterPrintln("IAS Zone Server Zone ID: 0x%X", zoneId); - emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_ID_ATTRIBUTE_ID, &zoneId, ZCL_INT8U_ATTRIBUTE_TYPE); + emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneId::Id, &zoneId, ZCL_INT8U_ATTRIBUTE_TYPE); } static void unenrollSecurityDevice(EndpointId endpoint) @@ -574,11 +572,10 @@ static void unenrollSecurityDevice(EndpointId endpoint) uint8_t ieeeAddress[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint16_t zoneType = EMBER_AF_PLUGIN_IAS_ZONE_SERVER_ZONE_TYPE; - emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_IAS_CIE_ADDRESS_ATTRIBUTE_ID, (uint8_t *) ieeeAddress, + emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::IasCieAddress::Id, (uint8_t *) ieeeAddress, ZCL_NODE_ID_ATTRIBUTE_TYPE); - emberAfWriteServerAttribute(endpoint, IasZone::Id, ZCL_ZONE_TYPE_ATTRIBUTE_ID, (uint8_t *) &zoneType, - ZCL_INT16U_ATTRIBUTE_TYPE); + emberAfWriteServerAttribute(endpoint, IasZone::Id, Attributes::ZoneType::Id, (uint8_t *) &zoneType, ZCL_INT16U_ATTRIBUTE_TYPE); setZoneId(endpoint, UNDEFINED_ZONE_ID); // Restore the enrollment method back to its default value. diff --git a/src/app/clusters/identify-server/identify-server.cpp b/src/app/clusters/identify-server/identify-server.cpp index 5dfe3a0aeba3bf..08b19f7e0183d1 100644 --- a/src/app/clusters/identify-server/identify-server.cpp +++ b/src/app/clusters/identify-server/identify-server.cpp @@ -17,8 +17,6 @@ #include "identify-server.h" -#include -#include #include #include #include diff --git a/src/app/clusters/mode-select-server/mode-select-server.cpp b/src/app/clusters/mode-select-server/mode-select-server.cpp index bf3e9872a46ea7..9091d4ba286f58 100644 --- a/src/app/clusters/mode-select-server/mode-select-server.cpp +++ b/src/app/clusters/mode-select-server/mode-select-server.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/src/app/clusters/scenes/scenes.cpp b/src/app/clusters/scenes/scenes.cpp index 580f6234c388ac..a02095d21764a1 100644 --- a/src/app/clusters/scenes/scenes.cpp +++ b/src/app/clusters/scenes/scenes.cpp @@ -17,14 +17,14 @@ #include "scenes.h" #include "app/util/common.h" -#include -#include +#include #include #include #include #include #include #include +#include #ifdef EMBER_AF_PLUGIN_GROUPS_SERVER #include @@ -44,32 +44,22 @@ uint8_t emberAfPluginScenesServerEntriesInUse = 0; EmberAfSceneTableEntry emberAfPluginScenesServerSceneTable[MATTER_SCENES_TABLE_SIZE]; #endif -static bool readServerAttribute(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, const char * name, - uint8_t * data, uint8_t size) +static bool logReadError(EmberAfStatus status, const char * attributeName) { - bool success = false; - if (emberAfContainsServer(endpoint, clusterId)) + // Don't log errors for the "this cluster is not even supported" cases. + if (status != EMBER_ZCL_STATUS_SUCCESS && status != EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT && + status != EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER) { - 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); - } + emberAfScenesClusterPrintln("ERR: %sing %s 0x%x", "read", attributeName, status); } - return success; + return status == EMBER_ZCL_STATUS_SUCCESS; } -static EmberAfStatus writeServerAttribute(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, const char * name, - uint8_t * data, EmberAfAttributeType type) +static EmberAfStatus logWriteError(EmberAfStatus status, const char * attributeName) { - EmberAfStatus status = emberAfWriteServerAttribute(endpoint, clusterId, attributeId, data, type); if (status != EMBER_ZCL_STATUS_SUCCESS) { - emberAfScenesClusterPrintln("ERR: %ping %p 0x%x", "writ", name, status); + emberAfScenesClusterPrintln("ERR: %sing %s 0x%x", "writ", attributeName, status); } return status; } @@ -90,8 +80,7 @@ void emberAfScenesClusterServerInitCallback(EndpointId endpoint) { // The high bit of Name Support indicates whether scene names are supported. uint8_t nameSupport = EMBER_BIT(7); - writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_NAME_SUPPORT_ATTRIBUTE_ID, "name support", (uint8_t *) &nameSupport, - ZCL_BITMAP8_ATTRIBUTE_TYPE); + logWriteError(Attributes::NameSupport::Set(endpoint, nameSupport), "NameSupport"); } #endif #if !defined(EMBER_AF_PLUGIN_SCENES_USE_TOKENS) || defined(EZSP_HOST) @@ -112,8 +101,7 @@ void emberAfScenesClusterServerInitCallback(EndpointId endpoint) EmberAfStatus emberAfScenesSetSceneCountAttribute(EndpointId endpoint, uint8_t newCount) { - return writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_COUNT_ATTRIBUTE_ID, "scene count", (uint8_t *) &newCount, - ZCL_INT8U_ATTRIBUTE_TYPE); + return logWriteError(Attributes::SceneCount::Set(endpoint, newCount), "SceneCount"); } EmberAfStatus emberAfScenesMakeValid(EndpointId endpoint, uint8_t sceneId, GroupId groupId) @@ -122,31 +110,27 @@ EmberAfStatus emberAfScenesMakeValid(EndpointId endpoint, uint8_t sceneId, Group bool valid = true; // scene ID - status = writeServerAttribute(endpoint, Scenes::Id, ZCL_CURRENT_SCENE_ATTRIBUTE_ID, "current scene", (uint8_t *) &sceneId, - ZCL_INT8U_ATTRIBUTE_TYPE); + status = logWriteError(Attributes::CurrentScene::Set(endpoint, sceneId), "CurrentScene"); if (status != EMBER_ZCL_STATUS_SUCCESS) { return status; } // group ID - status = writeServerAttribute(endpoint, Scenes::Id, ZCL_CURRENT_GROUP_ATTRIBUTE_ID, "current group", (uint8_t *) &groupId, - ZCL_INT16U_ATTRIBUTE_TYPE); + status = logWriteError(Attributes::CurrentGroup::Set(endpoint, groupId), "CurrentGroup"); if (status != EMBER_ZCL_STATUS_SUCCESS) { return status; } - status = writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_VALID_ATTRIBUTE_ID, "scene valid", (uint8_t *) &valid, - ZCL_BOOLEAN_ATTRIBUTE_TYPE); + status = logWriteError(Attributes::SceneValid::Set(endpoint, valid), "SceneValid"); return status; } EmberAfStatus emberAfScenesClusterMakeInvalidCallback(EndpointId endpoint) { bool valid = false; - return writeServerAttribute(endpoint, Scenes::Id, ZCL_SCENE_VALID_ATTRIBUTE_ID, "scene valid", (uint8_t *) &valid, - ZCL_BOOLEAN_ATTRIBUTE_TYPE); + return logWriteError(Attributes::SceneValid::Set(endpoint, valid), "SceneValid"); } void emAfPluginScenesServerPrintInfo() @@ -172,7 +156,14 @@ void emAfPluginScenesServerPrintInfo() emberAfCorePrint(" on/off %x", entry.onOffValue); #endif #ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER - emberAfCorePrint(" lvl %x", entry.currentLevelValue); + if (entry.currentLevelValue.IsNull()) + { + emberAfCorePrint(" lvl null"); + } + else + { + emberAfCorePrint(" lvl %x", entry.currentLevelValue.Value()); + } #endif #ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER emberAfCorePrint(" therm %2x %2x %x", entry.occupiedCoolingSetpointValue, entry.occupiedHeatingSetpointValue, @@ -186,13 +177,44 @@ void emAfPluginScenesServerPrintInfo() emberAfCoreFlush(); #endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER #ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER - emberAfCorePrint(" door %x", entry.lockStateValue); + if (entry.lockStateValue.IsNull()) + { + emberAfCorePrint(" door null"); + } + else + { + emberAfCorePrint(" door %x", to_underlying(entry.lockStateValue.Value())); + } #endif #ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER - emberAfCorePrint(" Window percentage Lift %3u, Tilt %3u", entry.currentPositionLiftPercentageValue, - entry.currentPositionTiltPercentageValue); - emberAfCorePrint(" Window percent100ths Lift %5u, Tilt %5u", entry.targetPositionLiftPercent100thsValue, - entry.targetPositionTiltPercent100thsValue); + if (!entry.currentPositionLiftPercentageValue.IsNull() && !entry.currentPositionTiltPercentageValue.IsNull()) + { + emberAfCorePrint(" Window current percentage Lift %3u, Tilt %3u", entry.currentPositionLiftPercentageValue.Value(), + entry.currentPositionTiltPercentageValue.Value()); + } + else if (!entry.currentPositionLiftPercentageValue.IsNull()) + { + emberAfCorePrint(" Window current percentage Lift %3u", entry.currentPositionLiftPercentageValue.Value()); + } + else if (!entry.currentPositionTiltPercentageValue.IsNull()) + { + emberAfCorePrint(" Window current percentage Tilt %3u", entry.currentPositionTiltPercentageValue.Value()); + } + + if (!entry.targetPositionLiftPercent100thsValue.IsNull() && !entry.targetPositionTiltPercent100thsValue.IsNull()) + { + emberAfCorePrint(" Window target percent100ths Lift %5u, Tilt %5u", + entry.targetPositionLiftPercent100thsValue.Value(), + entry.targetPositionTiltPercent100thsValue.Value()); + } + else if (!entry.targetPositionLiftPercent100thsValue.IsNull()) + { + emberAfCorePrint(" Window target percent100ths Lift %5u", entry.targetPositionLiftPercent100thsValue.Value()); + } + else if (!entry.targetPositionTiltPercent100thsValue.IsNull()) + { + emberAfCorePrint(" Window target percent100ths Tilt %5u", entry.targetPositionTiltPercent100thsValue.Value()); + } #endif } emberAfCorePrintln("%s", ""); @@ -500,64 +522,59 @@ EmberAfStatus emberAfScenesClusterStoreCurrentSceneCallback(chip::FabricIndex fa // 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, OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, "on/off", (uint8_t *) &entry.onOffValue, - sizeof(entry.onOffValue)); + entry.hasOnOffValue = logReadError(OnOff::Attributes::OnOff::Get(endpoint, &entry.onOffValue), "OnOff"); #endif #ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER - entry.hasCurrentLevelValue = readServerAttribute(endpoint, LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, "current level", - (uint8_t *) &entry.currentLevelValue, sizeof(entry.currentLevelValue)); + entry.hasCurrentLevelValue = + logReadError(LevelControl::Attributes::CurrentLevel::Get(endpoint, entry.currentLevelValue), "CurrentLevel"); #endif #ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER - entry.hasOccupiedCoolingSetpointValue = - readServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID, "occupied cooling setpoint", - (uint8_t *) &entry.occupiedCoolingSetpointValue, sizeof(entry.occupiedCoolingSetpointValue)); - entry.hasOccupiedHeatingSetpointValue = - readServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID, "occupied heating setpoint", - (uint8_t *) &entry.occupiedHeatingSetpointValue, sizeof(entry.occupiedHeatingSetpointValue)); - entry.hasSystemModeValue = readServerAttribute(endpoint, Thermostat::Id, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, "system mode", - (uint8_t *) &entry.systemModeValue, sizeof(entry.systemModeValue)); + { + using namespace Thermostat::Attributes; + entry.hasOccupiedCoolingSetpointValue = + logReadError(OccupiedCoolingSetpoint::Get(endpoint, &entry.occupiedCoolingSetpointValue), "OccupiedCoolingSetpoint"); + entry.hasOccupiedHeatingSetpointValue = + logReadError(OccupiedHeatingSetpoint::Get(endpoint, &entry.occupiedHeatingSetpointValue), "OccupiedHeatingSetpoint"); + entry.hasSystemModeValue = logReadError(SystemMode::Get(endpoint, &entry.systemModeValue), "SystemMode"); + } #endif #ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER - entry.hasCurrentXValue = readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID, "current x", - (uint8_t *) &entry.currentXValue, sizeof(entry.currentXValue)); - entry.hasCurrentYValue = readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID, "current y", - (uint8_t *) &entry.currentYValue, sizeof(entry.currentYValue)); - entry.hasEnhancedCurrentHueValue = - readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_ENHANCED_CURRENT_HUE_ATTRIBUTE_ID, "enhanced current hue", - (uint8_t *) &entry.enhancedCurrentHueValue, sizeof(entry.enhancedCurrentHueValue)); - entry.hasCurrentSaturationValue = - readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, "current saturation", - (uint8_t *) &entry.currentSaturationValue, sizeof(entry.currentSaturationValue)); - entry.hasColorLoopActiveValue = - readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_ACTIVE_ATTRIBUTE_ID, "color loop active", - (uint8_t *) &entry.colorLoopActiveValue, sizeof(entry.colorLoopActiveValue)); - entry.hasColorLoopDirectionValue = - readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_DIRECTION_ATTRIBUTE_ID, "color loop direction", - (uint8_t *) &entry.colorLoopDirectionValue, sizeof(entry.colorLoopDirectionValue)); - entry.hasColorLoopTimeValue = - readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_LOOP_TIME_ATTRIBUTE_ID, "color loop time", - (uint8_t *) &entry.colorLoopTimeValue, sizeof(entry.colorLoopTimeValue)); - entry.hasColorTemperatureMiredsValue = - readServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID, "color temp mireds", - (uint8_t *) &entry.colorTemperatureMiredsValue, sizeof(entry.colorTemperatureMiredsValue)); + { + using namespace ColorControl::Attributes; + entry.hasCurrentXValue = logReadError(CurrentX::Get(endpoint, &entry.currentXValue), "CurrentX"); + entry.hasCurrentYValue = logReadError(CurrentY::Get(endpoint, &entry.currentYValue), "CurrentY"); + entry.hasEnhancedCurrentHueValue = + logReadError(EnhancedCurrentHue::Get(endpoint, &entry.enhancedCurrentHueValue), "EnhancedCurrentHue"); + entry.hasCurrentSaturationValue = + logReadError(CurrentSaturation::Get(endpoint, &entry.currentSaturationValue), "CurrentSaturation"); + entry.hasColorLoopActiveValue = + logReadError(ColorLoopActive::Get(endpoint, &entry.colorLoopActiveValue), "ColorLoopActive"); + entry.hasColorLoopDirectionValue = + logReadError(ColorLoopDirection::Get(endpoint, &entry.colorLoopDirectionValue), "ColorLoopDirection"); + entry.hasColorLoopTimeValue = logReadError(ColorLoopTime::Get(endpoint, &entry.colorLoopTimeValue), "ColorLoopTime"); + entry.hasColorTemperatureMiredsValue = + logReadError(ColorTemperatureMireds::Get(endpoint, &entry.colorTemperatureMiredsValue), "ColorTemperatureMireds"); + } #endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER #ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER - entry.hasLockStateValue = readServerAttribute(endpoint, DoorLock::Id, ZCL_LOCK_STATE_ATTRIBUTE_ID, "lock state", - (uint8_t *) &entry.lockStateValue, sizeof(entry.lockStateValue)); + entry.hasLockStateValue = logReadError(DoorLock::Attributes::LockState::Get(endpoint, entry.lockStateValue), "LockState"); #endif #ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER - entry.hasCurrentPositionLiftPercentageValue = readServerAttribute( - endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_LIFT_PERCENTAGE_ATTRIBUTE_ID, "currentPositionLiftPercentage", - (uint8_t *) &entry.currentPositionLiftPercentageValue, sizeof(entry.currentPositionLiftPercentageValue)); - entry.hasCurrentPositionTiltPercentageValue = readServerAttribute( - endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_TILT_PERCENTAGE_ATTRIBUTE_ID, "currentPositionTiltPercentage", - (uint8_t *) &entry.currentPositionTiltPercentageValue, sizeof(entry.currentPositionTiltPercentageValue)); - entry.hasTargetPositionLiftPercent100thsValue = readServerAttribute( - endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_LIFT_PERCENT100_THS_ATTRIBUTE_ID, "targetPositionLiftPercent100ths", - (uint8_t *) &entry.targetPositionLiftPercent100thsValue, sizeof(entry.targetPositionLiftPercent100thsValue)); - entry.hasTargetPositionTiltPercent100thsValue = readServerAttribute( - endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_TILT_PERCENT100_THS_ATTRIBUTE_ID, "targetPositionTiltPercent100ths", - (uint8_t *) &entry.targetPositionTiltPercent100thsValue, sizeof(entry.targetPositionTiltPercent100thsValue)); + { + using namespace WindowCovering::Attributes; + entry.hasCurrentPositionLiftPercentageValue = + logReadError(CurrentPositionLiftPercentage::Get(endpoint, entry.currentPositionLiftPercentageValue), + "CurrentPositionLiftPercentage"); + entry.hasCurrentPositionTiltPercentageValue = + logReadError(CurrentPositionTiltPercentage::Get(endpoint, entry.currentPositionTiltPercentageValue), + "CurrentPositionTiltPercentage"); + entry.hasTargetPositionLiftPercent100thsValue = + logReadError(TargetPositionLiftPercent100ths::Get(endpoint, entry.targetPositionLiftPercent100thsValue), + "TragetPositionLiftPercent100ths"); + entry.hasTargetPositionTiltPercent100thsValue = + logReadError(TargetPositionTiltPercent100ths::Get(endpoint, entry.targetPositionTiltPercent100thsValue), + "TragetPositionTiltPercent100ths"); + } #endif // When creating a new entry, the name is set to the null string (i.e., the @@ -603,111 +620,102 @@ EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(chip::FabricIndex fab #ifdef ZCL_USING_ON_OFF_CLUSTER_SERVER if (entry.hasOnOffValue) { - writeServerAttribute(endpoint, OnOff::Id, ZCL_ON_OFF_ATTRIBUTE_ID, "on/off", (uint8_t *) &entry.onOffValue, - ZCL_BOOLEAN_ATTRIBUTE_TYPE); + logWriteError(OnOff::Attributes::OnOff::Set(endpoint, entry.onOffValue), "OnOff"); } #endif #ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER if (entry.hasCurrentLevelValue) { - writeServerAttribute(endpoint, LevelControl::Id, ZCL_CURRENT_LEVEL_ATTRIBUTE_ID, "current level", - (uint8_t *) &entry.currentLevelValue, ZCL_INT8U_ATTRIBUTE_TYPE); + logWriteError(LevelControl::Attributes::CurrentLevel::Set(endpoint, entry.currentLevelValue), "CurrentLevel"); } #endif #ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER - if (entry.hasOccupiedCoolingSetpointValue) - { - writeServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_COOLING_SETPOINT_ATTRIBUTE_ID, - "occupied cooling setpoint", (uint8_t *) &entry.occupiedCoolingSetpointValue, - ZCL_INT16S_ATTRIBUTE_TYPE); - } - if (entry.hasOccupiedHeatingSetpointValue) - { - writeServerAttribute(endpoint, Thermostat::Id, ZCL_OCCUPIED_HEATING_SETPOINT_ATTRIBUTE_ID, - "occupied heating setpoint", (uint8_t *) &entry.occupiedHeatingSetpointValue, - ZCL_INT16S_ATTRIBUTE_TYPE); - } - if (entry.hasSystemModeValue) { - writeServerAttribute(endpoint, Thermostat::Id, ZCL_SYSTEM_MODE_ATTRIBUTE_ID, "system mode", - (uint8_t *) &entry.systemModeValue, ZCL_INT8U_ATTRIBUTE_TYPE); + using namespace Thermostat::Attributes; + if (entry.hasOccupiedCoolingSetpointValue) + { + logWriteError(OccupiedCoolingSetpoint::Set(endpoint, entry.occupiedCoolingSetpointValue), + "OccupiedCoolingSetpoint"); + } + if (entry.hasOccupiedHeatingSetpointValue) + { + logWriteError(OccupiedHeatingSetpoint::Set(endpoint, entry.occupiedHeatingSetpointValue), + "OccupiedHeatingSetpoint"); + } + if (entry.hasSystemModeValue) + { + logWriteError(SystemMode::Set(endpoint, entry.systemModeValue), "SystemMode"); + } } #endif #ifdef ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER - if (entry.hasCurrentXValue) { - writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_X_ATTRIBUTE_ID, "current x", - (uint8_t *) &entry.currentXValue, ZCL_INT16U_ATTRIBUTE_TYPE); - } - if (entry.hasCurrentYValue) - { - writeServerAttribute(endpoint, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_Y_ATTRIBUTE_ID, "current y", - (uint8_t *) &entry.currentYValue, ZCL_INT16U_ATTRIBUTE_TYPE); - } + using namespace ColorControl::Attributes; + if (entry.hasCurrentXValue) + { + logWriteError(CurrentX::Set(endpoint, entry.currentXValue), "CurrentX"); + } + if (entry.hasCurrentYValue) + { + logWriteError(CurrentY::Set(endpoint, entry.currentXValue), "CurrentY"); + } - if (entry.hasEnhancedCurrentHueValue) - { - writeServerAttribute(endpoint, ColorControl::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, ColorControl::Id, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, - "current saturation", (uint8_t *) &entry.currentSaturationValue, ZCL_INT8U_ATTRIBUTE_TYPE); - } - if (entry.hasColorLoopActiveValue) - { - writeServerAttribute(endpoint, ColorControl::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, ColorControl::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, ColorControl::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, ColorControl::Id, ZCL_COLOR_CONTROL_COLOR_TEMPERATURE_ATTRIBUTE_ID, - "color temp mireds", (uint8_t *) &entry.colorTemperatureMiredsValue, - ZCL_INT16U_ATTRIBUTE_TYPE); + if (entry.hasEnhancedCurrentHueValue) + { + logWriteError(EnhancedCurrentHue::Set(endpoint, entry.enhancedCurrentHueValue), "EnhancedCurrentHue"); + } + if (entry.hasCurrentSaturationValue) + { + logWriteError(CurrentSaturation::Set(endpoint, entry.currentSaturationValue), "CurrentSaturation"); + } + if (entry.hasColorLoopActiveValue) + { + logWriteError(ColorLoopActive::Set(endpoint, entry.colorLoopActiveValue), "ColorLoopActive"); + } + if (entry.hasColorLoopDirectionValue) + { + logWriteError(ColorLoopDirection::Set(endpoint, entry.colorLoopDirectionValue), "ColorLoopDirection"); + } + if (entry.hasColorLoopTimeValue) + { + logWriteError(ColorLoopTime::Set(endpoint, entry.colorLoopTimeValue), "ColorLoopTime"); + } + if (entry.hasColorTemperatureMiredsValue) + { + logWriteError(ColorTemperatureMireds::Set(endpoint, entry.colorTemperatureMiredsValue), + "ColorTemperatureMireds"); + } } #endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER #ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER if (entry.hasLockStateValue) { - writeServerAttribute(endpoint, DoorLock::Id, ZCL_LOCK_STATE_ATTRIBUTE_ID, "lock state", - (uint8_t *) &entry.lockStateValue, ZCL_INT8U_ATTRIBUTE_TYPE); + logWriteError(DoorLock::Attributes::LockState::Set(endpoint, entry.lockStateValue), "LockState"); } #endif #ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER - if (entry.hasCurrentPositionLiftPercentageValue) - { - writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_LIFT_PERCENTAGE_ATTRIBUTE_ID, - "CurrentPositionLiftPercentage", (uint8_t *) &entry.currentPositionLiftPercentageValue, - ZCL_INT8U_ATTRIBUTE_TYPE); - } - if (entry.hasCurrentPositionTiltPercentageValue) - { - writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_CURRENT_POSITION_TILT_PERCENTAGE_ATTRIBUTE_ID, - "CurrentPositionTiltPercentage", (uint8_t *) &entry.currentPositionTiltPercentageValue, - ZCL_INT8U_ATTRIBUTE_TYPE); - } - if (entry.hasTargetPositionLiftPercent100thsValue) { - writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_LIFT_PERCENT100_THS_ATTRIBUTE_ID, - "TargetPositionLiftPercent100ths", (uint8_t *) &entry.targetPositionLiftPercent100thsValue, - ZCL_INT16U_ATTRIBUTE_TYPE); - } - if (entry.hasTargetPositionTiltPercent100thsValue) - { - writeServerAttribute(endpoint, WindowCovering::Id, ZCL_WC_TARGET_POSITION_TILT_PERCENT100_THS_ATTRIBUTE_ID, - "TargetPositionTiltPercent100ths", (uint8_t *) &entry.targetPositionTiltPercent100thsValue, - ZCL_INT16U_ATTRIBUTE_TYPE); + using namespace WindowCovering::Attributes; + if (entry.hasCurrentPositionLiftPercentageValue) + { + logWriteError(CurrentPositionLiftPercentage::Set(endpoint, entry.currentPositionLiftPercentageValue), + "CurrentPositionLiftPercentage"); + } + if (entry.hasCurrentPositionTiltPercentageValue) + { + logWriteError(CurrentPositionTiltPercentage::Set(endpoint, entry.currentPositionTiltPercentageValue), + "CurrentPositionTiltPercentage"); + } + if (entry.hasTargetPositionLiftPercent100thsValue) + { + logWriteError(TargetPositionLiftPercent100ths::Set(endpoint, entry.targetPositionLiftPercent100thsValue), + "TargetPositionLiftPercent100ths"); + } + if (entry.hasTargetPositionTiltPercent100thsValue) + { + logWriteError(TargetPositionTiltPercent100ths::Set(endpoint, entry.targetPositionTiltPercent100thsValue), + "TargetPositionTiltPercent100ths"); + } } #endif emberAfScenesMakeValid(endpoint, sceneId, groupId); @@ -718,6 +726,17 @@ EmberAfStatus emberAfScenesClusterRecallSavedSceneCallback(chip::FabricIndex fab return EMBER_ZCL_STATUS_NOT_FOUND; } +template +struct NullableUnderlyingType +{ +}; + +template +struct NullableUnderlyingType> +{ + using Type = T; +}; + bool emberAfPluginScenesServerParseAddScene( app::CommandHandler * commandObj, const EmberAfClusterCommand * cmd, GroupId groupId, uint8_t sceneId, uint16_t transitionTime, const CharSpan & sceneName, const app::DataModel::DecodableList & extensionFieldSets) @@ -839,14 +858,22 @@ bool emberAfPluginScenesServerParseAddScene( break; #endif #ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER - case LevelControl::Id: + case LevelControl::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); + using Traits = NumericAttributeTraits::Type>; + // TODO: This is not right; we should be getting TLV values here or something! + Traits::StorageType storedValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + if (Traits::IsNullValue(storedValue)) { + entry.currentLevelValue.SetNull(); + } else { + entry.currentLevelValue.SetValue(storedValue); + } break; + } #endif #ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER case Thermostat::Id: @@ -953,49 +980,99 @@ bool emberAfPluginScenesServerParseAddScene( break; #endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER #ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER - case DoorLock::Id: + case DoorLock::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); + using Traits = NumericAttributeTraits::Type>; + // TODO: This is not right; we should be getting TLV values here or something! + Traits::StorageType storedValue = emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + if (Traits::IsNullValue(storedValue)) { + entry.lockStateValue.SetNull(); + } else { + entry.lockStateValue.SetValue(storedValue); + } break; + } #endif #ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER case WindowCovering::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); + { + entry.hasCurrentPositionLiftPercentageValue = true; + using Traits = NumericAttributeTraits::Type>; + // TODO: This is not right; we should be getting TLV values here or something! + Traits::StorageType storedValue = + emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + if (Traits::IsNullValue(storedValue)){ + entry.currentPositionLiftPercentageValue.SetNull(); + } else { + entry.currentPositionLiftPercentageValue.SetValue(storedValue); + } + } + extensionFieldSetsIndex++; length--; if (length < 1) { break; } - entry.hasCurrentPositionTiltPercentageValue = true; - entry.currentPositionTiltPercentageValue = - emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + + { + entry.hasCurrentPositionTiltPercentageValue = true; + using Traits = NumericAttributeTraits::Type>; + // TODO: This is not right; we should be getting TLV values here or something! + Traits::StorageType storedValue = + emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + if (Traits::IsNullValue(storedValue)){ + entry.currentPositionTiltPercentageValue.SetNull(); + } else { + entry.currentPositionTiltPercentageValue.SetValue(storedValue); + } + } + extensionFieldSetsIndex++; length--; if (length < 2) { break; } - entry.hasTargetPositionLiftPercent100thsValue = true; - entry.targetPositionLiftPercent100thsValue = - emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + + { + entry.hasTargetPositionLiftPercent100thsValue = true; + using Traits = NumericAttributeTraits::Type>; + // TODO: This is not right; we should be getting TLV values here or something! + Traits::StorageType storedValue = + emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + if (Traits::IsNullValue(storedValue)){ + entry.targetPositionLiftPercent100thsValue.SetNull(); + } else { + entry.targetPositionLiftPercent100thsValue.SetValue(storedValue); + } + } + extensionFieldSetsIndex = static_cast(extensionFieldSetsIndex + 2); length = static_cast(length - 2); if (length < 2) { break; } - entry.hasTargetPositionTiltPercent100thsValue = true; - entry.targetPositionTiltPercent100thsValue = - emberAfGetInt16u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + + { + entry.hasTargetPositionTiltPercent100thsValue = true; + using Traits = NumericAttributeTraits::Type>; + // TODO: This is not right; we should be getting TLV values here or something! + Traits::StorageType storedValue = + emberAfGetInt8u(extensionFieldSets, extensionFieldSetsIndex, extensionFieldSetsLen); + if (Traits::IsNullValue(storedValue)){ + entry.targetPositionTiltPercent100thsValue.SetNull(); + } else { + entry.targetPositionTiltPercent100thsValue.SetValue(storedValue); + } + } // If additional Window Covering extensions are added, adjust the index // and length variables here. break; diff --git a/src/app/clusters/thermostat-server/thermostat-server.cpp b/src/app/clusters/thermostat-server/thermostat-server.cpp index 199632e128655e..a5aef3ff319482 100644 --- a/src/app/clusters/thermostat-server/thermostat-server.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server.cpp @@ -20,8 +20,6 @@ #include #include -#include -#include #include #include #include diff --git a/src/app/clusters/thermostat-user-interface-configuration-server/thermostat-user-interface-configuration-server.cpp b/src/app/clusters/thermostat-user-interface-configuration-server/thermostat-user-interface-configuration-server.cpp index 957990dbac4a86..3bc24f0b994dad 100644 --- a/src/app/clusters/thermostat-user-interface-configuration-server/thermostat-user-interface-configuration-server.cpp +++ b/src/app/clusters/thermostat-user-interface-configuration-server/thermostat-user-interface-configuration-server.cpp @@ -3,8 +3,6 @@ #include #include -#include -#include #include #include #include diff --git a/src/app/clusters/window-covering-server/window-covering-server.cpp b/src/app/clusters/window-covering-server/window-covering-server.cpp index 8b3358ff897e28..f46f9db1278d5f 100644 --- a/src/app/clusters/window-covering-server/window-covering-server.cpp +++ b/src/app/clusters/window-covering-server/window-covering-server.cpp @@ -17,7 +17,6 @@ #include "window-covering-server.h" -#include #include #include #include diff --git a/src/app/clusters/window-covering-server/window-covering-server.h b/src/app/clusters/window-covering-server/window-covering-server.h index 903751c4dd2041..874417ab1d1214 100644 --- a/src/app/clusters/window-covering-server/window-covering-server.h +++ b/src/app/clusters/window-covering-server/window-covering-server.h @@ -18,7 +18,6 @@ #pragma once #include "window-covering-delegate.h" -#include #include #include #include diff --git a/src/app/util/af-types.h b/src/app/util/af-types.h index 382a4bec755ebe..74a7dd426dd611 100644 --- a/src/app/util/af-types.h +++ b/src/app/util/af-types.h @@ -34,9 +34,12 @@ #include // EmberAfAttributeMetadata #include +#include #include #include +#include + #ifdef EZSP_HOST #include "app/util/ezsp/ezsp-enum.h" #endif @@ -734,7 +737,7 @@ typedef struct #endif #ifdef ZCL_USING_LEVEL_CONTROL_CLUSTER_SERVER bool hasCurrentLevelValue; - uint8_t currentLevelValue; + chip::app::DataModel::Nullable currentLevelValue; #endif #ifdef ZCL_USING_THERMOSTAT_CLUSTER_SERVER bool hasOccupiedCoolingSetpointValue; @@ -764,17 +767,17 @@ typedef struct #endif // ZCL_USING_COLOR_CONTROL_CLUSTER_SERVER #ifdef ZCL_USING_DOOR_LOCK_CLUSTER_SERVER bool hasLockStateValue; - uint8_t lockStateValue; + chip::app::DataModel::Nullable lockStateValue; #endif #ifdef ZCL_USING_WINDOW_COVERING_CLUSTER_SERVER bool hasCurrentPositionLiftPercentageValue; - uint8_t currentPositionLiftPercentageValue; + chip::app::DataModel::Nullable currentPositionLiftPercentageValue; bool hasCurrentPositionTiltPercentageValue; - uint8_t currentPositionTiltPercentageValue; + chip::app::DataModel::Nullable currentPositionTiltPercentageValue; bool hasTargetPositionLiftPercent100thsValue; - uint16_t targetPositionLiftPercent100thsValue; + chip::app::DataModel::Nullable targetPositionLiftPercent100thsValue; bool hasTargetPositionTiltPercent100thsValue; - uint16_t targetPositionTiltPercent100thsValue; + chip::app::DataModel::Nullable targetPositionTiltPercent100thsValue; #endif } EmberAfSceneTableEntry; diff --git a/src/app/util/attribute-storage.cpp b/src/app/util/attribute-storage.cpp index db55e2bd6e1d7e..3c9fac5a09a5b6 100644 --- a/src/app/util/attribute-storage.cpp +++ b/src/app/util/attribute-storage.cpp @@ -322,7 +322,11 @@ EmberAfStatus emAfClusterPreAttributeChangedCallback(const app::ConcreteAttribut const EmberAfCluster * cluster = emberAfFindServerCluster(attributePath.mEndpointId, attributePath.mClusterId); if (cluster == nullptr) { - return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; + if (!emberAfEndpointIsEnabled(attributePath.mEndpointId)) + { + return EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT; + } + return EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER; } EmberAfStatus status = EMBER_ZCL_STATUS_SUCCESS; @@ -591,23 +595,27 @@ EmberAfStatus emAfReadOrWriteAttribute(EmberAfAttributeSearchRecord * attRecord, } } } + + // Attribute is not in the cluster. + return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; } - else - { // Not the cluster we are looking for - attributeOffsetIndex = static_cast(attributeOffsetIndex + cluster->clusterSize); - } + + // Not the cluster we are looking for + attributeOffsetIndex = static_cast(attributeOffsetIndex + cluster->clusterSize); } + + // Cluster is not in the endpoint. + return EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER; } - else - { // Not the endpoint we are looking for - // Dynamic endpoints are external and don't factor into storage size - if (!isDynamicEndpoint) - { - attributeOffsetIndex = static_cast(attributeOffsetIndex + emAfEndpoints[ep].endpointType->endpointSize); - } + + // Not the endpoint we are looking for + // Dynamic endpoints are external and don't factor into storage size + if (!isDynamicEndpoint) + { + attributeOffsetIndex = static_cast(attributeOffsetIndex + emAfEndpoints[ep].endpointType->endpointSize); } } - return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; // Sorry, attribute was not found. + return EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT; // Sorry, endpoint was not found. } const EmberAfEndpointType * emberAfFindEndpointType(chip::EndpointId endpointId) diff --git a/src/app/util/attribute-table.cpp b/src/app/util/attribute-table.cpp index 4012932b2dc381..6e4106ead2d02d 100644 --- a/src/app/util/attribute-table.cpp +++ b/src/app/util/attribute-table.cpp @@ -212,8 +212,9 @@ static bool IsNullValue(const uint8_t * data, uint16_t dataLen, bool isAttribute // writes an attribute (identified by clusterID and attrID to the given value. // this returns: -// - EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE: if attribute isnt supported by the device (the -// device is not found in the attribute table) +// - EMBER_ZCL_STATUS_UNSUPPORTED_ENDPOINT: if endpoint isn't supported by the device. +// - EMBER_ZCL_STATUS_UNSUPPORTED_CLUSTER: if cluster isn't supported on the endpoint. +// - EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE: if attribute isn't supported in the cluster. // - EMBER_ZCL_STATUS_INVALID_DATA_TYPE: if the data type passed in doesnt match the type // stored in the attribute table // - EMBER_ZCL_STATUS_UNSUPPORTED_WRITE: if the attribute isnt writable @@ -236,13 +237,13 @@ EmberAfStatus emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, Attribu { const EmberAfAttributeMetadata * metadata = nullptr; EmberAfAttributeSearchRecord record; - record.endpoint = endpoint; - record.clusterId = cluster; - record.attributeId = attributeID; - emAfReadOrWriteAttribute(&record, &metadata, - nullptr, // buffer - 0, // buffer size - false); // write? + record.endpoint = endpoint; + record.clusterId = cluster; + record.attributeId = attributeID; + EmberAfStatus status = emAfReadOrWriteAttribute(&record, &metadata, + nullptr, // buffer + 0, // buffer size + false); // write? // if we dont support that attribute if (metadata == nullptr) @@ -250,7 +251,7 @@ EmberAfStatus emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, Attribu emberAfAttributesPrintln("%pep %x clus " ChipLogFormatMEI " attr " ChipLogFormatMEI " not supported", "WRITE ERR: ", endpoint, ChipLogValueMEI(cluster), ChipLogValueMEI(attributeID)); emberAfAttributesFlush(); - return EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE; + return status; } // if the data type specified by the caller is incorrect @@ -329,8 +330,7 @@ EmberAfStatus emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, Attribu // Pre-write attribute callback specific // to the cluster that the attribute lives in. - EmberAfStatus status = - emAfClusterPreAttributeChangedCallback(attributePath, dataType, emberAfAttributeSize(metadata), data); + status = emAfClusterPreAttributeChangedCallback(attributePath, dataType, emberAfAttributeSize(metadata), data); // Ignore the following write operation and return success if (status == EMBER_ZCL_STATUS_WRITE_IGNORED) diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp index 3c940a83a05333..dee7c35902c548 100644 --- a/src/app/util/util.cpp +++ b/src/app/util/util.cpp @@ -16,8 +16,8 @@ */ #include "app/util/common.h" -#include #include +#include #include #include #include @@ -84,8 +84,7 @@ bool emberAfIsDeviceIdentifying(EndpointId endpoint) { #ifdef ZCL_USING_IDENTIFY_CLUSTER_SERVER uint16_t identifyTime; - EmberAfStatus status = emberAfReadServerAttribute(endpoint, app::Clusters::Identify::Id, ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, - (uint8_t *) &identifyTime, sizeof(identifyTime)); + EmberAfStatus status = app::Clusters::Identify::Attributes::IdentifyTime::Get(endpoint, &identifyTime); return (status == EMBER_ZCL_STATUS_SUCCESS && 0 < identifyTime); #else return false;