blob: 0a6476ff38e49f8c2f4382ee467db1b600900c97 [file] [log] [blame]
/*
*
* 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 <app/CASEClientPool.h>
#include <app/CASESessionManager.h>
#include <app/reporting/ReportScheduler.h>
#include <credentials/FabricTable.h>
#include <credentials/GroupDataProvider.h>
#include <crypto/SessionKeystore.h>
#include <lib/core/CHIPConfig.h>
#include <protocols/bdx/BdxTransferServer.h>
#include <protocols/secure_channel/CASEServer.h>
#include <protocols/secure_channel/MessageCounterManager.h>
#include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
#include <protocols/secure_channel/UnsolicitedStatusHandler.h>
#include <transport/TransportMgr.h>
#include <transport/raw/UDP.h>
#if CONFIG_DEVICE_LAYER
#include <platform/CHIPDeviceLayer.h>
#endif
#if CONFIG_NETWORK_LAYER_BLE
#include <ble/Ble.h>
#include <transport/raw/BLE.h>
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
#include <transport/raw/WiFiPAF.h>
#endif
namespace chip {
inline constexpr size_t kMaxDeviceTransportBlePendingPackets = 1;
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
inline constexpr size_t kMaxDeviceTransportWiFiPAFPendingPackets = 1;
#endif
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
inline constexpr size_t kMaxDeviceTransportTcpActiveConnectionCount = CHIP_CONFIG_MAX_ACTIVE_TCP_CONNECTIONS;
inline constexpr size_t kMaxDeviceTransportTcpPendingPackets = CHIP_CONFIG_MAX_TCP_PENDING_PACKETS;
#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
using DeviceTransportMgr =
TransportMgr<Transport::UDP /* IPv6 */
#if INET_CONFIG_ENABLE_IPV4
,
Transport::UDP /* IPv4 */
#endif
#if CONFIG_NETWORK_LAYER_BLE
,
Transport::BLE<kMaxDeviceTransportBlePendingPackets> /* BLE */
#endif
#if INET_CONFIG_ENABLE_TCP_ENDPOINT
,
Transport::TCP<kMaxDeviceTransportTcpActiveConnectionCount, kMaxDeviceTransportTcpPendingPackets>
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
,
Transport::WiFiPAF<kMaxDeviceTransportWiFiPAFPendingPackets> /* WiFiPAF */
#endif
>;
namespace Controller {
struct DeviceControllerSystemStateParams
{
using SessionSetupPool = OperationalSessionSetupPool<CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_DEVICES>;
using CASEClientPool = chip::CASEClientPool<CHIP_CONFIG_CONTROLLER_MAX_ACTIVE_CASE_CLIENTS>;
// Params that can outlive the DeviceControllerSystemState
System::Layer * systemLayer = nullptr;
Inet::EndPointManager<Inet::TCPEndPoint> * tcpEndPointManager = nullptr;
Inet::EndPointManager<Inet::UDPEndPoint> * udpEndPointManager = nullptr;
FabricTable * fabricTable = nullptr;
#if CONFIG_NETWORK_LAYER_BLE
Ble::BleLayer * bleLayer = nullptr;
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
Transport::WiFiPAFLayer * wifipaf_layer = nullptr;
#endif
Credentials::GroupDataProvider * groupDataProvider = nullptr;
Crypto::SessionKeystore * sessionKeystore = nullptr;
// NOTE: Exactly one of externalSessionResumptionStorage (externally provided,
// externally owned) or ownedSessionResumptionStorage (managed by the system
// state) must be non-null.
SessionResumptionStorage * externalSessionResumptionStorage = nullptr;
// Params that will be deallocated via Platform::Delete in
// DeviceControllerSystemState::Shutdown.
DeviceTransportMgr * transportMgr = nullptr;
// NOTE: Exactly one of externalSessionResumptionStorage (externally provided,
// externally owned) or ownedSessionResumptionStorage (managed by the system
// state) must be non-null.
Platform::UniquePtr<SimpleSessionResumptionStorage> ownedSessionResumptionStorage;
Credentials::CertificateValidityPolicy * certificateValidityPolicy = nullptr;
SessionManager * sessionMgr = nullptr;
Protocols::SecureChannel::UnsolicitedStatusHandler * unsolicitedStatusHandler = nullptr;
Messaging::ExchangeManager * exchangeMgr = nullptr;
secure_channel::MessageCounterManager * messageCounterManager = nullptr;
bdx::BDXTransferServer * bdxTransferServer = nullptr;
CASEServer * caseServer = nullptr;
CASESessionManager * caseSessionManager = nullptr;
SessionSetupPool * sessionSetupPool = nullptr;
CASEClientPool * caseClientPool = nullptr;
FabricTable::Delegate * fabricTableDelegate = nullptr;
chip::app::reporting::ReportScheduler::TimerDelegate * timerDelegate = nullptr;
chip::app::reporting::ReportScheduler * reportScheduler = nullptr;
};
// A representation of the internal state maintained by the DeviceControllerFactory.
//
// This class automatically maintains a count of active device controllers and
// shuts down Matter when there are none remaining.
//
// NB: Lifetime of the object itself is not managed by reference counting; it is
// owned by DeviceControllerFactory.
class DeviceControllerSystemState
{
using SessionSetupPool = DeviceControllerSystemStateParams::SessionSetupPool;
using CASEClientPool = DeviceControllerSystemStateParams::CASEClientPool;
public:
~DeviceControllerSystemState()
{
// We could get here if a DeviceControllerFactory is shut down
// without ever creating any controllers, so our refcount never goes
// above 1. In that case we need to make sure we call Shutdown().
Shutdown();
};
DeviceControllerSystemState(DeviceControllerSystemStateParams params) :
mSystemLayer(params.systemLayer), mTCPEndPointManager(params.tcpEndPointManager),
mUDPEndPointManager(params.udpEndPointManager), mTransportMgr(params.transportMgr), mSessionMgr(params.sessionMgr),
mUnsolicitedStatusHandler(params.unsolicitedStatusHandler), mExchangeMgr(params.exchangeMgr),
mMessageCounterManager(params.messageCounterManager), mFabrics(params.fabricTable),
mBDXTransferServer(params.bdxTransferServer), mCASEServer(params.caseServer),
mCASESessionManager(params.caseSessionManager), mSessionSetupPool(params.sessionSetupPool),
mCASEClientPool(params.caseClientPool), mGroupDataProvider(params.groupDataProvider), mTimerDelegate(params.timerDelegate),
mReportScheduler(params.reportScheduler), mSessionKeystore(params.sessionKeystore),
mFabricTableDelegate(params.fabricTableDelegate),
mOwnedSessionResumptionStorage(std::move(params.ownedSessionResumptionStorage))
{
if (mOwnedSessionResumptionStorage)
{
mSessionResumptionStorage = mOwnedSessionResumptionStorage.get();
}
else
{
mSessionResumptionStorage = params.externalSessionResumptionStorage;
}
#if CONFIG_NETWORK_LAYER_BLE
mBleLayer = params.bleLayer;
#endif
VerifyOrDie(IsInitialized());
};
// Acquires a reference to the system state.
//
// While a reference is held, the shared state is kept alive. Release()
// should be called to release the reference once it is no longer needed.
DeviceControllerSystemState * Retain()
{
auto count = mRefCount++;
VerifyOrDie(count < std::numeric_limits<decltype(count)>::max()); // overflow
VerifyOrDie(!IsShutDown()); // avoid zombie
return this;
};
// Releases a reference to the system state.
//
// The stack will shut down when all references are released.
//
// NB: The system state is owned by the factory; Release() will not free it
// but will free its members (Shutdown()).
//
// Returns true if the system state was shut down in response to this call.
bool Release()
{
auto count = mRefCount--;
VerifyOrDie(count > 0); // underflow
VerifyOrReturnValue(count == 1, false);
Shutdown();
return true;
};
bool IsInitialized()
{
return mSystemLayer != nullptr && mUDPEndPointManager != nullptr && mTransportMgr != nullptr && mSessionMgr != nullptr &&
mUnsolicitedStatusHandler != nullptr && mExchangeMgr != nullptr && mMessageCounterManager != nullptr &&
mFabrics != nullptr && mCASESessionManager != nullptr && mSessionSetupPool != nullptr && mCASEClientPool != nullptr &&
mGroupDataProvider != nullptr && mReportScheduler != nullptr && mTimerDelegate != nullptr &&
mSessionKeystore != nullptr && mSessionResumptionStorage != nullptr && mBDXTransferServer != nullptr;
};
bool IsShutDown() const { return mHaveShutDown; }
System::Layer * SystemLayer() const { return mSystemLayer; };
Inet::EndPointManager<Inet::TCPEndPoint> * TCPEndPointManager() const { return mTCPEndPointManager; };
Inet::EndPointManager<Inet::UDPEndPoint> * UDPEndPointManager() const { return mUDPEndPointManager; };
DeviceTransportMgr * TransportMgr() const { return mTransportMgr; };
SessionManager * SessionMgr() const { return mSessionMgr; };
Messaging::ExchangeManager * ExchangeMgr() const { return mExchangeMgr; }
secure_channel::MessageCounterManager * MessageCounterManager() const { return mMessageCounterManager; };
FabricTable * Fabrics() const { return mFabrics; };
#if CONFIG_NETWORK_LAYER_BLE
Ble::BleLayer * BleLayer() const { return mBleLayer; };
#endif
CASESessionManager * CASESessionMgr() const { return mCASESessionManager; }
Credentials::GroupDataProvider * GetGroupDataProvider() const { return mGroupDataProvider; }
chip::app::reporting::ReportScheduler * GetReportScheduler() const { return mReportScheduler; }
Crypto::SessionKeystore * GetSessionKeystore() const { return mSessionKeystore; }
void SetTempFabricTable(FabricTable * tempFabricTable, bool enableServerInteractions)
{
mTempFabricTable = tempFabricTable;
mEnableServerInteractions = enableServerInteractions;
}
bdx::BDXTransferServer * BDXTransferServer() const { return mBDXTransferServer; }
private:
DeviceControllerSystemState() {}
System::Layer * mSystemLayer = nullptr;
Inet::EndPointManager<Inet::TCPEndPoint> * mTCPEndPointManager = nullptr;
Inet::EndPointManager<Inet::UDPEndPoint> * mUDPEndPointManager = nullptr;
#if CONFIG_NETWORK_LAYER_BLE
Ble::BleLayer * mBleLayer = nullptr;
#endif
DeviceTransportMgr * mTransportMgr = nullptr;
SessionManager * mSessionMgr = nullptr;
Protocols::SecureChannel::UnsolicitedStatusHandler * mUnsolicitedStatusHandler = nullptr;
Messaging::ExchangeManager * mExchangeMgr = nullptr;
secure_channel::MessageCounterManager * mMessageCounterManager = nullptr;
FabricTable * mFabrics = nullptr;
bdx::BDXTransferServer * mBDXTransferServer = nullptr;
CASEServer * mCASEServer = nullptr;
CASESessionManager * mCASESessionManager = nullptr;
SessionSetupPool * mSessionSetupPool = nullptr;
CASEClientPool * mCASEClientPool = nullptr;
Credentials::GroupDataProvider * mGroupDataProvider = nullptr;
app::reporting::ReportScheduler::TimerDelegate * mTimerDelegate = nullptr;
app::reporting::ReportScheduler * mReportScheduler = nullptr;
Crypto::SessionKeystore * mSessionKeystore = nullptr;
FabricTable::Delegate * mFabricTableDelegate = nullptr;
SessionResumptionStorage * mSessionResumptionStorage = nullptr;
Platform::UniquePtr<SimpleSessionResumptionStorage> mOwnedSessionResumptionStorage;
// If mTempFabricTable is not null, it was created during
// DeviceControllerFactory::InitSystemState and needs to be
// freed during shutdown
FabricTable * mTempFabricTable = nullptr;
std::atomic<uint32_t> mRefCount{ 0 };
bool mHaveShutDown = false;
bool mEnableServerInteractions = false;
void Shutdown();
};
} // namespace Controller
} // namespace chip