From 163321257a603d385bb96377685f338ce5682037 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 18 Nov 2021 18:33:55 -0500 Subject: [PATCH] Disallow writes to readonly attributes via AttributeAccessInterface (#11942) * Disallow writes to readonly attributes even when the writes are intercepted. Need to move the IsReadOnly() check higher up the callstack. * Mark attributes in test cluster writable as needed. --- examples/chip-tool/templates/commands.zapt | 8 ++ src/app/util/af-types.h | 5 + src/app/util/af.h | 7 -- src/app/util/attribute-table.cpp | 4 +- .../util/ember-compatibility-functions.cpp | 49 +++++---- .../templates/app/CHIPClusters-src.zapt | 2 + .../templates/app/CHIPClusters.zapt | 2 + .../zcl/data-model/chip/test-cluster.xml | 6 +- .../java/templates/CHIPClusters-JNI.zapt | 3 + .../java/templates/ChipClusters-java.zapt | 6 + .../ClusterInfo-write-interaction.zapt | 2 + .../python/chip/clusters/CHIPClusters.py | 3 + .../CHIP/zap-generated/CHIPClustersObjc.h | 3 + .../CHIP/zap-generated/CHIPClustersObjc.mm | 103 ++++++++++++++++++ .../CHIP/zap-generated/CHIPTestClustersObjc.h | 3 - .../zap-generated/CHIPTestClustersObjc.mm | 103 ------------------ .../zap-generated/endpoint_config.h | 7 +- .../zap-generated/endpoint_config.h | 7 +- 18 files changed, 177 insertions(+), 146 deletions(-) diff --git a/examples/chip-tool/templates/commands.zapt b/examples/chip-tool/templates/commands.zapt index f20e584ccb24b0..508fd0df266e1e 100644 --- a/examples/chip-tool/templates/commands.zapt +++ b/examples/chip-tool/templates/commands.zapt @@ -459,6 +459,9 @@ private: }; {{#if isWritableAttribute}} +{{! No list support for writing yet. Need to figure out how to represent the + values. }} +{{#unless isList}} class Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public ModelCommand { public: @@ -494,6 +497,7 @@ private: {{chipType}} mValue; }; +{{/unless}} {{/if}} {{#if isReportableAttribute}} class Report{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public ModelCommand @@ -563,7 +567,11 @@ void registerCluster{{asUpperCamelCase name}}(Commands & commands) {{#chip_server_cluster_attributes}} make_unique(), // {{#if isWritableAttribute}} + {{! No list support for writing yet. Need to figure out how to + represent the values. }} + {{#unless isList}} make_unique(), // + {{/unless}} {{/if}} {{#if isReportableAttribute}} make_unique(), // diff --git a/src/app/util/af-types.h b/src/app/util/af-types.h index 570a77d0a508ef..3f521173e79eef 100644 --- a/src/app/util/af-types.h +++ b/src/app/util/af-types.h @@ -217,6 +217,11 @@ struct EmberAfAttributeMetadata * Check whether this attribute is nullable. */ bool IsNullable() const { return mask & ATTRIBUTE_MASK_NULLABLE; } + + /** + * Check whether this attribute is readonly. + */ + bool IsReadOnly() const { return !(mask & ATTRIBUTE_MASK_WRITABLE); } }; /** diff --git a/src/app/util/af.h b/src/app/util/af.h index 6900ef11a37efb..2a9824fffb7a4d 100644 --- a/src/app/util/af.h +++ b/src/app/util/af.h @@ -373,13 +373,6 @@ uint8_t emberAfGetDataSize(uint8_t dataType); */ #define emberAfClusterIsManufacturerSpecific(cluster) ((cluster)->clusterId >= 0xFC00) -/** - * @brief macro that returns true if attribute is read only. - * - * @param metadata EmberAfAttributeMetadata* to consider. - */ -#define emberAfAttributeIsReadOnly(metadata) (((metadata)->mask & ATTRIBUTE_MASK_WRITABLE) == 0) - /** * @brief macro that returns true if client attribute, and false if server. * diff --git a/src/app/util/attribute-table.cpp b/src/app/util/attribute-table.cpp index be56614aa65267..a9b62f698c1fe5 100644 --- a/src/app/util/attribute-table.cpp +++ b/src/app/util/attribute-table.cpp @@ -296,7 +296,7 @@ void emberAfPrintAttributeTable(void) emberAfAttributesPrint("%2x", mfgCode); } emberAfAttributesPrint(" / %x (%x) / %p / %p / ", metaData->attributeType, emberAfAttributeSize(metaData), - (emberAfAttributeIsReadOnly(metaData) ? "RO" : "RW"), + (metaData->IsReadOnly() ? "RO" : "RW"), (emberAfAttributeIsTokenized(metaData) ? " token " : (emberAfAttributeIsExternal(metaData) ? "extern " : " RAM "))); @@ -524,7 +524,7 @@ EmberAfStatus emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, Attribu return EMBER_ZCL_STATUS_INVALID_DATA_TYPE; } - if (emberAfAttributeIsReadOnly(metadata)) + if (metadata->IsReadOnly()) { emberAfAttributesPrintln("%pattr not writable", "WRITE ERR: "); emberAfAttributesFlush(); diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 949dd6703c6745..3f4574b1a1b138 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -542,53 +542,58 @@ CHIP_ERROR prepareWriteData(const EmberAfAttributeMetadata * metadata, TLV::TLVR } } // namespace -static Protocols::InteractionModel::Status WriteSingleClusterDataInternal(ClusterInfo & aClusterInfo, TLV::TLVReader & aReader, - WriteHandler * apWriteHandler) +static Protocols::InteractionModel::Status WriteSingleClusterDataInternal(const ConcreteAttributePath aPath, + const EmberAfAttributeMetadata * aMetadata, + TLV::TLVReader & aReader, WriteHandler * apWriteHandler) { - // Passing nullptr as buf to emberAfReadAttribute means we only need attribute type here, and ember will not do data read & - // copy in this case. - const EmberAfAttributeMetadata * attributeMetadata = emberAfLocateAttributeMetadata( - aClusterInfo.mEndpointId, aClusterInfo.mClusterId, aClusterInfo.mAttributeId, CLUSTER_MASK_SERVER, 0); - - if (attributeMetadata == nullptr) - { - return Protocols::InteractionModel::Status::UnsupportedAttribute; - } - CHIP_ERROR preparationError = CHIP_NO_ERROR; uint16_t dataLen = 0; - if ((preparationError = prepareWriteData(attributeMetadata, aReader, dataLen)) != CHIP_NO_ERROR) + if ((preparationError = prepareWriteData(aMetadata, aReader, dataLen)) != CHIP_NO_ERROR) { ChipLogDetail(Zcl, "Failed to prepare data to write: %s", ErrorStr(preparationError)); return Protocols::InteractionModel::Status::InvalidValue; } - if (dataLen > attributeMetadata->size) + if (dataLen > aMetadata->size) { ChipLogDetail(Zcl, "Data to write exceedes the attribute size claimed."); return Protocols::InteractionModel::Status::InvalidValue; } - return ToInteractionModelStatus(emberAfWriteAttributeExternal(aClusterInfo.mEndpointId, aClusterInfo.mClusterId, - aClusterInfo.mAttributeId, CLUSTER_MASK_SERVER, 0, attributeData, - attributeMetadata->attributeType)); + return ToInteractionModelStatus(emberAfWriteAttributeExternal(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId, + CLUSTER_MASK_SERVER, 0, attributeData, aMetadata->attributeType)); } CHIP_ERROR WriteSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVReader & aReader, WriteHandler * apWriteHandler) { + // TODO: Refactor WriteSingleClusterData and all dependent functions to take ConcreteAttributePath instead of ClusterInfo + // as the input argument. AttributePathParams attributePathParams; attributePathParams.mEndpointId = aClusterInfo.mEndpointId; attributePathParams.mClusterId = aClusterInfo.mClusterId; attributePathParams.mAttributeId = aClusterInfo.mAttributeId; - // TODO: Refactor WriteSingleClusterData and all dependent functions to take ConcreteAttributePath instead of ClusterInfo - // as the input argument. + // Named aPath for now to reduce the amount of code change that needs to + // happen when the above TODO is resolved. + ConcreteAttributePath aPath(aClusterInfo.mEndpointId, aClusterInfo.mClusterId, aClusterInfo.mAttributeId); + const EmberAfAttributeMetadata * attributeMetadata = + emberAfLocateAttributeMetadata(aPath.mEndpointId, aPath.mClusterId, aPath.mAttributeId, CLUSTER_MASK_SERVER, 0); + + if (attributeMetadata == nullptr) + { + return apWriteHandler->AddStatus(attributePathParams, Protocols::InteractionModel::Status::UnsupportedAttribute); + } + + if (attributeMetadata->IsReadOnly()) + { + return apWriteHandler->AddStatus(attributePathParams, Protocols::InteractionModel::Status::UnsupportedWrite); + } + AttributeAccessInterface * attrOverride = findAttributeAccessOverride(aClusterInfo.mEndpointId, aClusterInfo.mClusterId); if (attrOverride != nullptr) { - ConcreteAttributePath path(aClusterInfo.mEndpointId, aClusterInfo.mClusterId, aClusterInfo.mAttributeId); AttributeValueDecoder valueDecoder(aReader); - ReturnErrorOnFailure(attrOverride->Write(path, valueDecoder)); + ReturnErrorOnFailure(attrOverride->Write(aPath, valueDecoder)); if (valueDecoder.TriedDecode()) { @@ -596,7 +601,7 @@ CHIP_ERROR WriteSingleClusterData(ClusterInfo & aClusterInfo, TLV::TLVReader & a } } - auto imCode = WriteSingleClusterDataInternal(aClusterInfo, aReader, apWriteHandler); + auto imCode = WriteSingleClusterDataInternal(aPath, attributeMetadata, aReader, apWriteHandler); return apWriteHandler->AddStatus(attributePathParams, imCode); } diff --git a/src/app/zap-templates/templates/app/CHIPClusters-src.zapt b/src/app/zap-templates/templates/app/CHIPClusters-src.zapt index 968b568f2387c5..7ef524558f29b2 100644 --- a/src/app/zap-templates/templates/app/CHIPClusters-src.zapt +++ b/src/app/zap-templates/templates/app/CHIPClusters-src.zapt @@ -83,6 +83,7 @@ CHIP_ERROR {{asUpperCamelCase parent.name}}Cluster::ReadAttribute{{asUpperCamelC } {{#if isWritableAttribute}} +{{#unless isList}} CHIP_ERROR {{asUpperCamelCase parent.name}}Cluster::WriteAttribute{{asUpperCamelCase name}}(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, {{chipType}} value) { app::WriteClientHandle handle; @@ -91,6 +92,7 @@ CHIP_ERROR {{asUpperCamelCase parent.name}}Cluster::WriteAttribute{{asUpperCamel return mDevice->SendWriteAttributeRequest(std::move(handle), onSuccessCallback, onFailureCallback); } +{{/unless}} {{/if}} {{#if isReportableAttribute}} CHIP_ERROR {{asUpperCamelCase parent.name}}Cluster::SubscribeAttribute{{asUpperCamelCase name}}(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, uint16_t minInterval, uint16_t maxInterval) diff --git a/src/app/zap-templates/templates/app/CHIPClusters.zapt b/src/app/zap-templates/templates/app/CHIPClusters.zapt index 662f6a7b202fa1..af1137626bee30 100644 --- a/src/app/zap-templates/templates/app/CHIPClusters.zapt +++ b/src/app/zap-templates/templates/app/CHIPClusters.zapt @@ -34,7 +34,9 @@ public: {{/chip_server_cluster_attributes}} {{#chip_server_cluster_attributes}} {{#if isWritableAttribute}} + {{#unless isList}} CHIP_ERROR WriteAttribute{{asUpperCamelCase name}}(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback, {{chipType}} value); + {{/unless}} {{/if}} {{/chip_server_cluster_attributes}} {{#chip_server_cluster_attributes}} diff --git a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml index 64b229ef1f5799..cbbac09c60ad5f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml @@ -124,9 +124,9 @@ limitations under the License. octet_string - list_int8u - list_octet_string - list_struct_octet_string + list_int8u + list_octet_string + list_struct_octet_string long_octet_string char_string diff --git a/src/controller/java/templates/CHIPClusters-JNI.zapt b/src/controller/java/templates/CHIPClusters-JNI.zapt index 6cd43c136eebca..36692be8fc443e 100644 --- a/src/controller/java/templates/CHIPClusters-JNI.zapt +++ b/src/controller/java/templates/CHIPClusters-JNI.zapt @@ -78,6 +78,8 @@ JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, {{asLowerCamelCase name}}) {{/chip_cluster_commands}} {{#chip_server_cluster_attributes}} {{#if isWritableAttribute}} +{{! TODO: Lists not supported in attribute writes yet. }} +{{#unless isList}} JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, write{{asUpperCamelCase name}}Attribute)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, {{asJniBasicType type false}} value) { @@ -106,6 +108,7 @@ JNI_METHOD(void, {{asUpperCamelCase ../name}}Cluster, write{{asUpperCamelCase na onSuccess.release(); onFailure.release(); } +{{/unless}} {{/if}} {{#if isReportableAttribute}} diff --git a/src/controller/java/templates/ChipClusters-java.zapt b/src/controller/java/templates/ChipClusters-java.zapt index caa278adedb25e..9898eda122ecb7 100644 --- a/src/controller/java/templates/ChipClusters-java.zapt +++ b/src/controller/java/templates/ChipClusters-java.zapt @@ -204,10 +204,13 @@ public class ChipClusters { read{{asUpperCamelCase name}}Attribute(chipClusterPtr, callback); } {{#if isWritableAttribute}} + {{! TODO: Lists not supported in attribute writes yet. }} + {{#unless isList}} public void write{{asUpperCamelCase name}}Attribute(DefaultClusterCallback callback, {{asJavaBasicType type}} value) { write{{asUpperCamelCase name}}Attribute(chipClusterPtr, callback, value); } + {{/unless}} {{/if}} {{#if isReportableAttribute}} @@ -230,8 +233,11 @@ public class ChipClusters { {{/if}} ); {{#if isWritableAttribute}} + {{! TODO: Lists not supported in attribute writes yet. }} + {{#unless isList}} private native void write{{asUpperCamelCase name}}Attribute(long chipClusterPtr, DefaultClusterCallback callback, {{asJavaBasicType type}} value); + {{/unless}} {{/if}} {{#if isReportableAttribute}} diff --git a/src/controller/java/templates/ClusterInfo-write-interaction.zapt b/src/controller/java/templates/ClusterInfo-write-interaction.zapt index 265fdf4c7ab599..9e713524d7144f 100644 --- a/src/controller/java/templates/ClusterInfo-write-interaction.zapt +++ b/src/controller/java/templates/ClusterInfo-write-interaction.zapt @@ -17,6 +17,7 @@ public class ClusterWriteMapping { Map write{{asUpperCamelCase name}}InteractionInfo = new LinkedHashMap<>(); {{#chip_server_cluster_attributes}} {{#if isWritableAttribute}} + {{#unless isList}} Map write{{asUpperCamelCase ../name}}{{asUpperCamelCase name}}CommandParams = new LinkedHashMap(); CommandParameterInfo {{asLowerCamelCase ../name}}{{asLowerCamelCase name}}CommandParameterInfo = new CommandParameterInfo("value", {{asJavaBasicType type}}.class); write{{asUpperCamelCase ../name}}{{asUpperCamelCase name}}CommandParams.put("value",{{asLowerCamelCase ../name}}{{asLowerCamelCase name}}CommandParameterInfo); @@ -32,6 +33,7 @@ public class ClusterWriteMapping { write{{asUpperCamelCase ../name}}{{asUpperCamelCase name}}CommandParams ); write{{asUpperCamelCase ../name}}InteractionInfo.put("write{{asUpperCamelCase name}}Attribute", write{{asUpperCamelCase ../name}}{{asUpperCamelCase name}}AttributeInteractionInfo); + {{/unless}} {{/if}} {{/chip_server_cluster_attributes}} writeAttributeMap.put("{{asLowerCamelCase name}}", write{{asUpperCamelCase name}}InteractionInfo); diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 862ae3e81e2088..3e653177dd448f 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -3499,16 +3499,19 @@ class ChipClusters: "attributeName": "ListInt8u", "attributeId": 0x0000001A, "type": "int", + "writable": True, }, 0x0000001B: { "attributeName": "ListOctetString", "attributeId": 0x0000001B, "type": "bytes", + "writable": True, }, 0x0000001C: { "attributeName": "ListStructOctetString", "attributeId": 0x0000001C, "type": "", + "writable": True, }, 0x0000001D: { "attributeName": "LongOctetString", diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h index f973a692fcd875..8ca1d00260dffe 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h @@ -1536,10 +1536,13 @@ NS_ASSUME_NONNULL_BEGIN - (void)writeAttributeOctetStringWithValue:(NSData * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; - (void)readAttributeListInt8uWithResponseHandler:(ResponseHandler)responseHandler; +- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; - (void)readAttributeListOctetStringWithResponseHandler:(ResponseHandler)responseHandler; +- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; - (void)readAttributeListStructOctetStringWithResponseHandler:(ResponseHandler)responseHandler; +- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; - (void)readAttributeLongOctetStringWithResponseHandler:(ResponseHandler)responseHandler; - (void)writeAttributeLongOctetStringWithValue:(NSData * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm index bb86da4aa5cb37..c6b07621aa3462 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm @@ -6612,6 +6612,40 @@ new CHIPTestClusterListInt8uListAttributeCallbackBridge( }); } +- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler +{ + new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + ListFreer listFreer; + using TypeInfo = TestCluster::Attributes::ListInt8u::TypeInfo; + TypeInfo::Type cppValue; + { + using ListType = std::remove_reference_t; + using ListMemberType = ListMemberTypeGetter::Type; + if (value.count != 0) { + auto * listHolder_0 = new ListHolder(value.count); + if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_0); + for (size_t i = 0; i < value.count; ++i) { + if (![value[i] isKindOfClass:[NSNumber class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_0 = (NSNumber *) value[i]; + listHolder_0->mList[i] = element_0.unsignedCharValue; + } + cppValue = ListType(listHolder_0->mList, value.count); + } else { + cppValue = ListType(); + } + } + auto successFn = Callback::FromCancelable(success); + auto failureFn = Callback::FromCancelable(failure); + return self.cppCluster.WriteAttribute(cppValue, successFn->mContext, successFn->mCall, failureFn->mCall); + }); +} + - (void)readAttributeListOctetStringWithResponseHandler:(ResponseHandler)responseHandler { new CHIPTestClusterListOctetStringListAttributeCallbackBridge( @@ -6620,6 +6654,40 @@ new CHIPTestClusterListOctetStringListAttributeCallbackBridge( }); } +- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler +{ + new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + ListFreer listFreer; + using TypeInfo = TestCluster::Attributes::ListOctetString::TypeInfo; + TypeInfo::Type cppValue; + { + using ListType = std::remove_reference_t; + using ListMemberType = ListMemberTypeGetter::Type; + if (value.count != 0) { + auto * listHolder_0 = new ListHolder(value.count); + if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_0); + for (size_t i = 0; i < value.count; ++i) { + if (![value[i] isKindOfClass:[NSData class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_0 = (NSData *) value[i]; + listHolder_0->mList[i] = [self asByteSpan:element_0]; + } + cppValue = ListType(listHolder_0->mList, value.count); + } else { + cppValue = ListType(); + } + } + auto successFn = Callback::FromCancelable(success); + auto failureFn = Callback::FromCancelable(failure); + return self.cppCluster.WriteAttribute(cppValue, successFn->mContext, successFn->mCall, failureFn->mCall); + }); +} + - (void)readAttributeListStructOctetStringWithResponseHandler:(ResponseHandler)responseHandler { new CHIPTestClusterListStructOctetStringListAttributeCallbackBridge( @@ -6628,6 +6696,41 @@ new CHIPTestClusterListStructOctetStringListAttributeCallbackBridge( }); } +- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler +{ + new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + ListFreer listFreer; + using TypeInfo = TestCluster::Attributes::ListStructOctetString::TypeInfo; + TypeInfo::Type cppValue; + { + using ListType = std::remove_reference_t; + using ListMemberType = ListMemberTypeGetter::Type; + if (value.count != 0) { + auto * listHolder_0 = new ListHolder(value.count); + if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_0); + for (size_t i = 0; i < value.count; ++i) { + if (![value[i] isKindOfClass:[CHIPTestClusterClusterTestListStructOctet class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_0 = (CHIPTestClusterClusterTestListStructOctet *) value[i]; + listHolder_0->mList[i].fabricIndex = element_0.fabricIndex.unsignedLongLongValue; + listHolder_0->mList[i].operationalCert = [self asByteSpan:element_0.operationalCert]; + } + cppValue = ListType(listHolder_0->mList, value.count); + } else { + cppValue = ListType(); + } + } + auto successFn = Callback::FromCancelable(success); + auto failureFn = Callback::FromCancelable(failure); + return self.cppCluster.WriteAttribute(cppValue, successFn->mContext, successFn->mCall, failureFn->mCall); + }); +} + - (void)readAttributeLongOctetStringWithResponseHandler:(ResponseHandler)responseHandler { new CHIPOctetStringAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.h index 132581e0e16299..f5ad34492c4d00 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.h @@ -766,9 +766,6 @@ NS_ASSUME_NONNULL_BEGIN */ @interface CHIPTestTestCluster : CHIPTestCluster -- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; -- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; -- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; - (void)writeAttributeClusterRevisionWithValue:(NSNumber * _Nonnull)value responseHandler:(ResponseHandler)responseHandler; diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.mm index ff46602de8a6c3..f3fbf8a25c0589 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPTestClustersObjc.mm @@ -4994,109 +4994,6 @@ @implementation CHIPTestTestCluster return &_cppCluster; } -- (void)writeAttributeListInt8uWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler -{ - new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { - ListFreer listFreer; - using TypeInfo = TestCluster::Attributes::ListInt8u::TypeInfo; - TypeInfo::Type cppValue; - { - using ListType = std::remove_reference_t; - using ListMemberType = ListMemberTypeGetter::Type; - if (value.count != 0) { - auto * listHolder_0 = new ListHolder(value.count); - if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - listFreer.add(listHolder_0); - for (size_t i = 0; i < value.count; ++i) { - if (![value[i] isKindOfClass:[NSNumber class]]) { - // Wrong kind of value. - return CHIP_ERROR_INVALID_ARGUMENT; - } - auto element_0 = (NSNumber *) value[i]; - listHolder_0->mList[i] = element_0.unsignedCharValue; - } - cppValue = ListType(listHolder_0->mList, value.count); - } else { - cppValue = ListType(); - } - } - auto successFn = Callback::FromCancelable(success); - auto failureFn = Callback::FromCancelable(failure); - return self.cppCluster.WriteAttribute(cppValue, successFn->mContext, successFn->mCall, failureFn->mCall); - }); -} - -- (void)writeAttributeListOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler -{ - new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { - ListFreer listFreer; - using TypeInfo = TestCluster::Attributes::ListOctetString::TypeInfo; - TypeInfo::Type cppValue; - { - using ListType = std::remove_reference_t; - using ListMemberType = ListMemberTypeGetter::Type; - if (value.count != 0) { - auto * listHolder_0 = new ListHolder(value.count); - if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - listFreer.add(listHolder_0); - for (size_t i = 0; i < value.count; ++i) { - if (![value[i] isKindOfClass:[NSData class]]) { - // Wrong kind of value. - return CHIP_ERROR_INVALID_ARGUMENT; - } - auto element_0 = (NSData *) value[i]; - listHolder_0->mList[i] = [self asByteSpan:element_0]; - } - cppValue = ListType(listHolder_0->mList, value.count); - } else { - cppValue = ListType(); - } - } - auto successFn = Callback::FromCancelable(success); - auto failureFn = Callback::FromCancelable(failure); - return self.cppCluster.WriteAttribute(cppValue, successFn->mContext, successFn->mCall, failureFn->mCall); - }); -} - -- (void)writeAttributeListStructOctetStringWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler -{ - new CHIPDefaultSuccessCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { - ListFreer listFreer; - using TypeInfo = TestCluster::Attributes::ListStructOctetString::TypeInfo; - TypeInfo::Type cppValue; - { - using ListType = std::remove_reference_t; - using ListMemberType = ListMemberTypeGetter::Type; - if (value.count != 0) { - auto * listHolder_0 = new ListHolder(value.count); - if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { - return CHIP_ERROR_INVALID_ARGUMENT; - } - listFreer.add(listHolder_0); - for (size_t i = 0; i < value.count; ++i) { - if (![value[i] isKindOfClass:[CHIPTestClusterClusterTestListStructOctet class]]) { - // Wrong kind of value. - return CHIP_ERROR_INVALID_ARGUMENT; - } - auto element_0 = (CHIPTestClusterClusterTestListStructOctet *) value[i]; - listHolder_0->mList[i].fabricIndex = element_0.fabricIndex.unsignedLongLongValue; - listHolder_0->mList[i].operationalCert = [self asByteSpan:element_0.operationalCert]; - } - cppValue = ListType(listHolder_0->mList, value.count); - } else { - cppValue = ListType(); - } - } - auto successFn = Callback::FromCancelable(success); - auto failureFn = Callback::FromCancelable(failure); - return self.cppCluster.WriteAttribute(cppValue, successFn->mContext, successFn->mCall, failureFn->mCall); - }); -} - - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnull)value responseHandler:(ResponseHandler)responseHandler { diff --git a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h index 2a0f4ba6b924f0..10532ccc715d36 100644 --- a/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h +++ b/zzz_generated/all-clusters-app/zap-generated/endpoint_config.h @@ -1819,9 +1819,10 @@ { 0x0015, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* enum8 */ \ { 0x0016, ZAP_TYPE(ENUM16), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* enum16 */ \ { 0x0019, ZAP_TYPE(OCTET_STRING), 11, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* octet_string */ \ - { 0x001A, ZAP_TYPE(ARRAY), 10, 0, ZAP_LONG_DEFAULTS_INDEX(3291) }, /* list_int8u */ \ - { 0x001B, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3301) }, /* list_octet_string */ \ - { 0x001C, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3555) }, /* list_struct_octet_string */ \ + { 0x001A, ZAP_TYPE(ARRAY), 10, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(3291) }, /* list_int8u */ \ + { 0x001B, ZAP_TYPE(ARRAY), 254, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(3301) }, /* list_octet_string */ \ + { 0x001C, ZAP_TYPE(ARRAY), 254, ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_LONG_DEFAULTS_INDEX(3555) }, /* list_struct_octet_string */ \ { 0x001D, ZAP_TYPE(LONG_OCTET_STRING), 1002, ZAP_ATTRIBUTE_MASK(WRITABLE), \ ZAP_EMPTY_DEFAULT() }, /* long_octet_string */ \ { 0x001E, ZAP_TYPE(CHAR_STRING), 11, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* char_string */ \ diff --git a/zzz_generated/tv-casting-app/zap-generated/endpoint_config.h b/zzz_generated/tv-casting-app/zap-generated/endpoint_config.h index 2628680f56583a..f08a3c3e9b7c57 100644 --- a/zzz_generated/tv-casting-app/zap-generated/endpoint_config.h +++ b/zzz_generated/tv-casting-app/zap-generated/endpoint_config.h @@ -1484,9 +1484,10 @@ { 0x0015, ZAP_TYPE(ENUM8), 1, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* enum8 */ \ { 0x0016, ZAP_TYPE(ENUM16), 2, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_SIMPLE_DEFAULT(0) }, /* enum16 */ \ { 0x0019, ZAP_TYPE(OCTET_STRING), 11, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_EMPTY_DEFAULT() }, /* octet_string */ \ - { 0x001A, ZAP_TYPE(ARRAY), 10, 0, ZAP_LONG_DEFAULTS_INDEX(3188) }, /* list_int8u */ \ - { 0x001B, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3198) }, /* list_octet_string */ \ - { 0x001C, ZAP_TYPE(ARRAY), 254, 0, ZAP_LONG_DEFAULTS_INDEX(3452) }, /* list_struct_octet_string */ \ + { 0x001A, ZAP_TYPE(ARRAY), 10, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(3188) }, /* list_int8u */ \ + { 0x001B, ZAP_TYPE(ARRAY), 254, ZAP_ATTRIBUTE_MASK(WRITABLE), ZAP_LONG_DEFAULTS_INDEX(3198) }, /* list_octet_string */ \ + { 0x001C, ZAP_TYPE(ARRAY), 254, ZAP_ATTRIBUTE_MASK(WRITABLE), \ + ZAP_LONG_DEFAULTS_INDEX(3452) }, /* list_struct_octet_string */ \ { 0x001D, ZAP_TYPE(LONG_OCTET_STRING), 1002, ZAP_ATTRIBUTE_MASK(WRITABLE), \ ZAP_EMPTY_DEFAULT() }, /* long_octet_string */ \ { 0xFFFD, ZAP_TYPE(INT16U), 2, 0, ZAP_SIMPLE_DEFAULT(0x0001) }, /* ClusterRevision */ \