diff --git a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp index dfbbf055eff5b2..1f3816a7ba9cb0 100644 --- a/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp +++ b/src/app/clusters/operational-credentials-server/operational-credentials-server.cpp @@ -69,6 +69,7 @@ class OperationalCredentialsAttrAccess : public AttributeAccessInterface private: CHIP_ERROR ReadFabricsList(EndpointId endpoint, AttributeValueEncoder & aEncoder); + CHIP_ERROR ReadRootCertificates(EndpointId endpoint, AttributeValueEncoder & aEncoder); }; CHIP_ERROR OperationalCredentialsAttrAccess::ReadFabricsList(EndpointId endpoint, AttributeValueEncoder & aEncoder) @@ -96,6 +97,24 @@ CHIP_ERROR OperationalCredentialsAttrAccess::ReadFabricsList(EndpointId endpoint }); } +CHIP_ERROR OperationalCredentialsAttrAccess::ReadRootCertificates(EndpointId endpoint, AttributeValueEncoder & aEncoder) +{ + return aEncoder.EncodeList([](const TagBoundEncoder & encoder) -> CHIP_ERROR { + for (auto & fabricInfo : Server::GetInstance().GetFabricTable()) + { + ByteSpan cert; + + if (!fabricInfo.IsInitialized()) + continue; + + ReturnErrorOnFailure(fabricInfo.GetRootCert(cert)); + ReturnErrorOnFailure(encoder.Encode(cert)); + } + + return CHIP_NO_ERROR; + }); +} + OperationalCredentialsAttrAccess gAttrAccess; CHIP_ERROR OperationalCredentialsAttrAccess::Read(const ConcreteAttributePath & aPath, AttributeValueEncoder & aEncoder) @@ -107,6 +126,9 @@ CHIP_ERROR OperationalCredentialsAttrAccess::Read(const ConcreteAttributePath & case Attributes::FabricsList::Id: { return ReadFabricsList(aPath.mEndpointId, aEncoder); } + case Attributes::TrustedRootCertificates::Id: { + return ReadRootCertificates(aPath.mEndpointId, aEncoder); + } default: break; } diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 68988712cd1090..9587df8099dea4 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -5137,6 +5137,21 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ClusterRevision", "code": 65533, diff --git a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp index 6af16bbecc3a84..aea41f7831cb30 100644 --- a/src/controller/java/zap-generated/CHIPClusters-JNI.cpp +++ b/src/controller/java/zap-generated/CHIPClusters-JNI.cpp @@ -7391,6 +7391,79 @@ class CHIPOperationalCredentialsFabricsListAttributeCallback jobject javaCallbackRef; }; +class CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback + : public Callback::Callback +{ +public: + CHIPOperationalCredentialsTrustedRootCertificatesAttributeCallback(jobject javaCallback) : + Callback::Callback(CallbackFn, this) + { + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + if (env == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + return; + } + + javaCallbackRef = env->NewGlobalRef(javaCallback); + if (javaCallbackRef == nullptr) + { + ChipLogError(Zcl, "Could not create global reference for Java callback"); + } + } + + static void CallbackFn(void * context, const chip::app::DataModel::DecodableList & list) + { + chip::DeviceLayer::StackUnlock unlock; + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); + jobject javaCallbackRef; + + VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env")); + + std::unique_ptr cppCallback( + reinterpret_cast(context)); + + // It's valid for javaCallbackRef to be nullptr if the Java code passed in a null callback. + javaCallbackRef = cppCallback.get()->javaCallbackRef; + VerifyOrReturn(javaCallbackRef != nullptr, + ChipLogProgress(Zcl, "Early return from attribute callback since Java callback is null")); + + jclass arrayListClass; + err = JniReferences::GetInstance().GetClassRef(env, "java/util/ArrayList", arrayListClass); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error using Java ArrayList")); + JniClass arrayListJniClass(arrayListClass); + jmethodID arrayListCtor = env->GetMethodID(arrayListClass, "", "()V"); + jmethodID arrayListAddMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); + VerifyOrReturn(arrayListCtor != nullptr && arrayListAddMethod != nullptr, + ChipLogError(Zcl, "Error finding Java ArrayList methods")); + jobject arrayListObj = env->NewObject(arrayListClass, arrayListCtor); + VerifyOrReturn(arrayListObj != nullptr, ChipLogError(Zcl, "Error creating Java ArrayList")); + + jmethodID javaMethod; + err = JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/util/List;)V", &javaMethod); + VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess() method")); + + auto iter = list.begin(); + while (iter.Next()) + { + auto & entry = iter.GetValue(); + jbyteArray trustedRootCertificates = env->NewByteArray(entry.size()); + env->SetByteArrayRegion(trustedRootCertificates, 0, entry.size(), reinterpret_cast(entry.data())); + env->CallBooleanMethod(arrayListObj, arrayListAddMethod, trustedRootCertificates); + } + VerifyOrReturn(iter.GetStatus() == CHIP_NO_ERROR, + ChipLogError(Zcl, "Error decoding TrustedRootCertificatesAttribute value: %" CHIP_ERROR_FORMAT, + iter.GetStatus().Format())); + + env->ExceptionClear(); + env->CallVoidMethod(javaCallbackRef, javaMethod, arrayListObj); + } + +private: + jobject javaCallbackRef; +}; + class CHIPPowerSourceActiveBatteryFaultsAttributeCallback : public Callback::Callback { @@ -22246,6 +22319,34 @@ JNI_METHOD(void, OperationalCredentialsCluster, readCommissionedFabricsAttribute onFailure.release(); } +JNI_METHOD(void, OperationalCredentialsCluster, readTrustedRootCertificatesAttribute) +(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) +{ + chip::DeviceLayer::StackLock lock; + std::unique_ptr + onSuccess(Platform::New(callback), + Platform::Delete); + VerifyOrReturn(onSuccess.get() != nullptr, + ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY)); + + std::unique_ptr onFailure( + Platform::New(callback), Platform::Delete); + VerifyOrReturn(onFailure.get() != nullptr, + ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY)); + + CHIP_ERROR err = CHIP_NO_ERROR; + OperationalCredentialsCluster * cppCluster = reinterpret_cast(clusterPtr); + VerifyOrReturn(cppCluster != nullptr, + ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE)); + + err = cppCluster->ReadAttributeTrustedRootCertificates(onSuccess->Cancel(), onFailure->Cancel()); + VerifyOrReturn(err == CHIP_NO_ERROR, ReturnIllegalStateException(env, callback, "Error reading attribute", err)); + + onSuccess.release(); + onFailure.release(); +} + JNI_METHOD(void, OperationalCredentialsCluster, readClusterRevisionAttribute) (JNIEnv * env, jobject self, jlong clusterPtr, jobject callback) { diff --git a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java index 00aa981a7f4c13..af12c13132cc5a 100644 --- a/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/zap-generated/chip/devicecontroller/ChipClusters.java @@ -4710,6 +4710,12 @@ public interface FabricsListAttributeCallback { void onError(Exception ex); } + public interface TrustedRootCertificatesAttributeCallback { + void onSuccess(List valueList); + + void onError(Exception ex); + } + public void readFabricsListAttribute(FabricsListAttributeCallback callback) { readFabricsListAttribute(chipClusterPtr, callback); } @@ -4722,6 +4728,11 @@ public void readCommissionedFabricsAttribute(IntegerAttributeCallback callback) readCommissionedFabricsAttribute(chipClusterPtr, callback); } + public void readTrustedRootCertificatesAttribute( + TrustedRootCertificatesAttributeCallback callback) { + readTrustedRootCertificatesAttribute(chipClusterPtr, callback); + } + public void readClusterRevisionAttribute(IntegerAttributeCallback callback) { readClusterRevisionAttribute(chipClusterPtr, callback); } @@ -4735,6 +4746,9 @@ private native void readSupportedFabricsAttribute( private native void readCommissionedFabricsAttribute( long chipClusterPtr, IntegerAttributeCallback callback); + private native void readTrustedRootCertificatesAttribute( + long chipClusterPtr, TrustedRootCertificatesAttributeCallback callback); + private native void readClusterRevisionAttribute( long chipClusterPtr, IntegerAttributeCallback callback); } diff --git a/src/controller/python/chip/clusters/CHIPClusters.cpp b/src/controller/python/chip/clusters/CHIPClusters.cpp index f40feccbe75035..2fadb2cf7286be 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.cpp +++ b/src/controller/python/chip/clusters/CHIPClusters.cpp @@ -832,6 +832,52 @@ static void OnOperationalCredentialsFabricsListListAttributeResponse( } chip::Callback::Callback gOperationalCredentialsFabricsListListAttributeCallback{ OnOperationalCredentialsFabricsListListAttributeResponse, nullptr }; +static void OnOperationalCredentialsTrustedRootCertificatesListAttributeResponse( + void * context, const chip::app::DataModel::DecodableList & list) +{ + size_t count = 0; + CHIP_ERROR err = list.ComputeSize(&count); + if (err != CHIP_NO_ERROR) + { + if (gFailureResponseDelegate != nullptr) + { + gFailureResponseDelegate(EMBER_ZCL_STATUS_INVALID_VALUE); + } + return; + } + + ChipLogProgress(Zcl, " attributeValue:%s", count > 0 ? "" : " []"); + + if (count > 0) + ChipLogProgress(Zcl, " ["); + + auto iter = list.begin(); + while (iter.Next()) + { +#if CHIP_PROGRESS_LOGGING + auto & entry = iter.GetValue(); +#endif // CHIP_PROGRESS_LOGGING + ChipLogProgress(Zcl, " %s,", ByteSpanToString(entry).c_str()); + } + if (iter.GetStatus() != CHIP_NO_ERROR) + { + if (gFailureResponseDelegate != nullptr) + { + gFailureResponseDelegate(EMBER_ZCL_STATUS_INVALID_VALUE); + } + return; + } + + if (count > 0) + ChipLogProgress(Zcl, " ]"); + + if (gSuccessResponseDelegate != nullptr) + gSuccessResponseDelegate(); +} +chip::Callback::Callback + gOperationalCredentialsTrustedRootCertificatesListAttributeCallback{ + OnOperationalCredentialsTrustedRootCertificatesListAttributeResponse, nullptr + }; static void OnPowerSourceActiveBatteryFaultsListAttributeResponse(void * context, const chip::app::DataModel::DecodableList & list) { @@ -5628,6 +5674,18 @@ chip::ChipError::StorageType chip_ime_ReadAttribute_OperationalCredentials_Commi return cluster.ReadAttributeCommissionedFabrics(gInt8uAttributeCallback.Cancel(), gDefaultFailureCallback.Cancel()).AsInteger(); } +chip::ChipError::StorageType chip_ime_ReadAttribute_OperationalCredentials_TrustedRootCertificates( + chip::Controller::Device * device, chip::EndpointId ZCLendpointId, chip::GroupId /* ZCLgroupId */) +{ + VerifyOrReturnError(device != nullptr, CHIP_ERROR_INVALID_ARGUMENT.AsInteger()); + chip::Controller::OperationalCredentialsCluster cluster; + cluster.Associate(device, ZCLendpointId); + return cluster + .ReadAttributeTrustedRootCertificates(gOperationalCredentialsTrustedRootCertificatesListAttributeCallback.Cancel(), + gDefaultFailureCallback.Cancel()) + .AsInteger(); +} + chip::ChipError::StorageType chip_ime_ReadAttribute_OperationalCredentials_ClusterRevision(chip::Controller::Device * device, chip::EndpointId ZCLendpointId, chip::GroupId /* ZCLgroupId */) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 992fd070d582e4..340432d9e6fcc9 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -2561,6 +2561,11 @@ class ChipClusters: "attributeId": 0x00000003, "type": "int", }, + 0x00000004: { + "attributeName": "TrustedRootCertificates", + "attributeId": 0x00000004, + "type": "bytes", + }, 0x0000FFFD: { "attributeName": "ClusterRevision", "attributeId": 0x0000FFFD, @@ -5965,6 +5970,9 @@ def ClusterOperationalCredentials_ReadAttributeSupportedFabrics(self, device: ct def ClusterOperationalCredentials_ReadAttributeCommissionedFabrics(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): return self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_CommissionedFabrics(device, ZCLendpoint, ZCLgroupid) + def ClusterOperationalCredentials_ReadAttributeTrustedRootCertificates(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): + return self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_TrustedRootCertificates(device, ZCLendpoint, ZCLgroupid) + def ClusterOperationalCredentials_ReadAttributeClusterRevision(self, device: ctypes.c_void_p, ZCLendpoint: int, ZCLgroupid: int): return self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_ClusterRevision(device, ZCLendpoint, ZCLgroupid) @@ -8425,6 +8433,10 @@ def InitLib(self, chipLib): self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_CommissionedFabrics.argtypes = [ ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_CommissionedFabrics.restype = ctypes.c_uint32 + # Cluster OperationalCredentials ReadAttribute TrustedRootCertificates + self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_TrustedRootCertificates.argtypes = [ + ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] + self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_TrustedRootCertificates.restype = ctypes.c_uint32 # Cluster OperationalCredentials ReadAttribute ClusterRevision self._chipLib.chip_ime_ReadAttribute_OperationalCredentials_ClusterRevision.argtypes = [ ctypes.c_void_p, ctypes.c_uint8, ctypes.c_uint16] diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge.mm index 58f0694bc222b0..8e078a71b903d1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge.mm @@ -378,6 +378,23 @@ DispatchSuccess(context, @ { @"value" : array }); }; +void CHIPOperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge::OnSuccessFn( + void * context, const chip::app::DataModel::DecodableList & list) +{ + id array = [[NSMutableArray alloc] init]; + auto iter = list.begin(); + while (iter.Next()) { + auto & entry = iter.GetValue(); + [array addObject:[NSData dataWithBytes:entry.data() length:entry.size()]]; + } + if (iter.GetStatus() != CHIP_NO_ERROR) { + OnFailureFn(context, EMBER_ZCL_STATUS_INVALID_VALUE); + return; + } + + DispatchSuccess(context, @ { @"value" : array }); +}; + void CHIPPowerSourceActiveBatteryFaultsListAttributeCallbackBridge::OnSuccessFn( void * context, const chip::app::DataModel::DecodableList & list) { diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge_internal.h b/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge_internal.h index d630388738e32b..e7185ee87c0a23 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge_internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPCallbackBridge_internal.h @@ -332,6 +332,18 @@ class CHIPOperationalCredentialsFabricsListListAttributeCallbackBridge chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptor::DecodableType> & list); }; +class CHIPOperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge + : public CHIPCallbackBridge +{ +public: + CHIPOperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge(dispatch_queue_t queue, ResponseHandler handler, + CHIPActionBlock action, bool keepAlive = false) : + CHIPCallbackBridge(queue, handler, action, OnSuccessFn, + keepAlive){}; + + static void OnSuccessFn(void * context, const chip::app::DataModel::DecodableList & list); +}; + class CHIPPowerSourceActiveBatteryFaultsListAttributeCallbackBridge : public CHIPCallbackBridge { diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h index 1c0593b2cf367f..93a0e97b4c38c7 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.h @@ -1235,6 +1235,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)readAttributeCommissionedFabricsWithResponseHandler:(ResponseHandler)responseHandler; +- (void)readAttributeTrustedRootCertificatesWithResponseHandler:(ResponseHandler)responseHandler; + - (void)readAttributeClusterRevisionWithResponseHandler:(ResponseHandler)responseHandler; @end diff --git a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm index 9b8ac4c0fa0aad..d6515e7b8b36e3 100644 --- a/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/CHIPClustersObjc.mm @@ -3651,6 +3651,14 @@ new CHIPInt8uAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Canc }); } +- (void)readAttributeTrustedRootCertificatesWithResponseHandler:(ResponseHandler)responseHandler +{ + new CHIPOperationalCredentialsTrustedRootCertificatesListAttributeCallbackBridge( + self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { + return self.cppCluster.ReadAttributeTrustedRootCertificates(success, failure); + }); +} + - (void)readAttributeClusterRevisionWithResponseHandler:(ResponseHandler)responseHandler { new CHIPInt16uAttributeCallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) { diff --git a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m index 20e78e75311c67..51d447316916da 100644 --- a/src/darwin/Framework/CHIPTests/CHIPClustersTests.m +++ b/src/darwin/Framework/CHIPTests/CHIPClustersTests.m @@ -16912,6 +16912,25 @@ - (void)testSendClusterOperationalCredentialsReadAttributeCommissionedFabricsWit [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; } +- (void)testSendClusterOperationalCredentialsReadAttributeTrustedRootCertificatesWithResponseHandler +{ + XCTestExpectation * expectation = + [self expectationWithDescription:@"OperationalCredentialsReadAttributeTrustedRootCertificatesWithResponseHandler"]; + + CHIPDevice * device = GetConnectedDevice(); + dispatch_queue_t queue = dispatch_get_main_queue(); + CHIPOperationalCredentials * cluster = [[CHIPOperationalCredentials alloc] initWithDevice:device endpoint:0 queue:queue]; + XCTAssertNotNil(cluster); + + [cluster readAttributeTrustedRootCertificatesWithResponseHandler:^(NSError * err, NSDictionary * values) { + NSLog(@"OperationalCredentials TrustedRootCertificates Error: %@", err); + XCTAssertEqual(err.code, 0); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:kTimeoutInSeconds handler:nil]; +} + - (void)testSendClusterOperationalCredentialsReadAttributeClusterRevisionWithResponseHandler { XCTestExpectation * expectation = diff --git a/src/transport/FabricTable.h b/src/transport/FabricTable.h index 95d4300a11f783..47a4ec3fce353d 100644 --- a/src/transport/FabricTable.h +++ b/src/transport/FabricTable.h @@ -123,7 +123,7 @@ class DLL_EXPORT FabricInfo // TODO - Refactor storing and loading of fabric info from persistent storage. // The op cert array doesn't need to be in RAM except when it's being // transmitted to peer node during CASE session setup. - CHIP_ERROR GetRootCert(ByteSpan & cert) + CHIP_ERROR GetRootCert(ByteSpan & cert) const { ReturnErrorCodeIf(mRootCert.empty(), CHIP_ERROR_INCORRECT_STATE); cert = mRootCert; diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index c543381ca6ac75..2e96e1c9391f32 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -619,6 +619,34 @@ static void OnOperationalCredentialsFabricsListListAttributeResponse( command->SetCommandExitStatus(iter.GetStatus()); } +static void OnOperationalCredentialsTrustedRootCertificatesListAttributeResponse( + void * context, const chip::app::DataModel::DecodableList & list) +{ + ModelCommand * command = static_cast(context); + + size_t count = 0; + CHIP_ERROR err = list.ComputeSize(&count); + if (err != CHIP_NO_ERROR) + { + command->SetCommandExitStatus(err); + return; + } + + ChipLogProgress(chipTool, "OnOperationalCredentialsTrustedRootCertificatesListAttributeResponse: %zu entries", count); + + auto iter = list.begin(); + uint16_t i = 0; + while (iter.Next()) + { +#if CHIP_PROGRESS_LOGGING + auto & entry = iter.GetValue(); +#endif // CHIP_PROGRESS_LOGGING + ++i; + ChipLogProgress(Zcl, " : %zu", entry.size()); + } + command->SetCommandExitStatus(iter.GetStatus()); +} + static void OnPowerSourceActiveBatteryFaultsListAttributeResponse(void * context, const chip::app::DataModel::DecodableList & list) { @@ -15010,6 +15038,7 @@ class ReadOnOffSwitchConfigurationClusterRevision : public ModelCommand | * FabricsList | 0x0001 | | * SupportedFabrics | 0x0002 | | * CommissionedFabrics | 0x0003 | +| * TrustedRootCertificates | 0x0004 | | * ClusterRevision | 0xFFFD | \*----------------------------------------------------------------------------*/ @@ -15346,6 +15375,41 @@ class ReadOperationalCredentialsCommissionedFabrics : public ModelCommand new chip::Callback::Callback(OnDefaultFailureResponse, this); }; +/* + * Attribute TrustedRootCertificates + */ +class ReadOperationalCredentialsTrustedRootCertificates : public ModelCommand +{ +public: + ReadOperationalCredentialsTrustedRootCertificates() : ModelCommand("read") + { + AddArgument("attr-name", "trusted-root-certificates"); + ModelCommand::AddArguments(); + } + + ~ReadOperationalCredentialsTrustedRootCertificates() + { + delete onSuccessCallback; + delete onFailureCallback; + } + + CHIP_ERROR SendCommand(ChipDevice * device, uint8_t endpointId) override + { + ChipLogProgress(chipTool, "Sending cluster (0x003E) command (0x00) on endpoint %" PRIu8, endpointId); + + chip::Controller::OperationalCredentialsCluster cluster; + cluster.Associate(device, endpointId); + return cluster.ReadAttributeTrustedRootCertificates(onSuccessCallback->Cancel(), onFailureCallback->Cancel()); + } + +private: + chip::Callback::Callback * onSuccessCallback = + new chip::Callback::Callback( + OnOperationalCredentialsTrustedRootCertificatesListAttributeResponse, this); + chip::Callback::Callback * onFailureCallback = + new chip::Callback::Callback(OnDefaultFailureResponse, this); +}; + /* * Attribute ClusterRevision */ @@ -26586,6 +26650,7 @@ void registerClusterOperationalCredentials(Commands & commands) make_unique(), // make_unique(), // make_unique(), // + make_unique(), // make_unique(), // }; diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp index c0da73bd03d295..37b468853e99c1 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.cpp @@ -502,6 +502,31 @@ void OperationalCredentialsClusterFabricsListListAttributeFilter(TLV::TLVReader #pragma GCC diagnostic pop #endif // __clang__ +void OperationalCredentialsClusterTrustedRootCertificatesListAttributeFilter(TLV::TLVReader * tlvData, + Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + chip::app::DataModel::DecodableList list; + CHIP_ERROR err = Decode(*tlvData, list); + if (err != CHIP_NO_ERROR) + { + if (onFailureCallback != nullptr) + { + Callback::Callback * cb = + Callback::Callback::FromCancelable(onFailureCallback); + cb->mCall(cb->mContext, EMBER_ZCL_STATUS_INVALID_VALUE); + } + return; + } + + Callback::Callback * cb = + Callback::Callback::FromCancelable(onSuccessCallback); + cb->mCall(cb->mContext, list); +} +#if !defined(__clang__) +#pragma GCC diagnostic pop +#endif // __clang__ + void PowerSourceClusterActiveBatteryFaultsListAttributeFilter(TLV::TLVReader * tlvData, Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.h b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.h index 0a8622772ae39d..0296e3a841e227 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.h +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClientCallbacks.h @@ -230,6 +230,11 @@ typedef void (*OperationalCredentialsFabricsListListAttributeCallback)( void * context, const chip::app::DataModel::DecodableList< chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptor::DecodableType> & data); +void OperationalCredentialsClusterTrustedRootCertificatesListAttributeFilter(chip::TLV::TLVReader * data, + chip::Callback::Cancelable * onSuccessCallback, + chip::Callback::Cancelable * onFailureCallback); +typedef void (*OperationalCredentialsTrustedRootCertificatesListAttributeCallback)( + void * context, const chip::app::DataModel::DecodableList & data); void PowerSourceClusterActiveBatteryFaultsListAttributeFilter(chip::TLV::TLVReader * data, chip::Callback::Cancelable * onSuccessCallback, chip::Callback::Cancelable * onFailureCallback); diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp index 9e40e4691df6b1..c7e7fe53cb346b 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.cpp @@ -9773,6 +9773,18 @@ CHIP_ERROR OperationalCredentialsCluster::ReadAttributeCommissionedFabrics(Callb BasicAttributeFilter); } +CHIP_ERROR OperationalCredentialsCluster::ReadAttributeTrustedRootCertificates(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback) +{ + app::AttributePathParams attributePath; + attributePath.mEndpointId = mEndpoint; + attributePath.mClusterId = mClusterId; + attributePath.mFieldId = 0x00000004; + attributePath.mFlags.Set(app::AttributePathParams::Flags::kFieldIdValid); + return mDevice->SendReadAttributeRequest(attributePath, onSuccessCallback, onFailureCallback, + OperationalCredentialsClusterTrustedRootCertificatesListAttributeFilter); +} + CHIP_ERROR OperationalCredentialsCluster::ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback) { diff --git a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h index 0e7380312fe396..27c639bcb35335 100644 --- a/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h +++ b/zzz_generated/controller-clusters/zap-generated/CHIPClusters.h @@ -1050,6 +1050,8 @@ class DLL_EXPORT OperationalCredentialsCluster : public ClusterBase CHIP_ERROR ReadAttributeFabricsList(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); CHIP_ERROR ReadAttributeSupportedFabrics(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); CHIP_ERROR ReadAttributeCommissionedFabrics(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); + CHIP_ERROR ReadAttributeTrustedRootCertificates(Callback::Cancelable * onSuccessCallback, + Callback::Cancelable * onFailureCallback); CHIP_ERROR ReadAttributeClusterRevision(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback); private: