Add a controller factory to vend controllers per Fabric (#9872)

* Add a controller factory to vend controllers per Fabric

* Remove the UDP port from CHIPDeviceController and CHIPDevice

* fix style
diff --git a/src/controller/BUILD.gn b/src/controller/BUILD.gn
index 9abe48d..84604fa 100644
--- a/src/controller/BUILD.gn
+++ b/src/controller/BUILD.gn
@@ -34,6 +34,8 @@
     "CHIPDevice.h",
     "CHIPDeviceController.cpp",
     "CHIPDeviceController.h",
+    "CHIPDeviceControllerFactory.cpp",
+    "CHIPDeviceControllerFactory.h",
     "DeviceAddressUpdateDelegate.h",
     "EmptyDataModelHandler.cpp",
     "ExampleOperationalCredentialsIssuer.cpp",
diff --git a/src/controller/CHIPDevice.h b/src/controller/CHIPDevice.h
index b9a256f..d7eb543 100644
--- a/src/controller/CHIPDevice.h
+++ b/src/controller/CHIPDevice.h
@@ -165,15 +165,13 @@
      *   still using them, it can lead to unknown behavior and crashes.
      *
      * @param[in] params       Wrapper object for transport manager etc.
-     * @param[in] listenPort   Port on which controller is listening (typically CHIP_PORT)
      * @param[in] fabric        Local administrator that's initializing this device object
      */
-    void Init(ControllerDeviceInitParams params, uint16_t listenPort, FabricIndex fabric)
+    void Init(ControllerDeviceInitParams params, FabricIndex fabric)
     {
         mSessionManager  = params.sessionManager;
         mExchangeMgr     = params.exchangeMgr;
         mInetLayer       = params.inetLayer;
-        mListenPort      = listenPort;
         mFabricIndex     = fabric;
         mStorageDelegate = params.storageDelegate;
         mIDAllocator     = params.idAllocator;
@@ -196,15 +194,13 @@
      *   is actually paired.
      *
      * @param[in] params       Wrapper object for transport manager etc.
-     * @param[in] listenPort   Port on which controller is listening (typically CHIP_PORT)
      * @param[in] deviceId     Node ID of the device
      * @param[in] peerAddress  The location of the peer. MUST be of type Transport::Type::kUdp
      * @param[in] fabric        Local administrator that's initializing this device object
      */
-    void Init(ControllerDeviceInitParams params, uint16_t listenPort, NodeId deviceId, const Transport::PeerAddress & peerAddress,
-              FabricIndex fabric)
+    void Init(ControllerDeviceInitParams params, NodeId deviceId, const Transport::PeerAddress & peerAddress, FabricIndex fabric)
     {
-        Init(params, mListenPort, fabric);
+        Init(params, fabric);
         mDeviceId = deviceId;
         mState    = ConnectionState::Connecting;
 
@@ -522,8 +518,6 @@
     static void OnOpenPairingWindowSuccessResponse(void * context);
     static void OnOpenPairingWindowFailureResponse(void * context, uint8_t status);
 
-    uint16_t mListenPort;
-
     FabricIndex mFabricIndex = Transport::kUndefinedFabricIndex;
 
     Transport::FabricTable * mFabricsTable = nullptr;
diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp
index 0b4952c..bb3cc97 100644
--- a/src/controller/CHIPDeviceController.cpp
+++ b/src/controller/CHIPDeviceController.cpp
@@ -109,8 +109,6 @@
 DeviceController::DeviceController()
 {
     mState                    = State::NotInitialized;
-    mSessionManager           = nullptr;
-    mExchangeMgr              = nullptr;
     mStorageDelegate          = nullptr;
     mPairedDevicesInitialized = false;
 }
@@ -118,95 +116,40 @@
 CHIP_ERROR DeviceController::Init(ControllerInitParams params)
 {
     VerifyOrReturnError(mState == State::NotInitialized, CHIP_ERROR_INCORRECT_STATE);
+    VerifyOrReturnError(params.systemState != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
 
-    if (params.systemLayer != nullptr && params.inetLayer != nullptr)
-    {
-        mSystemLayer = params.systemLayer;
-        mInetLayer   = params.inetLayer;
-        mListenPort  = params.listenPort;
-    }
-    else
-    {
-#if CONFIG_DEVICE_LAYER
-        ReturnErrorOnFailure(DeviceLayer::PlatformMgr().InitChipStack());
-
-        mSystemLayer = &DeviceLayer::SystemLayer();
-        mInetLayer   = &DeviceLayer::InetLayer;
-#endif // CONFIG_DEVICE_LAYER
-    }
-
-    VerifyOrReturnError(mSystemLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
-    VerifyOrReturnError(mInetLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+    VerifyOrReturnError(params.systemState->SystemLayer() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+    VerifyOrReturnError(params.systemState->InetLayer() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
 
     mStorageDelegate = params.storageDelegate;
 #if CONFIG_NETWORK_LAYER_BLE
-#if CONFIG_DEVICE_LAYER
-    if (params.bleLayer == nullptr)
-    {
-        params.bleLayer = DeviceLayer::ConnectivityMgr().GetBleLayer();
-    }
-#endif // CONFIG_DEVICE_LAYER
-    mBleLayer = params.bleLayer;
-    VerifyOrReturnError(mBleLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+    VerifyOrReturnError(params.systemState->BleLayer() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
 #endif
 
-    mTransportMgr          = chip::Platform::New<DeviceTransportMgr>();
-    mSessionManager        = chip::Platform::New<SessionManager>();
-    mExchangeMgr           = chip::Platform::New<Messaging::ExchangeManager>();
-    mMessageCounterManager = chip::Platform::New<secure_channel::MessageCounterManager>();
+    VerifyOrReturnError(params.systemState->TransportMgr() != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
 
-    ReturnErrorOnFailure(mTransportMgr->Init(
-        Transport::UdpListenParameters(mInetLayer).SetAddressType(Inet::kIPAddressType_IPv6).SetListenPort(mListenPort)
-#if INET_CONFIG_ENABLE_IPV4
-            ,
-        Transport::UdpListenParameters(mInetLayer).SetAddressType(Inet::kIPAddressType_IPv4).SetListenPort(mListenPort)
-#endif
-#if CONFIG_NETWORK_LAYER_BLE
-            ,
-        Transport::BleListenParameters(mBleLayer)
-#endif
-            ));
-
-    ReturnErrorOnFailure(mFabrics.Init(mStorageDelegate));
-
-    ReturnErrorOnFailure(mSessionManager->Init(mSystemLayer, mTransportMgr, &mFabrics, mMessageCounterManager));
-
-    ReturnErrorOnFailure(mExchangeMgr->Init(mSessionManager));
-
-    ReturnErrorOnFailure(mMessageCounterManager->Init(mExchangeMgr));
-
-    ReturnErrorOnFailure(mExchangeMgr->RegisterUnsolicitedMessageHandlerForProtocol(Protocols::TempZCL::Id, this));
-
-    if (params.imDelegate != nullptr)
-    {
-        mInteractionModelDelegate = params.imDelegate;
-    }
-    else
-    {
-        mDefaultIMDelegate        = chip::Platform::New<DeviceControllerInteractionModelDelegate>();
-        mInteractionModelDelegate = mDefaultIMDelegate;
-    }
-    ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(mExchangeMgr, mInteractionModelDelegate));
-
-    mExchangeMgr->SetDelegate(this);
+    // TODO Exchange Mgr needs to be able to track multiple delegates. Delegate API should be able to query for the right delegate
+    // to handle events.
+    ReturnErrorOnFailure(
+        params.systemState->ExchangeMgr()->RegisterUnsolicitedMessageHandlerForProtocol(Protocols::TempZCL::Id, this));
+    params.systemState->ExchangeMgr()->SetDelegate(this);
 
 #if CHIP_DEVICE_CONFIG_ENABLE_MDNS
     ReturnErrorOnFailure(Mdns::Resolver::Instance().SetResolverDelegate(this));
-    RegisterDeviceAddressUpdateDelegate(params.mDeviceAddressUpdateDelegate);
-    Mdns::Resolver::Instance().StartResolver(mInetLayer, kMdnsPort);
+    RegisterDeviceAddressUpdateDelegate(params.deviceAddressUpdateDelegate);
+    Mdns::Resolver::Instance().StartResolver(params.systemState->InetLayer(), kMdnsPort);
 #endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS
 
-    InitDataModelHandler(mExchangeMgr);
+    InitDataModelHandler(params.systemState->ExchangeMgr());
 
     VerifyOrReturnError(params.operationalCredentialsDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
     mOperationalCredentialsDelegate = params.operationalCredentialsDelegate;
 
     ReturnErrorOnFailure(ProcessControllerNOCChain(params));
 
-    mState = State::Initialized;
-
+    mSystemState = params.systemState->Retain();
+    mState       = State::Initialized;
     ReleaseAllDevices();
-
     return CHIP_NO_ERROR;
 }
 
@@ -244,7 +187,7 @@
     ReturnErrorOnFailure(newFabric.SetNOCCert(chipCertSpan));
     newFabric.SetVendorId(params.controllerVendorId);
 
-    Transport::FabricInfo * fabric = mFabrics.FindFabricWithIndex(mFabricIndex);
+    Transport::FabricInfo * fabric = params.systemState->Fabrics()->FindFabricWithIndex(mFabricIndex);
     ReturnErrorCodeIf(fabric == nullptr, CHIP_ERROR_INCORRECT_STATE);
 
     ReturnErrorOnFailure(fabric->SetFabricInfo(newFabric));
@@ -272,80 +215,17 @@
 
     mState = State::NotInitialized;
 
-    // Shut down the interaction model before we try shuttting down the exchange
-    // manager.
-    app::InteractionModelEngine::GetInstance()->Shutdown();
-
 #if CHIP_DEVICE_CONFIG_ENABLE_MDNS
     Mdns::Resolver::Instance().ShutdownResolver();
 #endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS
 
-    // TODO(#6668): Some exchange has leak, shutting down ExchangeManager will cause a assert fail.
-    // if (mExchangeMgr != nullptr)
-    // {
-    //     mExchangeMgr->Shutdown();
-    // }
-    if (mSessionManager != nullptr)
-    {
-        mSessionManager->Shutdown();
-    }
-
     mStorageDelegate = nullptr;
 
     ReleaseAllDevices();
 
-#if CONFIG_DEVICE_LAYER
-    //
-    // We can safely call PlatformMgr().Shutdown(), which like DeviceController::Shutdown(),
-    // expects to be called with external thread synchronization and will not try to acquire the
-    // stack lock.
-    //
-    // Actually stopping the event queue is a separable call that applications will have to sequence.
-    // Consumers are expected to call PlaformMgr().StopEventLoopTask() before calling
-    // DeviceController::Shutdown() in the CONFIG_DEVICE_LAYER configuration
-    //
-    ReturnErrorOnFailure(DeviceLayer::PlatformMgr().Shutdown());
-#else
-    ReturnErrorOnFailure(mInetLayer->Shutdown());
-    ReturnErrorOnFailure(mSystemLayer->Shutdown());
-    chip::Platform::Delete(mInetLayer);
-    chip::Platform::Delete(mSystemLayer);
-#endif // CONFIG_DEVICE_LAYER
-
-    mSystemLayer = nullptr;
-    mInetLayer   = nullptr;
-
-    if (mMessageCounterManager != nullptr)
-    {
-        chip::Platform::Delete(mMessageCounterManager);
-        mMessageCounterManager = nullptr;
-    }
-
-    if (mExchangeMgr != nullptr)
-    {
-        chip::Platform::Delete(mExchangeMgr);
-        mExchangeMgr = nullptr;
-    }
-
-    if (mSessionManager != nullptr)
-    {
-        chip::Platform::Delete(mSessionManager);
-        mSessionManager = nullptr;
-    }
-
-    if (mTransportMgr != nullptr)
-    {
-        chip::Platform::Delete(mTransportMgr);
-        mTransportMgr = nullptr;
-    }
-
-    if (mDefaultIMDelegate != nullptr)
-    {
-        chip::Platform::Delete(mDefaultIMDelegate);
-        mDefaultIMDelegate = nullptr;
-    }
-
-    mFabrics.ReleaseFabricIndex(mFabricIndex);
+    mSystemState->Fabrics()->ReleaseFabricIndex(mFabricIndex);
+    mSystemState->Release();
+    mSystemState = nullptr;
 
 #if CHIP_DEVICE_CONFIG_ENABLE_MDNS
     Mdns::Resolver::Instance().SetResolverDelegate(nullptr);
@@ -355,17 +235,6 @@
     return CHIP_NO_ERROR;
 }
 
-CHIP_ERROR DeviceController::SetUdpListenPort(uint16_t listenPort)
-{
-    if (mState == State::Initialized)
-    {
-        return CHIP_ERROR_INCORRECT_STATE;
-    }
-
-    mListenPort = listenPort;
-    return CHIP_NO_ERROR;
-}
-
 CHIP_ERROR DeviceController::GetDevice(NodeId deviceId, Device ** out_device)
 {
     CHIP_ERROR err  = CHIP_NO_ERROR;
@@ -402,7 +271,7 @@
             err = device->Deserialize(deviceInfo);
             VerifyOrExit(err == CHIP_NO_ERROR, ReleaseDevice(device));
 
-            device->Init(GetControllerDeviceInitParams(), mListenPort, mFabricIndex);
+            device->Init(GetControllerDeviceInitParams(), mFabricIndex);
         }
     }
 
@@ -475,17 +344,6 @@
     }
 }
 
-CHIP_ERROR DeviceController::ServiceEvents()
-{
-    VerifyOrReturnError(mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
-
-#if CONFIG_DEVICE_LAYER
-    ReturnErrorOnFailure(DeviceLayer::PlatformMgr().StartEventLoopTask());
-#endif // CONFIG_DEVICE_LAYER
-
-    return CHIP_NO_ERROR;
-}
-
 CHIP_ERROR DeviceController::OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
                                                System::PacketBufferHandle && msgBuf)
 {
@@ -719,14 +577,14 @@
 ControllerDeviceInitParams DeviceController::GetControllerDeviceInitParams()
 {
     return ControllerDeviceInitParams{
-        .transportMgr    = mTransportMgr,
-        .sessionManager  = mSessionManager,
-        .exchangeMgr     = mExchangeMgr,
-        .inetLayer       = mInetLayer,
+        .transportMgr    = mSystemState->TransportMgr(),
+        .sessionManager  = mSystemState->SessionMgr(),
+        .exchangeMgr     = mSystemState->ExchangeMgr(),
+        .inetLayer       = mSystemState->InetLayer(),
         .storageDelegate = mStorageDelegate,
         .idAllocator     = &mIDAllocator,
-        .fabricsTable    = &mFabrics,
-        .imDelegate      = mInteractionModelDelegate,
+        .fabricsTable    = mSystemState->Fabrics(),
+        .imDelegate      = mSystemState->IMDelegate(),
     };
 }
 
@@ -761,18 +619,18 @@
 
 #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable
     mUdcTransportMgr = chip::Platform::New<DeviceTransportMgr>();
-    ReturnErrorOnFailure(mUdcTransportMgr->Init(Transport::UdpListenParameters(mInetLayer)
+    ReturnErrorOnFailure(mUdcTransportMgr->Init(Transport::UdpListenParameters(mSystemState->InetLayer())
                                                     .SetAddressType(Inet::kIPAddressType_IPv6)
                                                     .SetListenPort((uint16_t)(mUdcListenPort))
 #if INET_CONFIG_ENABLE_IPV4
                                                     ,
-                                                Transport::UdpListenParameters(mInetLayer)
+                                                Transport::UdpListenParameters(mSystemState->InetLayer())
                                                     .SetAddressType(Inet::kIPAddressType_IPv4)
                                                     .SetListenPort((uint16_t)(mUdcListenPort))
 #endif // INET_CONFIG_ENABLE_IPV4
 #if CONFIG_NETWORK_LAYER_BLE
                                                     ,
-                                                Transport::BleListenParameters(mBleLayer)
+                                                Transport::BleListenParameters(mSystemState->BleLayer())
 #endif // CONFIG_NETWORK_LAYER_BLE
                                                     ));
 
@@ -825,7 +683,7 @@
 
     uint16_t keyID = 0;
 
-    Transport::FabricInfo * fabric = mFabrics.FindFabricWithIndex(mFabricIndex);
+    Transport::FabricInfo * fabric = mSystemState->Fabrics()->FindFabricWithIndex(mFabricIndex);
 
     VerifyOrExit(IsOperationalNodeId(remoteDeviceId), err = CHIP_ERROR_INVALID_ARGUMENT);
     VerifyOrExit(mState == State::Initialized, err = CHIP_ERROR_INCORRECT_STATE);
@@ -884,12 +742,12 @@
 
     mIsIPRendezvous = (params.GetPeerAddress().GetTransportType() != Transport::Type::kBle);
 
-    err = mPairingSession.MessageDispatch().Init(mSessionManager);
+    err = mPairingSession.MessageDispatch().Init(mSystemState->SessionMgr());
     SuccessOrExit(err);
 
-    device->Init(GetControllerDeviceInitParams(), mListenPort, remoteDeviceId, peerAddress, fabric->GetFabricIndex());
+    device->Init(GetControllerDeviceInitParams(), remoteDeviceId, peerAddress, fabric->GetFabricIndex());
 
-    mSystemLayer->StartTimer(kSessionEstablishmentTimeout, OnSessionEstablishmentTimeoutCallback, this);
+    mSystemState->SystemLayer()->StartTimer(kSessionEstablishmentTimeout, OnSessionEstablishmentTimeoutCallback, this);
     if (params.GetPeerAddress().GetTransportType() != Transport::Type::kBle)
     {
         device->SetAddress(params.GetPeerAddress().GetIPAddress());
@@ -899,11 +757,11 @@
     {
         if (params.HasConnectionObject())
         {
-            SuccessOrExit(err = mBleLayer->NewBleConnectionByObject(params.GetConnectionObject()));
+            SuccessOrExit(err = mSystemState->BleLayer()->NewBleConnectionByObject(params.GetConnectionObject()));
         }
         else if (params.HasDiscriminator())
         {
-            SuccessOrExit(err = mBleLayer->NewBleConnectionByDiscriminator(params.GetDiscriminator()));
+            SuccessOrExit(err = mSystemState->BleLayer()->NewBleConnectionByDiscriminator(params.GetDiscriminator()));
         }
         else
         {
@@ -911,10 +769,10 @@
         }
     }
 #endif
-    session = mSessionManager->CreateUnauthenticatedSession(params.GetPeerAddress());
+    session = mSystemState->SessionMgr()->CreateUnauthenticatedSession(params.GetPeerAddress());
     VerifyOrExit(session.HasValue(), CHIP_ERROR_NO_MEMORY);
 
-    exchangeCtxt = mExchangeMgr->NewContext(session.Value(), &mPairingSession);
+    exchangeCtxt = mSystemState->ExchangeMgr()->NewContext(session.Value(), &mPairingSession);
     VerifyOrExit(exchangeCtxt != nullptr, err = CHIP_ERROR_INTERNAL);
 
     err = mIDAllocator.Allocate(keyID);
@@ -968,12 +826,12 @@
 
     testSecurePairingSecret->ToSerializable(device->GetPairing());
 
-    device->Init(GetControllerDeviceInitParams(), mListenPort, remoteDeviceId, peerAddress, mFabricIndex);
+    device->Init(GetControllerDeviceInitParams(), remoteDeviceId, peerAddress, mFabricIndex);
 
     device->Serialize(serialized);
 
-    err = mSessionManager->NewPairing(Optional<Transport::PeerAddress>::Value(peerAddress), device->GetDeviceId(),
-                                      testSecurePairingSecret, CryptoContext::SessionRole::kInitiator, mFabricIndex);
+    err = mSystemState->SessionMgr()->NewPairing(Optional<Transport::PeerAddress>::Value(peerAddress), device->GetDeviceId(),
+                                                 testSecurePairingSecret, CryptoContext::SessionRole::kInitiator, mFabricIndex);
     if (err != CHIP_NO_ERROR)
     {
         ChipLogError(Controller, "Failed in setting up secure channel: err %s", ErrorStr(err));
@@ -1149,7 +1007,7 @@
 
 void DeviceCommissioner::OnSessionEstablishmentError(CHIP_ERROR err)
 {
-    mSystemLayer->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);
+    mSystemState->SystemLayer()->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);
 
     if (mPairingDelegate != nullptr)
     {
@@ -1168,9 +1026,9 @@
     // TODO: the session should know which peer we are trying to connect to when started
     mPairingSession.SetPeerNodeId(device->GetDeviceId());
 
-    CHIP_ERROR err = mSessionManager->NewPairing(Optional<Transport::PeerAddress>::Value(mPairingSession.GetPeerAddress()),
-                                                 mPairingSession.GetPeerNodeId(), &mPairingSession,
-                                                 CryptoContext::SessionRole::kInitiator, mFabricIndex);
+    CHIP_ERROR err = mSystemState->SessionMgr()->NewPairing(
+        Optional<Transport::PeerAddress>::Value(mPairingSession.GetPeerAddress()), mPairingSession.GetPeerNodeId(),
+        &mPairingSession, CryptoContext::SessionRole::kInitiator, mFabricIndex);
     if (err != CHIP_NO_ERROR)
     {
         ChipLogError(Controller, "Failed in setting up secure channel: err %s", ErrorStr(err));
@@ -1337,7 +1195,7 @@
     DeviceAttestationVerifier * dac_verifier = GetDeviceAttestationVerifier();
 
     // Retrieve attestation challenge
-    ByteSpan attestationChallenge = mSessionManager
+    ByteSpan attestationChallenge = mSystemState->SessionMgr()
                                         ->GetSecureSession({ mPairingSession.GetPeerNodeId(), mPairingSession.GetLocalSessionId(),
                                                              mPairingSession.GetPeerSessionId(), mFabricIndex })
                                         ->GetCryptoContext()
@@ -1674,7 +1532,7 @@
 #endif
     {
         mPairingSession.ToSerializable(device->GetPairing());
-        mSystemLayer->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);
+        mSystemState->SystemLayer()->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);
 
         mPairedDevices.Insert(device->GetDeviceId());
         mPairedDevicesUpdated = true;
@@ -1721,7 +1579,7 @@
     // It is fine since we can only commission one device at the same time.
     // We should be able to distinguish different BLE connections if we want
     // to commission multiple devices at the same time over BLE.
-    return mBleLayer->CloseAllBleConnections();
+    return mSystemState->BleLayer()->CloseAllBleConnections();
 }
 #endif
 
@@ -2163,7 +2021,7 @@
     case CommissioningStage::kCleanup:
         ChipLogProgress(Controller, "Rendezvous cleanup");
         mPairingSession.ToSerializable(device->GetPairing());
-        mSystemLayer->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);
+        mSystemState->SystemLayer()->CancelTimer(OnSessionEstablishmentTimeoutCallback, this);
 
         mPairedDevices.Insert(device->GetDeviceId());
         mPairedDevicesUpdated = true;
diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h
index f449e07..81d3adc 100644
--- a/src/controller/CHIPDeviceController.h
+++ b/src/controller/CHIPDeviceController.h
@@ -32,6 +32,7 @@
 #include <controller-clusters/zap-generated/CHIPClientCallbacks.h>
 #include <controller/AbstractMdnsDiscoveryController.h>
 #include <controller/CHIPDevice.h>
+#include <controller/CHIPDeviceControllerSystemState.h>
 #include <controller/DeviceControllerInteractionModelDelegate.h>
 #include <controller/OperationalCredentialsDelegate.h>
 #include <credentials/CHIPOperationalCredentials.h>
@@ -83,15 +84,9 @@
 struct ControllerInitParams
 {
     PersistentStorageDelegate * storageDelegate = nullptr;
-    System::Layer * systemLayer                 = nullptr;
-    Inet::InetLayer * inetLayer                 = nullptr;
-
-#if CONFIG_NETWORK_LAYER_BLE
-    Ble::BleLayer * bleLayer = nullptr;
-#endif
-    DeviceControllerInteractionModelDelegate * imDelegate = nullptr;
+    DeviceControllerSystemState * systemState   = nullptr;
 #if CHIP_DEVICE_CONFIG_ENABLE_MDNS
-    DeviceAddressUpdateDelegate * mDeviceAddressUpdateDelegate = nullptr;
+    DeviceAddressUpdateDelegate * deviceAddressUpdateDelegate = nullptr;
 #endif
     OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;
 
@@ -106,9 +101,7 @@
 
     uint16_t controllerVendorId;
 
-    /* The port used for operational communication to listen for and send messages over UDP/TCP.
-     * The default value of `0` will pick any available port. */
-    uint16_t listenPort = 0;
+    FabricId fabricId = kUndefinedFabricId;
 };
 
 enum CommissioningStage : uint8_t
@@ -248,22 +241,12 @@
 
     void PersistDevice(Device * device);
 
-    CHIP_ERROR SetUdpListenPort(uint16_t listenPort);
-
     virtual void ReleaseDevice(Device * device);
 
 #if CHIP_DEVICE_CONFIG_ENABLE_MDNS
     void RegisterDeviceAddressUpdateDelegate(DeviceAddressUpdateDelegate * delegate) { mDeviceAddressUpdateDelegate = delegate; }
 #endif
 
-    // ----- IO -----
-    /**
-     * @brief
-     * Start the event loop task within the CHIP stack
-     * @return CHIP_ERROR   The return status
-     */
-    CHIP_ERROR ServiceEvents();
-
     /**
      * @brief Get the Compressed Fabric ID assigned to the device.
      */
@@ -274,7 +257,14 @@
      */
     uint64_t GetFabricId() const { return mFabricId; }
 
-    DeviceControllerInteractionModelDelegate * GetInteractionModelDelegate() { return mInteractionModelDelegate; }
+    DeviceControllerInteractionModelDelegate * GetInteractionModelDelegate()
+    {
+        if (mSystemState != nullptr)
+        {
+            return mSystemState->IMDelegate();
+        }
+        return nullptr;
+    }
 
 protected:
     enum class State
@@ -297,26 +287,15 @@
     PeerId mLocalId    = PeerId();
     FabricId mFabricId = kUndefinedFabricId;
 
-    DeviceTransportMgr * mTransportMgr                             = nullptr;
-    SessionManager * mSessionManager                               = nullptr;
-    Messaging::ExchangeManager * mExchangeMgr                      = nullptr;
-    secure_channel::MessageCounterManager * mMessageCounterManager = nullptr;
-    PersistentStorageDelegate * mStorageDelegate                   = nullptr;
-    DeviceControllerInteractionModelDelegate * mDefaultIMDelegate  = nullptr;
+    PersistentStorageDelegate * mStorageDelegate = nullptr;
 #if CHIP_DEVICE_CONFIG_ENABLE_MDNS
     DeviceAddressUpdateDelegate * mDeviceAddressUpdateDelegate = nullptr;
     // TODO(cecille): Make this configuarable.
     static constexpr int kMaxCommissionableNodes = 10;
     Mdns::DiscoveredNodeData mCommissionableNodes[kMaxCommissionableNodes];
 #endif
-    Inet::InetLayer * mInetLayer = nullptr;
-#if CONFIG_NETWORK_LAYER_BLE
-    Ble::BleLayer * mBleLayer = nullptr;
-#endif
-    System::Layer * mSystemLayer                                         = nullptr;
-    DeviceControllerInteractionModelDelegate * mInteractionModelDelegate = nullptr;
+    DeviceControllerSystemState * mSystemState = nullptr;
 
-    uint16_t mListenPort;
     uint16_t GetInactiveDeviceIndex();
     uint16_t FindDeviceIndex(SessionHandle session);
     uint16_t FindDeviceIndex(NodeId id);
@@ -329,7 +308,6 @@
     void PersistNextKeyId();
 
     FabricIndex mFabricIndex = Transport::kMinValidFabricIndex;
-    Transport::FabricTable mFabrics;
 
     OperationalCredentialsDelegate * mOperationalCredentialsDelegate;
 
diff --git a/src/controller/CHIPDeviceControllerFactory.cpp b/src/controller/CHIPDeviceControllerFactory.cpp
new file mode 100644
index 0000000..fa14179
--- /dev/null
+++ b/src/controller/CHIPDeviceControllerFactory.cpp
@@ -0,0 +1,284 @@
+/*
+ *
+ *    Copyright (c) 2021 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.
+ */
+
+/**
+ *    @file
+ *      Implementation of CHIP Device Controller Factory, a utility/manager class
+ *      that vends Controller objects
+ */
+
+#include <controller/CHIPDeviceControllerFactory.h>
+
+#include <lib/support/ErrorStr.h>
+
+#if CONFIG_DEVICE_LAYER
+#include <platform/CHIPDeviceLayer.h>
+#include <platform/ConfigurationManager.h>
+#endif
+
+using namespace chip::Inet;
+using namespace chip::System;
+using namespace chip::Credentials;
+
+namespace chip {
+namespace Controller {
+
+CHIP_ERROR DeviceControllerFactory::Init(FactoryInitParams params)
+{
+
+    // SystemState is only set the first time init is called, after that it is managed
+    // internally. If SystemState is set then init has already completed.
+    if (mSystemState != nullptr)
+    {
+        ChipLogError(Controller, "Device Controller Factory already initialized...");
+        return CHIP_NO_ERROR;
+    }
+
+    mListenPort      = params.listenPort;
+    mStorageDelegate = params.storageDelegate;
+
+    CHIP_ERROR err = InitSystemState(params);
+
+    return err;
+}
+
+CHIP_ERROR DeviceControllerFactory::InitSystemState()
+{
+    FactoryInitParams params;
+    if (mSystemState != nullptr)
+    {
+        params.systemLayer = mSystemState->SystemLayer();
+        params.inetLayer   = mSystemState->InetLayer();
+#if CONFIG_NETWORK_LAYER_BLE
+        params.bleLayer = mSystemState->BleLayer();
+#endif
+    }
+
+    return InitSystemState(params);
+}
+
+CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params)
+{
+    if (mSystemState != nullptr && mSystemState->IsInitialized())
+    {
+        return CHIP_NO_ERROR;
+    }
+
+    if (mSystemState != nullptr)
+    {
+        mSystemState->Release();
+        chip::Platform::Delete(mSystemState);
+        mSystemState = nullptr;
+    }
+
+    DeviceControllerSystemStateParams stateParams;
+#if CONFIG_DEVICE_LAYER
+    ReturnErrorOnFailure(DeviceLayer::PlatformMgr().InitChipStack());
+
+    stateParams.systemLayer = &DeviceLayer::SystemLayer();
+    stateParams.inetLayer   = &DeviceLayer::InetLayer;
+#else
+    stateParams.systemLayer = params.systemLayer;
+    stateParams.inetLayer   = params.inetLayer;
+    ChipLogError(Controller, "Warning: Device Controller Factory should be with a CHIP Device Layer...");
+#endif // CONFIG_DEVICE_LAYER
+
+    VerifyOrReturnError(stateParams.systemLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+    VerifyOrReturnError(stateParams.inetLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+#if CONFIG_NETWORK_LAYER_BLE
+#if CONFIG_DEVICE_LAYER
+    stateParams.bleLayer = DeviceLayer::ConnectivityMgr().GetBleLayer();
+#else
+    stateParams.bleLayer = params.bleLayer;
+#endif // CONFIG_DEVICE_LAYER
+    VerifyOrReturnError(stateParams.bleLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+#endif
+
+    stateParams.transportMgr = chip::Platform::New<DeviceTransportMgr>();
+
+    ReturnErrorOnFailure(stateParams.transportMgr->Init(
+        Transport::UdpListenParameters(stateParams.inetLayer).SetAddressType(Inet::kIPAddressType_IPv6).SetListenPort(mListenPort)
+#if INET_CONFIG_ENABLE_IPV4
+            ,
+        Transport::UdpListenParameters(stateParams.inetLayer).SetAddressType(Inet::kIPAddressType_IPv4).SetListenPort(mListenPort)
+#endif
+#if CONFIG_NETWORK_LAYER_BLE
+            ,
+        Transport::BleListenParameters(stateParams.bleLayer)
+#endif
+            ));
+
+    if (params.imDelegate == nullptr)
+    {
+        params.imDelegate = chip::Platform::New<DeviceControllerInteractionModelDelegate>();
+    }
+
+    stateParams.fabricTable           = chip::Platform::New<Transport::FabricTable>();
+    stateParams.sessionMgr            = chip::Platform::New<SessionManager>();
+    stateParams.exchangeMgr           = chip::Platform::New<Messaging::ExchangeManager>();
+    stateParams.messageCounterManager = chip::Platform::New<secure_channel::MessageCounterManager>();
+
+    ReturnErrorOnFailure(stateParams.fabricTable->Init(mStorageDelegate));
+    ReturnErrorOnFailure(stateParams.sessionMgr->Init(stateParams.systemLayer, stateParams.transportMgr, stateParams.fabricTable,
+                                                      stateParams.messageCounterManager));
+    ReturnErrorOnFailure(stateParams.exchangeMgr->Init(stateParams.sessionMgr));
+    ReturnErrorOnFailure(stateParams.messageCounterManager->Init(stateParams.exchangeMgr));
+
+    stateParams.imDelegate = params.imDelegate;
+    ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->Init(stateParams.exchangeMgr, stateParams.imDelegate));
+
+    // store the system state
+    mSystemState = chip::Platform::New<DeviceControllerSystemState>(stateParams);
+    ChipLogDetail(Controller, "System State Initialized...");
+    return CHIP_NO_ERROR;
+}
+
+void DeviceControllerFactory::PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params)
+{
+#if CHIP_DEVICE_CONFIG_ENABLE_MDNS
+    controllerParams.deviceAddressUpdateDelegate = params.deviceAddressUpdateDelegate;
+#endif
+    controllerParams.operationalCredentialsDelegate = params.operationalCredentialsDelegate;
+    controllerParams.ephemeralKeypair               = params.ephemeralKeypair;
+    controllerParams.controllerNOC                  = params.controllerNOC;
+    controllerParams.controllerICAC                 = params.controllerICAC;
+    controllerParams.controllerRCAC                 = params.controllerRCAC;
+    controllerParams.fabricId                       = params.fabricId;
+
+    controllerParams.systemState        = mSystemState;
+    controllerParams.storageDelegate    = mStorageDelegate;
+    controllerParams.controllerVendorId = params.controllerVendorId;
+}
+
+CHIP_ERROR DeviceControllerFactory::SetupController(SetupParams params, DeviceController & controller)
+{
+    VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
+    ReturnErrorOnFailure(InitSystemState());
+
+    ControllerInitParams controllerParams;
+    PopulateInitParams(controllerParams, params);
+
+    CHIP_ERROR err = controller.Init(controllerParams);
+    return err;
+}
+
+CHIP_ERROR DeviceControllerFactory::SetupCommissioner(SetupParams params, DeviceCommissioner & commissioner)
+{
+    VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
+    ReturnErrorOnFailure(InitSystemState());
+
+    CommissionerInitParams commissionerParams;
+    PopulateInitParams(commissionerParams, params);
+    commissionerParams.pairingDelegate = params.pairingDelegate;
+
+    CHIP_ERROR err = commissioner.Init(commissionerParams);
+    return err;
+}
+
+CHIP_ERROR DeviceControllerFactory::ServiceEvents()
+{
+    VerifyOrReturnError(mSystemState != nullptr, CHIP_ERROR_INCORRECT_STATE);
+
+#if CONFIG_DEVICE_LAYER
+    ReturnErrorOnFailure(DeviceLayer::PlatformMgr().StartEventLoopTask());
+#endif // CONFIG_DEVICE_LAYER
+
+    return CHIP_NO_ERROR;
+}
+
+DeviceControllerFactory::~DeviceControllerFactory()
+{
+    if (mSystemState != nullptr)
+    {
+        mSystemState->Release();
+        chip::Platform::Delete(mSystemState);
+        mSystemState = nullptr;
+    }
+    mStorageDelegate = nullptr;
+}
+
+CHIP_ERROR DeviceControllerSystemState::Shutdown()
+{
+    VerifyOrReturnError(mRefCount == 1, CHIP_ERROR_INCORRECT_STATE);
+
+    ChipLogDetail(Controller, "Shutting down the System State, this will teardown the CHIP Stack");
+
+    // Shut down the interaction model
+    app::InteractionModelEngine::GetInstance()->Shutdown();
+
+#if CONFIG_DEVICE_LAYER
+    //
+    // We can safely call PlatformMgr().Shutdown(), which like DeviceController::Shutdown(),
+    // expects to be called with external thread synchronization and will not try to acquire the
+    // stack lock.
+    //
+    // Actually stopping the event queue is a separable call that applications will have to sequence.
+    // Consumers are expected to call PlaformMgr().StopEventLoopTask() before calling
+    // DeviceController::Shutdown() in the CONFIG_DEVICE_LAYER configuration
+    //
+    ReturnErrorOnFailure(DeviceLayer::PlatformMgr().Shutdown());
+#endif
+
+    // TODO(#6668): Some exchange has leak, shutting down ExchangeManager will cause a assert fail.
+    // if (mExchangeMgr != nullptr)
+    // {
+    //     mExchangeMgr->Shutdown();
+    // }
+    if (mSessionMgr != nullptr)
+    {
+        mSessionMgr->Shutdown();
+    }
+
+    mSystemLayer = nullptr;
+    mInetLayer   = nullptr;
+    if (mTransportMgr != nullptr)
+    {
+        chip::Platform::Delete(mTransportMgr);
+        mTransportMgr = nullptr;
+    }
+
+    if (mMessageCounterManager != nullptr)
+    {
+        chip::Platform::Delete(mMessageCounterManager);
+        mMessageCounterManager = nullptr;
+    }
+
+    if (mExchangeMgr != nullptr)
+    {
+        chip::Platform::Delete(mExchangeMgr);
+        mExchangeMgr = nullptr;
+    }
+
+    if (mSessionMgr != nullptr)
+    {
+        chip::Platform::Delete(mSessionMgr);
+        mSessionMgr = nullptr;
+    }
+
+    if (mIMDelegate != nullptr)
+    {
+        chip::Platform::Delete(mIMDelegate);
+        mIMDelegate = nullptr;
+    }
+
+    return CHIP_NO_ERROR;
+}
+
+} // namespace Controller
+} // namespace chip
diff --git a/src/controller/CHIPDeviceControllerFactory.h b/src/controller/CHIPDeviceControllerFactory.h
new file mode 100644
index 0000000..1808b66
--- /dev/null
+++ b/src/controller/CHIPDeviceControllerFactory.h
@@ -0,0 +1,117 @@
+/*
+ *
+ *    Copyright (c) 2021 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.
+ */
+
+/**
+ *    @file
+ *      DeviceControllerFactory is a singleton utility class that manages the
+ *      runtime DeviceControllerSystemState and provides APIs to setup DeviceControllers
+ *      and DeviceCommissioners.
+ *
+ *      Together with the SystemState this class implicitly manages the lifecycle of the underlying
+ *      CHIP stack. It lazily initializes the CHIPStack when setting up Controllers if the SystemState
+ *      was previously shutdown.
+ */
+
+#pragma once
+
+#include <controller/CHIPDeviceController.h>
+#include <controller/CHIPDeviceControllerSystemState.h>
+
+namespace chip {
+
+namespace Controller {
+
+struct SetupParams
+{
+#if CHIP_DEVICE_CONFIG_ENABLE_MDNS
+    DeviceAddressUpdateDelegate * deviceAddressUpdateDelegate = nullptr;
+#endif
+    OperationalCredentialsDelegate * operationalCredentialsDelegate = nullptr;
+
+    /* The following keypair must correspond to the public key used for generating
+    controllerNOC. It's used by controller to establish CASE sessions with devices */
+    Crypto::P256Keypair * ephemeralKeypair = nullptr;
+
+    /* The following certificates must be in x509 DER format */
+    ByteSpan controllerNOC;
+    ByteSpan controllerICAC;
+    ByteSpan controllerRCAC;
+
+    FabricId fabricId = kUndefinedFabricId;
+
+    uint16_t controllerVendorId;
+
+    // The Device Pairing Delegated used to initialize a Commissioner
+    DevicePairingDelegate * pairingDelegate = nullptr;
+};
+
+// TODO everything other than the storage delegate here should be removed.
+// We're blocked because of the need to support !CHIP_DEVICE_LAYER
+struct FactoryInitParams
+{
+    PersistentStorageDelegate * storageDelegate           = nullptr;
+    System::Layer * systemLayer                           = nullptr;
+    Inet::InetLayer * inetLayer                           = nullptr;
+    DeviceControllerInteractionModelDelegate * imDelegate = nullptr;
+#if CONFIG_NETWORK_LAYER_BLE
+    Ble::BleLayer * bleLayer = nullptr;
+#endif
+
+    /* The port used for operational communication to listen for and send messages over UDP/TCP.
+     * The default value of `0` will pick any available port. */
+    uint16_t listenPort = 0;
+};
+
+class DeviceControllerFactory
+{
+public:
+    static DeviceControllerFactory & GetInstance()
+    {
+        static DeviceControllerFactory instance;
+        return instance;
+    }
+
+    CHIP_ERROR Init(FactoryInitParams params);
+    CHIP_ERROR SetupController(SetupParams params, DeviceController & controller);
+    CHIP_ERROR SetupCommissioner(SetupParams params, DeviceCommissioner & commissioner);
+
+    // ----- IO -----
+    /**
+     * @brief
+     * Start the event loop task within the CHIP stack
+     * @return CHIP_ERROR   The return status
+     */
+    CHIP_ERROR ServiceEvents();
+
+    ~DeviceControllerFactory();
+    DeviceControllerFactory(DeviceControllerFactory const &) = delete;
+    void operator=(DeviceControllerFactory const &) = delete;
+
+private:
+    DeviceControllerFactory(){};
+    void PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params);
+    CHIP_ERROR InitSystemState(FactoryInitParams params);
+    CHIP_ERROR InitSystemState();
+
+    uint16_t mListenPort;
+    PersistentStorageDelegate * mStorageDelegate = nullptr;
+    DeviceControllerSystemState * mSystemState   = nullptr;
+};
+
+} // namespace Controller
+} // namespace chip
diff --git a/src/controller/CHIPDeviceControllerSystemState.h b/src/controller/CHIPDeviceControllerSystemState.h
new file mode 100644
index 0000000..741b941
--- /dev/null
+++ b/src/controller/CHIPDeviceControllerSystemState.h
@@ -0,0 +1,146 @@
+/*
+ *
+ *    Copyright (c) 2021 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.
+ */
+
+/**
+ *    @file
+ *      DeviceControllerSystemState is a representation of all the runtime state
+ *      inside of CHIP that can be shared across Controllers and Commissioners.
+ *
+ *      The System State assumes it's being owned by and managed by the DeviceControllerFactory.
+ *      It will automatically shutdown the underlying CHIP Stack when its reference count
+ *      decreases to "1".
+ *
+ */
+
+#pragma once
+
+#include <controller/DeviceControllerInteractionModelDelegate.h>
+#include <protocols/secure_channel/MessageCounterManager.h>
+#include <transport/TransportMgr.h>
+#if CONFIG_DEVICE_LAYER
+#include <platform/CHIPDeviceLayer.h>
+#endif
+
+#if CONFIG_NETWORK_LAYER_BLE
+#include <ble/BleLayer.h>
+#endif
+
+namespace chip {
+
+namespace Controller {
+
+struct DeviceControllerSystemStateParams
+{
+    System::Layer * systemLayer = nullptr;
+    Inet::InetLayer * inetLayer = nullptr;
+#if CONFIG_NETWORK_LAYER_BLE
+    Ble::BleLayer * bleLayer = nullptr;
+#endif
+    DeviceTransportMgr * transportMgr                             = nullptr;
+    SessionManager * sessionMgr                                   = nullptr;
+    Messaging::ExchangeManager * exchangeMgr                      = nullptr;
+    secure_channel::MessageCounterManager * messageCounterManager = nullptr;
+    Transport::FabricTable * fabricTable                          = nullptr;
+    DeviceControllerInteractionModelDelegate * imDelegate         = nullptr;
+};
+
+// A representation of the internal state maintained by the DeviceControllerFactory
+// and refcounted by Device Controllers.
+// Expects that the creator of this object is the last one to release it.
+class DeviceControllerSystemState
+{
+public:
+    ~DeviceControllerSystemState(){};
+    DeviceControllerSystemState(DeviceControllerSystemStateParams params) :
+        mSystemLayer(params.systemLayer), mInetLayer(params.inetLayer), mTransportMgr(params.transportMgr),
+        mSessionMgr(params.sessionMgr), mExchangeMgr(params.exchangeMgr), mMessageCounterManager(params.messageCounterManager),
+        mFabrics(params.fabricTable), mIMDelegate(params.imDelegate)
+    {
+#if CONFIG_NETWORK_LAYER_BLE
+        mBleLayer = params.bleLayer;
+#endif
+    };
+
+    DeviceControllerSystemState * Retain()
+    {
+        if (mRefCount == std::numeric_limits<uint32_t>::max())
+        {
+            abort();
+        }
+        ++mRefCount;
+        return this;
+    };
+
+    void Release()
+    {
+        if (mRefCount == 0)
+        {
+            abort();
+        }
+
+        mRefCount--;
+        if (mRefCount == 1)
+        {
+            // Only the factory should have a ref now, shutdown and release the underlying objects
+            Shutdown();
+        }
+        else if (mRefCount == 0)
+        {
+            this->~DeviceControllerSystemState();
+        }
+    };
+    bool IsInitialized()
+    {
+        return mSystemLayer != nullptr && mInetLayer != nullptr && mTransportMgr != nullptr && mSessionMgr != nullptr &&
+            mExchangeMgr != nullptr && mMessageCounterManager != nullptr && mFabrics != nullptr;
+    };
+
+    System::Layer * SystemLayer() { return mSystemLayer; };
+    Inet::InetLayer * InetLayer() { return mInetLayer; };
+    DeviceTransportMgr * TransportMgr() { return mTransportMgr; };
+    SessionManager * SessionMgr() { return mSessionMgr; };
+    Messaging::ExchangeManager * ExchangeMgr() { return mExchangeMgr; }
+    secure_channel::MessageCounterManager * MessageCounterManager() { return mMessageCounterManager; };
+    Transport::FabricTable * Fabrics() { return mFabrics; };
+    DeviceControllerInteractionModelDelegate * IMDelegate() { return mIMDelegate; }
+#if CONFIG_NETWORK_LAYER_BLE
+    Ble::BleLayer * BleLayer() { return mBleLayer; };
+#endif
+
+private:
+    DeviceControllerSystemState(){};
+
+    System::Layer * mSystemLayer = nullptr;
+    Inet::InetLayer * mInetLayer = nullptr;
+#if CONFIG_NETWORK_LAYER_BLE
+    Ble::BleLayer * mBleLayer = nullptr;
+#endif
+    DeviceTransportMgr * mTransportMgr                             = nullptr;
+    SessionManager * mSessionMgr                                   = nullptr;
+    Messaging::ExchangeManager * mExchangeMgr                      = nullptr;
+    secure_channel::MessageCounterManager * mMessageCounterManager = nullptr;
+    Transport::FabricTable * mFabrics                              = nullptr;
+    DeviceControllerInteractionModelDelegate * mIMDelegate         = nullptr;
+
+    std::atomic<uint32_t> mRefCount{ 1 };
+
+    CHIP_ERROR Shutdown();
+};
+
+} // namespace Controller
+} // namespace chip
diff --git a/src/controller/java/AndroidDeviceControllerWrapper.cpp b/src/controller/java/AndroidDeviceControllerWrapper.cpp
index 81e89ec..2c9ec3a 100644
--- a/src/controller/java/AndroidDeviceControllerWrapper.cpp
+++ b/src/controller/java/AndroidDeviceControllerWrapper.cpp
@@ -25,6 +25,7 @@
 #include "JniReferences.h"
 #include <lib/support/CodeUtils.h>
 
+#include <controller/CHIPDeviceControllerFactory.h>
 #include <credentials/DeviceAttestationVerifier.h>
 #include <credentials/examples/DeviceAttestationVerifierExample.h>
 #include <lib/core/CHIPTLV.h>
@@ -205,19 +206,20 @@
     std::unique_ptr<AndroidDeviceControllerWrapper> wrapper(new AndroidDeviceControllerWrapper(std::move(controller), stackLock));
 
     wrapper->SetJavaObjectRef(vm, deviceControllerObj);
-    wrapper->Controller()->SetUdpListenPort(CHIP_PORT + 1);
 
     // Initialize device attestation verifier
     SetDeviceAttestationVerifier(Examples::GetExampleDACVerifier());
 
-    chip::Controller::CommissionerInitParams initParams;
+    chip::Controller::FactoryInitParams initParams;
+    chip::Controller::SetupParams setupParams;
 
-    initParams.storageDelegate                = wrapper.get();
-    initParams.pairingDelegate                = wrapper.get();
-    initParams.operationalCredentialsDelegate = wrapper.get();
-    initParams.systemLayer                    = systemLayer;
-    initParams.inetLayer                      = inetLayer;
-    initParams.bleLayer                       = GetJNIBleLayer();
+    initParams.storageDelegate                 = wrapper.get();
+    initParams.systemLayer                     = systemLayer;
+    initParams.inetLayer                       = inetLayer;
+    initParams.bleLayer                        = GetJNIBleLayer();
+    initParams.listenPort                      = CHIP_PORT + 1;
+    setupParams.pairingDelegate                = wrapper.get();
+    setupParams.operationalCredentialsDelegate = wrapper.get();
 
     wrapper->InitializeOperationalCredentialsIssuer();
 
@@ -252,13 +254,17 @@
         return nullptr;
     }
 
-    initParams.ephemeralKeypair = &ephemeralKey;
-    initParams.controllerRCAC   = rcacSpan;
-    initParams.controllerICAC   = icacSpan;
-    initParams.controllerNOC    = nocSpan;
+    setupParams.ephemeralKeypair = &ephemeralKey;
+    setupParams.controllerRCAC   = rcacSpan;
+    setupParams.controllerICAC   = icacSpan;
+    setupParams.controllerNOC    = nocSpan;
 
-    *errInfoOnFailure = wrapper->Controller()->Init(initParams);
-
+    *errInfoOnFailure = DeviceControllerFactory::GetInstance().Init(initParams);
+    if (*errInfoOnFailure != CHIP_NO_ERROR)
+    {
+        return nullptr;
+    }
+    *errInfoOnFailure = DeviceControllerFactory::GetInstance().SetupCommissioner(setupParams, *wrapper->Controller());
     if (*errInfoOnFailure != CHIP_NO_ERROR)
     {
         return nullptr;
diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp
index 69053b8..fc99cc8 100644
--- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp
+++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp
@@ -51,6 +51,7 @@
 #include <app/server/Mdns.h>
 #include <controller/CHIPDevice.h>
 #include <controller/CHIPDeviceController.h>
+#include <controller/CHIPDeviceControllerFactory.h>
 #include <controller/ExampleOperationalCredentialsIssuer.h>
 #include <credentials/DeviceAttestationVerifier.h>
 #include <credentials/examples/DeviceAttestationVerifierExample.h>
@@ -205,19 +206,21 @@
                                                                         nocSpan);
     VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
 
-    CommissionerInitParams initParams;
-    initParams.storageDelegate                = &sStorageDelegate;
-    initParams.mDeviceAddressUpdateDelegate   = &sDeviceAddressUpdateDelegate;
+    FactoryInitParams factoryParams;
+    factoryParams.storageDelegate = &sStorageDelegate;
+    factoryParams.imDelegate      = &PythonInteractionModelDelegate::Instance();
+
+    SetupParams initParams;
+    initParams.deviceAddressUpdateDelegate    = &sDeviceAddressUpdateDelegate;
     initParams.pairingDelegate                = &sPairingDelegate;
     initParams.operationalCredentialsDelegate = &sOperationalCredentialsIssuer;
-    initParams.imDelegate                     = &PythonInteractionModelDelegate::Instance();
     initParams.ephemeralKeypair               = &ephemeralKey;
     initParams.controllerRCAC                 = rcacSpan;
     initParams.controllerICAC                 = icacSpan;
     initParams.controllerNOC                  = nocSpan;
 
-    (*outDevCtrl)->SetUdpListenPort(0);
-    err = (*outDevCtrl)->Init(initParams);
+    ReturnErrorOnFailure(DeviceControllerFactory::GetInstance().Init(factoryParams).AsInteger());
+    err = DeviceControllerFactory::GetInstance().SetupCommissioner(initParams, **outDevCtrl);
     VerifyOrReturnError(err == CHIP_NO_ERROR, err.AsInteger());
 #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
     chip::app::MdnsServer::Instance().StartServer(chip::Mdns::CommissioningMode::kDisabled);
diff --git a/src/controller/python/chip/internal/CommissionerImpl.cpp b/src/controller/python/chip/internal/CommissionerImpl.cpp
index 081abda..ac71588 100644
--- a/src/controller/python/chip/internal/CommissionerImpl.cpp
+++ b/src/controller/python/chip/internal/CommissionerImpl.cpp
@@ -17,6 +17,7 @@
 #include <memory>
 
 #include <controller/CHIPDeviceController.h>
+#include <controller/CHIPDeviceControllerFactory.h>
 #include <controller/ExampleOperationalCredentialsIssuer.h>
 #include <credentials/DeviceAttestationVerifier.h>
 #include <credentials/examples/DeviceAttestationVerifierExample.h>
@@ -29,6 +30,8 @@
 
 #include "ChipThreadWork.h"
 
+using DeviceControllerFactory = chip::Controller::DeviceControllerFactory;
+
 namespace {
 
 class ServerStorageDelegate : public chip::PersistentStorageDelegate
@@ -97,12 +100,11 @@
 
         // System and Inet layers explicitly passed to indicate that the CHIP stack is
         // already assumed initialized
-        chip::Controller::CommissionerInitParams params;
+        chip::Controller::SetupParams commissionerParams;
+        chip::Controller::FactoryInitParams factoryParams;
 
-        params.storageDelegate = &gServerStorage;
-        params.systemLayer     = &chip::DeviceLayer::SystemLayer();
-        params.inetLayer       = &chip::DeviceLayer::InetLayer;
-        params.pairingDelegate = &gPairingDelegate;
+        commissionerParams.pairingDelegate = &gPairingDelegate;
+        factoryParams.storageDelegate      = &gServerStorage;
 
         chip::Platform::ScopedMemoryBuffer<uint8_t> noc;
         chip::Platform::ScopedMemoryBuffer<uint8_t> icac;
@@ -134,13 +136,14 @@
                                                                                 icacSpan, nocSpan);
             SuccessOrExit(err);
 
-            params.operationalCredentialsDelegate = &gOperationalCredentialsIssuer;
-            params.ephemeralKeypair               = &ephemeralKey;
-            params.controllerRCAC                 = rcacSpan;
-            params.controllerICAC                 = icacSpan;
-            params.controllerNOC                  = nocSpan;
+            commissionerParams.operationalCredentialsDelegate = &gOperationalCredentialsIssuer;
+            commissionerParams.ephemeralKeypair               = &ephemeralKey;
+            commissionerParams.controllerRCAC                 = rcacSpan;
+            commissionerParams.controllerICAC                 = icacSpan;
+            commissionerParams.controllerNOC                  = nocSpan;
 
-            err = result->Init(params);
+            SuccessOrExit(DeviceControllerFactory::GetInstance().Init(factoryParams));
+            err = DeviceControllerFactory::GetInstance().SetupCommissioner(commissionerParams, *result);
         }
     exit:
         ChipLogProgress(Controller, "Commissioner initialization status: %s", chip::ErrorStr(err));
diff --git a/src/controller/tests/TestDevice.cpp b/src/controller/tests/TestDevice.cpp
index ff1156c..8b9fdac 100644
--- a/src/controller/tests/TestDevice.cpp
+++ b/src/controller/tests/TestDevice.cpp
@@ -91,7 +91,7 @@
     Inet::IPAddress mockAddr;
     Inet::IPAddress::FromString("127.0.0.1", mockAddr);
     PeerAddress addr = PeerAddress::UDP(mockAddr, CHIP_PORT);
-    device.Init(params, CHIP_PORT, mockNodeId, addr, mockFabricIndex);
+    device.Init(params, mockNodeId, addr, mockFabricIndex);
 
     device.OperationalCertProvisioned();
     NL_TEST_ASSERT(inSuite, device.EstablishConnectivity(nullptr, nullptr) == CHIP_NO_ERROR);