From d048afccdeec0b2ed3eb61f6d6d3605f999f0596 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 18 Jul 2024 10:16:39 -0400 Subject: [PATCH 1/5] Let the read implementation return the error status for failed reads. The checkpoint logic and error statuses are duplicated between Engine.cpp and ember-compatibility-functions. This change makes the code consistent either error out (with something that the engine can handle) or encode success. --- .../util/ember-compatibility-functions.cpp | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 676197be9ab2f2..9288054e338732 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -177,16 +177,6 @@ CHIP_ERROR SendSuccessStatus(AttributeReportIB::Builder & aAttributeReport, Attr return aAttributeReport.EndOfAttributeReportIB(); } -CHIP_ERROR SendFailureStatus(const ConcreteAttributePath & aPath, AttributeReportIBs::Builder & aAttributeReports, - Protocols::InteractionModel::Status aStatus, TLV::TLVWriter * aReportCheckpoint) -{ - if (aReportCheckpoint != nullptr) - { - aAttributeReports.Rollback(*aReportCheckpoint); - } - return aAttributeReports.EncodeAttributeStatus(aPath, StatusIB(aStatus)); -} - // Helper function for trying to read an attribute value via an // AttributeAccessInterface. On failure, the read has failed. On success, the // aTriedEncode outparam is set to whether the AttributeAccessInterface tried to encode a value. @@ -302,7 +292,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b if (attributeCluster == nullptr && attributeMetadata == nullptr) { - return SendFailureStatus(aPath, aAttributeReports, UnsupportedAttributeStatus(aPath), nullptr); + return CHIP_IM_GLOBAL_STATUS_VALUE(UnsupportedAttributeStatus(aPath)); } // Check access control. A failed check will disallow the operation, and may or may not generate an attribute report @@ -319,8 +309,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b { return CHIP_NO_ERROR; } - - return SendFailureStatus(aPath, aAttributeReports, Protocols::InteractionModel::Status::UnsupportedAccess, nullptr); + return CHIP_IM_GLOBAL_STATUS(UnsupportedAccess); } } @@ -340,10 +329,6 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b } // Read attribute using Ember, if it doesn't have an override. - - TLV::TLVWriter backup; - aAttributeReports.Checkpoint(backup); - AttributeReportIB::Builder & attributeReport = aAttributeReports.CreateAttributeReport(); ReturnErrorOnFailure(aAttributeReports.GetError()); @@ -579,7 +564,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b return SendSuccessStatus(attributeReport, attributeDataIBBuilder); } - return SendFailureStatus(aPath, aAttributeReports, status, &backup); + return CHIP_IM_GLOBAL_STATUS_VALUE(status); } namespace { From 263900f38d93409b68b959b6352052fa14f96a8e Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 18 Jul 2024 10:19:28 -0400 Subject: [PATCH 2/5] Fix typo --- src/app/util/ember-compatibility-functions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 9288054e338732..e747225c4d7d78 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -292,7 +292,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b if (attributeCluster == nullptr && attributeMetadata == nullptr) { - return CHIP_IM_GLOBAL_STATUS_VALUE(UnsupportedAttributeStatus(aPath)); + return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(UnsupportedAttributeStatus(aPath)); } // Check access control. A failed check will disallow the operation, and may or may not generate an attribute report @@ -564,7 +564,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b return SendSuccessStatus(attributeReport, attributeDataIBBuilder); } - return CHIP_IM_GLOBAL_STATUS_VALUE(status); + return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status); } namespace { From 8dffdf821b04f16ad4dfcbf4746a908e54575d83 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 18 Jul 2024 10:28:43 -0400 Subject: [PATCH 3/5] One more code cleanup for return values. No more global statuses --- .../util/ember-compatibility-functions.cpp | 343 ++++++++---------- 1 file changed, 160 insertions(+), 183 deletions(-) diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index e747225c4d7d78..1b2e6ba1f9f72c 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -171,12 +171,6 @@ CHIP_ERROR ReadClusterDataVersion(const ConcreteClusterPath & aConcreteClusterPa return CHIP_NO_ERROR; } -CHIP_ERROR SendSuccessStatus(AttributeReportIB::Builder & aAttributeReport, AttributeDataIB::Builder & aAttributeDataIBBuilder) -{ - ReturnErrorOnFailure(aAttributeDataIBBuilder.EndOfAttributeDataIB()); - return aAttributeReport.EndOfAttributeReportIB(); -} - // Helper function for trying to read an attribute value via an // AttributeAccessInterface. On failure, the read has failed. On success, the // aTriedEncode outparam is set to whether the AttributeAccessInterface tried to encode a value. @@ -357,214 +351,197 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b static_cast(gEmberAttributeIOBufferSpan.size()), /* write = */ false); - if (status == Status::Success) + if (status != Status::Success) { - EmberAfAttributeType attributeType = attributeMetadata->attributeType; - bool isNullable = attributeMetadata->IsNullable(); - TLV::TLVWriter * writer = attributeDataIBBuilder.GetWriter(); - VerifyOrReturnError(writer != nullptr, CHIP_NO_ERROR); - TLV::Tag tag = TLV::ContextTag(AttributeDataIB::Tag::kData); - switch (AttributeBaseType(attributeType)) - { - case ZCL_NO_DATA_ATTRIBUTE_TYPE: // No data - ReturnErrorOnFailure(writer->PutNull(tag)); - break; - case ZCL_BOOLEAN_ATTRIBUTE_TYPE: // Boolean - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer - { - using IntType = OddSizedInteger<3, false>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer - { - using IntType = OddSizedInteger<5, false>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer - { - using IntType = OddSizedInteger<6, false>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer - { - using IntType = OddSizedInteger<7, false>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer - { - using IntType = OddSizedInteger<3, true>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer - { - using IntType = OddSizedInteger<5, true>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer - { - using IntType = OddSizedInteger<6, true>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer - { - using IntType = OddSizedInteger<7, true>; - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_SINGLE_ATTRIBUTE_TYPE: // 32-bit float - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_DOUBLE_ATTRIBUTE_TYPE: // 64-bit float - { - ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); - break; - } - case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: // Char string + return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status); + } + + TLV::TLVWriter * writer = attributeDataIBBuilder.GetWriter(); + VerifyOrReturnError(writer != nullptr, CHIP_NO_ERROR); + + const EmberAfAttributeType attributeType = attributeMetadata->attributeType; + const bool isNullable = attributeMetadata->IsNullable(); + const TLV::Tag tag = TLV::ContextTag(AttributeDataIB::Tag::kData); + + switch (AttributeBaseType(attributeType)) + { + case ZCL_NO_DATA_ATTRIBUTE_TYPE: // No data + ReturnErrorOnFailure(writer->PutNull(tag)); + break; + case ZCL_BOOLEAN_ATTRIBUTE_TYPE: // Boolean + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer + { + using IntType = OddSizedInteger<3, false>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer + { + using IntType = OddSizedInteger<5, false>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer + { + using IntType = OddSizedInteger<6, false>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer + { + using IntType = OddSizedInteger<7, false>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer + { + using IntType = OddSizedInteger<3, true>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer + { + using IntType = OddSizedInteger<5, true>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer + { + using IntType = OddSizedInteger<6, true>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer + { + using IntType = OddSizedInteger<7, true>; + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + } + case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_SINGLE_ATTRIBUTE_TYPE: // 32-bit float + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_DOUBLE_ATTRIBUTE_TYPE: // 64-bit float + ReturnErrorOnFailure(attributeBufferToNumericTlvData(*writer, isNullable)); + break; + case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: // Char string + { + char * actualData = reinterpret_cast(gEmberAttributeIOBufferSpan.data() + 1); + uint8_t dataLength = gEmberAttributeIOBufferSpan[0]; + if (dataLength == 0xFF) { - char * actualData = reinterpret_cast(gEmberAttributeIOBufferSpan.data() + 1); - uint8_t dataLength = gEmberAttributeIOBufferSpan[0]; - if (dataLength == 0xFF) + if (isNullable) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + ReturnErrorOnFailure(writer->PutNull(tag)); } else { - ReturnErrorOnFailure(writer->PutString(tag, actualData, dataLength)); + return CHIP_ERROR_INCORRECT_STATE; } - break; } - case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE: { - char * actualData = - reinterpret_cast(gEmberAttributeIOBufferSpan.data() + 2); // The pascal string contains 2 bytes length - uint16_t dataLength; - memcpy(&dataLength, gEmberAttributeIOBufferSpan.data(), sizeof(dataLength)); - if (dataLength == 0xFFFF) + else + { + ReturnErrorOnFailure(writer->PutString(tag, actualData, dataLength)); + } + break; + } + case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE: { + char * actualData = + reinterpret_cast(gEmberAttributeIOBufferSpan.data() + 2); // The pascal string contains 2 bytes length + uint16_t dataLength; + memcpy(&dataLength, gEmberAttributeIOBufferSpan.data(), sizeof(dataLength)); + if (dataLength == 0xFFFF) + { + if (isNullable) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + ReturnErrorOnFailure(writer->PutNull(tag)); } else { - ReturnErrorOnFailure(writer->PutString(tag, actualData, dataLength)); + return CHIP_ERROR_INCORRECT_STATE; } - break; } - case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: // Octet string + else { - uint8_t * actualData = gEmberAttributeIOBufferSpan.data() + 1; - uint8_t dataLength = gEmberAttributeIOBufferSpan[0]; - if (dataLength == 0xFF) + ReturnErrorOnFailure(writer->PutString(tag, actualData, dataLength)); + } + break; + } + case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: // Octet string + { + uint8_t * actualData = gEmberAttributeIOBufferSpan.data() + 1; + uint8_t dataLength = gEmberAttributeIOBufferSpan[0]; + if (dataLength == 0xFF) + { + if (isNullable) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + ReturnErrorOnFailure(writer->PutNull(tag)); } else { - ReturnErrorOnFailure(writer->Put(tag, chip::ByteSpan(actualData, dataLength))); + return CHIP_ERROR_INCORRECT_STATE; } - break; } - case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE: { - uint8_t * actualData = gEmberAttributeIOBufferSpan.data() + 2; // The pascal string contains 2 bytes length - uint16_t dataLength; - memcpy(&dataLength, gEmberAttributeIOBufferSpan.data(), sizeof(dataLength)); - if (dataLength == 0xFFFF) + else + { + ReturnErrorOnFailure(writer->Put(tag, chip::ByteSpan(actualData, dataLength))); + } + break; + } + case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE: { + uint8_t * actualData = gEmberAttributeIOBufferSpan.data() + 2; // The pascal string contains 2 bytes length + uint16_t dataLength; + memcpy(&dataLength, gEmberAttributeIOBufferSpan.data(), sizeof(dataLength)); + if (dataLength == 0xFFFF) + { + if (isNullable) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + ReturnErrorOnFailure(writer->PutNull(tag)); } else { - ReturnErrorOnFailure(writer->Put(tag, chip::ByteSpan(actualData, dataLength))); + return CHIP_ERROR_INCORRECT_STATE; } - break; } - default: - ChipLogError(DataManagement, "Attribute type 0x%x not handled", static_cast(attributeType)); - status = Status::Failure; + else + { + ReturnErrorOnFailure(writer->Put(tag, chip::ByteSpan(actualData, dataLength))); } + break; } - - if (status == Protocols::InteractionModel::Status::Success) - { - return SendSuccessStatus(attributeReport, attributeDataIBBuilder); + default: + ChipLogError(DataManagement, "Attribute type 0x%x not handled", static_cast(attributeType)); + return CHIP_IM_GLOBAL_STATUS(Failure); } - return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status); + // If we got this far, write succeeded. Encode the success by terminating the write + ReturnErrorOnFailure(attributeDataIBBuilder.EndOfAttributeDataIB()); + return attributeReport.EndOfAttributeReportIB(); } namespace { From 7f6b56e37b48d3b924aa38f639358e3c5667479a Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 18 Jul 2024 10:35:33 -0400 Subject: [PATCH 4/5] minor update to kick ci --- .../util/ember-compatibility-functions.cpp | 40 ++++--------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 1b2e6ba1f9f72c..67d344eb05bdb8 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -455,14 +455,8 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b uint8_t dataLength = gEmberAttributeIOBufferSpan[0]; if (dataLength == 0xFF) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + VerifyOrReturnError(isNullable, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(writer->PutNull(tag)); } else { @@ -477,14 +471,8 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b memcpy(&dataLength, gEmberAttributeIOBufferSpan.data(), sizeof(dataLength)); if (dataLength == 0xFFFF) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + VerifyOrReturnError(isNullable, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(writer->PutNull(tag)); } else { @@ -498,14 +486,8 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b uint8_t dataLength = gEmberAttributeIOBufferSpan[0]; if (dataLength == 0xFF) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + VerifyOrReturnError(isNullable, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(writer->PutNull(tag)); } else { @@ -519,14 +501,8 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b memcpy(&dataLength, gEmberAttributeIOBufferSpan.data(), sizeof(dataLength)); if (dataLength == 0xFFFF) { - if (isNullable) - { - ReturnErrorOnFailure(writer->PutNull(tag)); - } - else - { - return CHIP_ERROR_INCORRECT_STATE; - } + VerifyOrReturnError(isNullable, CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(writer->PutNull(tag)); } else { From e7b8944511b8a7378078ca49526e0171282648e3 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 18 Jul 2024 11:55:23 -0400 Subject: [PATCH 5/5] Update src/app/util/ember-compatibility-functions.cpp Co-authored-by: Boris Zbarsky --- src/app/util/ember-compatibility-functions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 67d344eb05bdb8..88aae59da51a56 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -515,7 +515,8 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b return CHIP_IM_GLOBAL_STATUS(Failure); } - // If we got this far, write succeeded. Encode the success by terminating the write + // If we got this far, placing the data to be read in the output TLVWriter succeeded. + // Try to terminate our attribute report to signal success. ReturnErrorOnFailure(attributeDataIBBuilder.EndOfAttributeDataIB()); return attributeReport.EndOfAttributeReportIB(); }