Add timeout to excute a command (#36492)

diff --git a/examples/fabric-sync/shell/BUILD.gn b/examples/fabric-sync/shell/BUILD.gn
index b3726ee..436f8b5 100644
--- a/examples/fabric-sync/shell/BUILD.gn
+++ b/examples/fabric-sync/shell/BUILD.gn
@@ -31,6 +31,7 @@
     "AddBridgeCommand.h",
     "AddDeviceCommand.cpp",
     "AddDeviceCommand.h",
+    "CommandRegistry.cpp",
     "CommandRegistry.h",
     "RemoveBridgeCommand.cpp",
     "RemoveBridgeCommand.h",
diff --git a/examples/fabric-sync/shell/CommandRegistry.cpp b/examples/fabric-sync/shell/CommandRegistry.cpp
new file mode 100644
index 0000000..34c0135
--- /dev/null
+++ b/examples/fabric-sync/shell/CommandRegistry.cpp
@@ -0,0 +1,48 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "CommandRegistry.h"
+
+#include <system/SystemLayer.h>
+
+using namespace ::chip;
+
+namespace commands {
+
+void CommandRegistry::SetActiveCommand(std::unique_ptr<Command> command, uint32_t timeoutSeconds)
+{
+    mActiveCommand = std::move(command);
+
+    // Cancel any previous timer to avoid multiple timers running simultaneously
+    DeviceLayer::SystemLayer().CancelTimer(OnTimeout, this);
+
+    // Start a new timer for the specified timeout
+    CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(timeoutSeconds * 1000), OnTimeout, this);
+    if (err != CHIP_NO_ERROR)
+    {
+        ResetActiveCommand();
+    }
+}
+
+void CommandRegistry::ResetActiveCommand()
+{
+    DeviceLayer::SystemLayer().CancelTimer(OnTimeout, this);
+    mActiveCommand.reset();
+}
+
+} // namespace commands
diff --git a/examples/fabric-sync/shell/CommandRegistry.h b/examples/fabric-sync/shell/CommandRegistry.h
index ec53e17..0043c26 100644
--- a/examples/fabric-sync/shell/CommandRegistry.h
+++ b/examples/fabric-sync/shell/CommandRegistry.h
@@ -38,16 +38,23 @@
         return instance;
     }
 
-    void SetActiveCommand(std::unique_ptr<Command> command) { mActiveCommand = std::move(command); }
+    void SetActiveCommand(std::unique_ptr<Command> command, uint32_t timeoutSeconds = 30);
 
     Command * GetActiveCommand() { return mActiveCommand.get(); }
 
-    void ResetActiveCommand() { mActiveCommand.reset(); }
+    void ResetActiveCommand();
 
     bool IsCommandActive() const { return mActiveCommand != nullptr; }
 
 private:
     CommandRegistry() = default;
+
+    static void OnTimeout(chip::System::Layer * layer, void * appState)
+    {
+        // Callback function to reset the command when the timer expires
+        static_cast<CommandRegistry *>(appState)->ResetActiveCommand();
+    }
+
     std::unique_ptr<Command> mActiveCommand;
 };