Add target endpoint to `CommissioningWindowOpener` (#34425)

* Add target endpoint id to commissioning window opener params

Co-authored-by: Yufeng Wang <yufengwang@google.com>

* Set endpoint id in fabric-admin app

* Set root endpoint id by default in commissioning window params

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

---------

Co-authored-by: Yufeng Wang <yufengwang@google.com>
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
diff --git a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp
index 480cfbc..b2d811f 100644
--- a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp
+++ b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp
@@ -38,6 +38,7 @@
             VerifyOrReturnError(mSalt.HasValue(), CHIP_ERROR_INVALID_ARGUMENT);
             return mWindowOpener->OpenCommissioningWindow(Controller::CommissioningWindowVerifierParams()
                                                               .SetNodeId(mNodeId)
+                                                              .SetEndpointId(mEndpointId)
                                                               .SetTimeout(mCommissioningWindowTimeout)
                                                               .SetIteration(mIteration)
                                                               .SetDiscriminator(mDiscriminator)
@@ -50,6 +51,7 @@
             SetupPayload ignored;
             return mWindowOpener->OpenCommissioningWindow(Controller::CommissioningWindowPasscodeParams()
                                                               .SetNodeId(mNodeId)
+                                                              .SetEndpointId(mEndpointId)
                                                               .SetTimeout(mCommissioningWindowTimeout)
                                                               .SetIteration(mIteration)
                                                               .SetDiscriminator(mDiscriminator)
diff --git a/src/controller/CommissioningWindowOpener.cpp b/src/controller/CommissioningWindowOpener.cpp
index 35011e6..e8d1b29 100644
--- a/src/controller/CommissioningWindowOpener.cpp
+++ b/src/controller/CommissioningWindowOpener.cpp
@@ -126,6 +126,7 @@
     mCommissioningWindowVerifierCallback = nullptr;
     mNodeId                              = params.GetNodeId();
     mCommissioningWindowTimeout          = params.GetTimeout();
+    mTargetEndpointId                    = params.GetEndpointId();
 
     if (params.GetReadVIDPIDAttributes())
     {
@@ -162,6 +163,7 @@
     mPBKDFIterations                     = params.GetIteration();
     mCommissioningWindowOption           = CommissioningWindowOption::kTokenWithProvidedPIN;
     mDiscriminator.SetLongValue(params.GetDiscriminator());
+    mTargetEndpointId = params.GetEndpointId();
 
     mNextStep = Step::kOpenCommissioningWindow;
 
@@ -173,9 +175,7 @@
 {
     ChipLogProgress(Controller, "OpenCommissioningWindow for device ID 0x" ChipLogFormatX64, ChipLogValueX64(mNodeId));
 
-    constexpr EndpointId kAdministratorCommissioningClusterEndpoint = 0;
-
-    ClusterBase cluster(exchangeMgr, sessionHandle, kAdministratorCommissioningClusterEndpoint);
+    ClusterBase cluster(exchangeMgr, sessionHandle, mTargetEndpointId);
 
     if (mCommissioningWindowOption != CommissioningWindowOption::kOriginalSetupCode)
     {
diff --git a/src/controller/CommissioningWindowOpener.h b/src/controller/CommissioningWindowOpener.h
index b657345..28a25d7 100644
--- a/src/controller/CommissioningWindowOpener.h
+++ b/src/controller/CommissioningWindowOpener.h
@@ -165,7 +165,8 @@
     Callback::Callback<OnOpenBasicCommissioningWindow> * mBasicCommissioningWindowCallback           = nullptr;
     SetupPayload mSetupPayload;
     SetupDiscriminator mDiscriminator{};
-    NodeId mNodeId                                       = kUndefinedNodeId;
+    NodeId mNodeId               = kUndefinedNodeId;
+    EndpointId mTargetEndpointId = kRootEndpointId; // Default endpoint for Administrator Commissioning Cluster
     System::Clock::Seconds16 mCommissioningWindowTimeout = System::Clock::kZero;
     CommissioningWindowOption mCommissioningWindowOption = CommissioningWindowOption::kOriginalSetupCode;
     Crypto::Spake2pVerifier mVerifier; // Used for non-basic commissioning.
diff --git a/src/controller/CommissioningWindowParams.h b/src/controller/CommissioningWindowParams.h
index a4f0e43..c845ecf 100644
--- a/src/controller/CommissioningWindowParams.h
+++ b/src/controller/CommissioningWindowParams.h
@@ -19,6 +19,7 @@
 
 #include <lib/core/CHIPCallback.h>
 #include <lib/core/CHIPError.h>
+#include <lib/core/DataModelTypes.h>
 #include <lib/core/NodeId.h>
 #include <lib/core/Optional.h>
 #include <lib/support/Span.h>
@@ -53,6 +54,13 @@
         return static_cast<Derived &>(*this);
     }
 
+    EndpointId GetEndpointId() const { return mEndpointId; }
+    Derived & SetEndpointId(EndpointId endpointId)
+    {
+        mEndpointId = endpointId;
+        return static_cast<Derived &>(*this);
+    }
+
     System::Clock::Seconds16 GetTimeout() const { return mTimeout; }
     // The duration for which the commissioning window should remain open.
     Derived & SetTimeout(System::Clock::Seconds16 timeout)
@@ -82,6 +90,7 @@
 
 private:
     NodeId mNodeId                    = kUndefinedNodeId;
+    EndpointId mEndpointId            = kRootEndpointId;               // Default endpoint for Administrator Commissioning Cluster
     System::Clock::Seconds16 mTimeout = System::Clock::Seconds16(300); // Defaulting
     uint32_t mIteration               = 1000;                          // Defaulting
     Optional<uint16_t> mDiscriminator = NullOptional; // Using optional type to avoid picking a sentinnel in valid range