Re-add the openCommissioningWindowWithSetupPasscode APIs on MTRDevice and MTRBaseDevice. (#23157)

This is a re-landing of the API addition parts of
https://github.com/project-chip/connectedhomeip/pull/22521, without including
any of the API changes/removals.  The code is identical to what was on master
before Darwin framework changes were reverted in
https://github.com/project-chip/connectedhomeip/pull/23155.
diff --git a/examples/darwin-framework-tool/commands/pairing/OpenCommissioningWindowCommand.mm b/examples/darwin-framework-tool/commands/pairing/OpenCommissioningWindowCommand.mm
index 2f3eb9e..4c25000 100644
--- a/examples/darwin-framework-tool/commands/pairing/OpenCommissioningWindowCommand.mm
+++ b/examples/darwin-framework-tool/commands/pairing/OpenCommissioningWindowCommand.mm
@@ -17,47 +17,59 @@
 
 #import <Matter/Matter.h>
 
+#import "MTRError_Utils.h"
+
 #include "OpenCommissioningWindowCommand.h"
 
 CHIP_ERROR OpenCommissioningWindowCommand::RunCommand()
 {
-    auto * controller = CurrentCommissioner();
-    NSError * error;
-    __block NSString * pairingCode;
-    if (mCommissioningWindowOption == 0) {
-        [controller openPairingWindow:mNodeId duration:mCommissioningWindowTimeoutMs error:&error];
-    } else {
-        pairingCode = [controller openPairingWindowWithPIN:mNodeId
-                                                  duration:mCommissioningWindowTimeoutMs
-                                             discriminator:mDiscriminator
-                                                  setupPIN:[MTRSetupPayload generateRandomPIN]
-                                                     error:&error];
-    }
-
-    if (error != nil) {
-        SetCommandExitStatus(error);
-        return CHIP_NO_ERROR;
-    }
-
-    // TODO: Those should be async operations and we should not claim to
-    // be done until they complete.  As things stand, we have no idea
-    // how to tell when we're done, so just set a timer for slightly
-    // less than our command timeout to call SetCommandExitStatus.
     mWorkQueue = dispatch_queue_create("com.chip.open_commissioning_window", DISPATCH_QUEUE_SERIAL);
-    mTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, mWorkQueue);
+    auto * controller = CurrentCommissioner();
+    auto * device = [MTRDevice deviceWithNodeID:mNodeId deviceController:controller];
+
     auto * self = this;
-    dispatch_source_set_event_handler(mTimer, ^{
-        dispatch_source_cancel(mTimer);
-        mTimer = nil;
-        mWorkQueue = nil;
-        if (pairingCode != nil) {
-            ChipLogProgress(chipTool, "Setup code: %s\n", [pairingCode UTF8String]);
-        }
-        self->SetCommandExitStatus(CHIP_NO_ERROR);
-    });
-    dispatch_source_set_timer(
-        mTimer, dispatch_time(DISPATCH_TIME_NOW, (GetWaitDuration().count() - 2000) * NSEC_PER_MSEC), DISPATCH_TIME_FOREVER, 0);
-    dispatch_resume(mTimer);
+    if (mCommissioningWindowOption == 0) {
+        auto * cluster = [[MTRClusterAdministratorCommissioning alloc] initWithDevice:device endpoint:0 queue:mWorkQueue];
+        auto * params = [[MTRAdministratorCommissioningClusterOpenBasicCommissioningWindowParams alloc] init];
+        params.commissioningTimeout = @(mCommissioningWindowTimeoutMs);
+        params.timedInvokeTimeoutMs = @(10000);
+        [cluster openBasicCommissioningWindowWithParams:params
+                                         expectedValues:nil
+                                  expectedValueInterval:nil
+                                      completionHandler:^(NSError * _Nullable error) {
+                                          if (error == nil) {
+                                              self->SetCommandExitStatus(CHIP_NO_ERROR);
+                                          } else {
+                                              self->SetCommandExitStatus(MTRErrorToCHIPErrorCode(error));
+                                          }
+                                      }];
+    } else {
+        [device
+            openCommissioningWindowWithSetupPasscode:[MTRSetupPayload generateRandomSetupPasscode]
+                                       discriminator:@(mDiscriminator)
+                                            duration:@(mCommissioningWindowTimeoutMs)
+                                               queue:mWorkQueue
+                                          completion:^(MTRSetupPayload * _Nullable payload, NSError * error) {
+                                              if (error != nil) {
+                                                  self->SetCommandExitStatus(MTRErrorToCHIPErrorCode(error));
+                                                  return;
+                                              }
+
+                                              if (payload == nil) {
+                                                  self->SetCommandExitStatus(CHIP_ERROR_INVALID_ARGUMENT);
+                                                  return;
+                                              }
+
+                                              auto * pairingCode = [payload manualEntryCode];
+                                              if (pairingCode == nil) {
+                                                  self->SetCommandExitStatus(CHIP_ERROR_INVALID_ARGUMENT);
+                                                  return;
+                                              }
+
+                                              ChipLogProgress(chipTool, "Setup code: %s\n", [[payload manualEntryCode] UTF8String]);
+                                              self->SetCommandExitStatus(CHIP_NO_ERROR);
+                                          }];
+    }
 
     return CHIP_NO_ERROR;
 }