[darwin-framework-tool][interactive] Add Ctrl+Z as a shortcut key to suspend or resume the running controllers (#36302)

diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h
index 90f3a6c..a71f18e 100644
--- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h
+++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h
@@ -128,6 +128,8 @@
 
     void RestartCommissioners();
 
+    void SuspendOrResumeCommissioners();
+
 private:
     CHIP_ERROR InitializeCommissioner(
         std::string key, chip::FabricId fabricId, const chip::Credentials::AttestationTrustStore * trustStore);
diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm
index 6472d2c..4a6e279 100644
--- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm
+++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm
@@ -358,6 +358,16 @@
     [[MTRDeviceControllerFactory sharedInstance] stopControllerFactory];
 }
 
+void CHIPCommandBridge::SuspendOrResumeCommissioners()
+{
+    for (auto & pair : mControllers) {
+        __auto_type * commissioner = pair.second;
+        if (commissioner.running) {
+            commissioner.suspended ? [commissioner resume] : [commissioner suspend];
+        }
+    }
+}
+
 CHIP_ERROR CHIPCommandBridge::StartWaiting(chip::System::Clock::Timeout duration)
 {
     auto waitingUntil = std::chrono::system_clock::now() + std::chrono::duration_cast<std::chrono::seconds>(duration);
diff --git a/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm b/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm
index cfad15b..b5bdcc9 100644
--- a/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm
+++ b/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm
@@ -30,9 +30,10 @@
 constexpr char kInteractiveModeInstruction[] = "╔══════════════════════════════════════════════════════════════════╗\n"
                                                "║                        Interactive Mode                          ║\n"
                                                "╠══════════════════════════════════════════════════════════════════╣\n"
-                                               "║ Stop and restart stack: [Ctrl+_] & [Ctrl+^ ]                     ║\n"
-                                               "║ Trigger exit(0)       : [Ctrl+@]                                 ║\n"
-                                               "║ Quit Interactive      : 'quit()' or `quit`                       ║\n"
+                                               "║ Stop and restart stack    : [Ctrl+_] & [Ctrl+^ ]                 ║\n"
+                                               "║ Suspend/Resume controllers: [Ctrl+Z]                             ║\n"
+                                               "║ Trigger exit(0)           : [Ctrl+@]                             ║\n"
+                                               "║ Quit Interactive          : 'quit()' or `quit`                   ║\n"
                                                "╚══════════════════════════════════════════════════════════════════╝\n";
 constexpr char kInteractiveModePrompt[] = ">>> ";
 constexpr char kInteractiveModeHistoryFilePath[] = "/tmp/darwin_framework_tool_history";
@@ -76,6 +77,22 @@
     chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(0); }
 };
 
+class SuspendOrResumeCommand : public CHIPCommandBridge {
+public:
+    SuspendOrResumeCommand()
+        : CHIPCommandBridge("suspend")
+    {
+    }
+
+    CHIP_ERROR RunCommand() override
+    {
+        SuspendOrResumeCommissioners();
+        return CHIP_NO_ERROR;
+    }
+
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(0); }
+};
+
 void ClearLine()
 {
     printf("\r\x1B[0J"); // Move cursor to the beginning of the line and clear from cursor to end of the screen
@@ -312,6 +329,13 @@
     return CSstay;
 }
 
+el_status_t SuspendOrResumeFunction()
+{
+    SuspendOrResumeCommand cmd;
+    cmd.RunCommand();
+    return CSstay;
+}
+
 el_status_t ExitFunction()
 {
     exit(0);
@@ -333,6 +357,7 @@
     el_bind_key(CTL('^'), RestartFunction);
     el_bind_key(CTL('_'), StopFunction);
     el_bind_key(CTL('@'), ExitFunction);
+    el_bind_key(CTL('Z'), SuspendOrResumeFunction);
 
     char * command = nullptr;
     int status;