[ICD] Trigger Check-In messages at boot (#31993)

* Send Check-In message at boot

* Update reboot test

* update comment

* restyle

* refactor function so that it can be used outside of the reboot

* Remove unused define function

---------

Co-authored-by: Andrei Litvin <andy314@gmail.com>
diff --git a/src/app/icd/server/ICDManager.cpp b/src/app/icd/server/ICDManager.cpp
index 954b3d7..05948fe 100644
--- a/src/app/icd/server/ICDManager.cpp
+++ b/src/app/icd/server/ICDManager.cpp
@@ -544,5 +544,19 @@
     return false;
 }
 
+void ICDManager::TriggerCheckInMessages()
+{
+    VerifyOrReturn(SupportsFeature(Feature::kCheckInProtocolSupport));
+
+    // Only trigger Check-In messages when we are in IdleMode.
+    // If we are already in ActiveMode, Check-In messages have already been sent.
+    VerifyOrReturn(mOperationalState == OperationalState::IdleMode);
+
+    // If we don't have any Check-In messages to send, do nothing
+    VerifyOrReturn(CheckInMessagesWouldBeSent());
+
+    UpdateOperationState(OperationalState::ActiveMode);
+}
+
 } // namespace app
 } // namespace chip
diff --git a/src/app/icd/server/ICDManager.h b/src/app/icd/server/ICDManager.h
index 3f78ccc..f115a41 100644
--- a/src/app/icd/server/ICDManager.h
+++ b/src/app/icd/server/ICDManager.h
@@ -108,6 +108,11 @@
     void OnICDManagementServerEvent(ICDManagementEvents event) override;
     void OnSubscriptionReport() override;
 
+    /**
+     * @brief Trigger the ICDManager to send Check-In message if necessary
+     */
+    void TriggerCheckInMessages();
+
 protected:
     friend class TestICDManager;
 
diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp
index 3c33c45..6228c10 100644
--- a/src/app/server/Server.cpp
+++ b/src/app/server/Server.cpp
@@ -436,6 +436,16 @@
         }
         break;
     case DeviceEventType::kServerReady:
+#if CHIP_CONFIG_ENABLE_ICD_SERVER
+        // Only Trigger Check-In messages if we are not in the middle of a commissioning.
+        // This check is only necessary for the first commissioiner since the kServerReady event
+        // is triggered once we join the network.
+        // We trigger Check-In messages before resuming subscriptions to avoid doing both.
+        if (!mFailSafeContext.IsFailSafeArmed())
+        {
+            mICDManager.TriggerCheckInMessages();
+        }
+#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
 #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
         ResumeSubscriptions();
 #endif
diff --git a/src/app/tests/suites/TestIcdManagementCluster.yaml b/src/app/tests/suites/TestIcdManagementCluster.yaml
index f8a853c..4a83c07 100644
--- a/src/app/tests/suites/TestIcdManagementCluster.yaml
+++ b/src/app/tests/suites/TestIcdManagementCluster.yaml
@@ -52,6 +52,43 @@
                   },
               ]
 
+    - label: "Read ICDCounter"
+      command: "readAttribute"
+      attribute: "ICDCounter"
+      response:
+          constraints:
+              type: int32u
+              minValue: 0x0
+              maxValue: 0xFFFFFFFF
+          saveAs: beforeRebootICDCounter
+
+    - label: "Reboot target device"
+      cluster: "SystemCommands"
+      command: "Reboot"
+
+    - label: "Connect to the device again"
+      cluster: "DelayCommands"
+      command: "WaitForCommissionee"
+      arguments:
+          values:
+              - name: "nodeId"
+                value: nodeId
+
+    - label: "Wait for 1S"
+      cluster: "DelayCommands"
+      command: "WaitForMs"
+      arguments:
+          values:
+              - name: "ms"
+                value: 1000
+
+    # Verifies ICDCounter increment and Check-In message at reboot
+    - label: "Read ICDCounter after reboot"
+      command: "readAttribute"
+      attribute: "ICDCounter"
+      response:
+          value: beforeRebootICDCounter + 101
+
     - label: "Unregister Client Registered During Commissioning"
       command: "UnregisterClient"
       arguments:
@@ -83,34 +120,6 @@
       response:
           value: 5000
 
-    - label: "Read ICDCounter"
-      command: "readAttribute"
-      attribute: "ICDCounter"
-      response:
-          constraints:
-              type: int32u
-              minValue: 0x0
-              maxValue: 0xFFFFFFFF
-          saveAs: beforeRebootICDCounter
-
-    - label: "Reboot target device"
-      cluster: "SystemCommands"
-      command: "Reboot"
-
-    - label: "Connect to the device again"
-      cluster: "DelayCommands"
-      command: "WaitForCommissionee"
-      arguments:
-          values:
-              - name: "nodeId"
-                value: nodeId
-
-    - label: "Read ICDCounter after reboot"
-      command: "readAttribute"
-      attribute: "ICDCounter"
-      response:
-          value: beforeRebootICDCounter + 100
-
     - label: "Read UserActiveModeTriggerHint"
       command: "readAttribute"
       attribute: "UserActiveModeTriggerHint"