Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #pragma once
19 :
20 : #include <app/AppConfig.h>
21 : #include <app/icd/server/ICDServerConfig.h>
22 :
23 : #include <access/AccessControl.h>
24 : #include <access/GroupAuxiliaryAccessControlDelegate.h>
25 : #include <access/examples/ExampleAccessControlDelegate.h>
26 : #include <access/examples/GroupAuxiliaryAccessControlDelegateImpl.h>
27 : #include <app/CASEClientPool.h>
28 : #include <app/CASESessionManager.h>
29 : #include <app/DefaultSafeAttributePersistenceProvider.h>
30 : #include <app/FailSafeContext.h>
31 : #include <app/OperationalSessionSetupPool.h>
32 : #include <app/SimpleSubscriptionResumptionStorage.h>
33 : #include <app/TestEventTriggerDelegate.h>
34 : #include <app/server/AclStorage.h>
35 : #include <app/server/AppDelegate.h>
36 : #include <app/server/CommissioningWindowManager.h>
37 : #include <app/server/DefaultAclStorage.h>
38 : #include <credentials/CertificateValidityPolicy.h>
39 : #include <credentials/FabricTable.h>
40 : #include <credentials/GroupDataProvider.h>
41 : #include <credentials/GroupDataProviderImpl.h>
42 : #include <credentials/OperationalCertificateStore.h>
43 : #include <credentials/PersistentStorageOpCertStore.h>
44 : #include <crypto/DefaultSessionKeystore.h>
45 : #include <crypto/OperationalKeystore.h>
46 : #include <crypto/PersistentStorageOperationalKeystore.h>
47 : #include <inet/InetConfig.h>
48 : #include <lib/core/CHIPConfig.h>
49 : #include <lib/support/AutoRelease.h>
50 : #include <lib/support/SafeInt.h>
51 : #include <messaging/ExchangeMgr.h>
52 : #include <platform/DefaultTimerDelegate.h>
53 : #include <platform/DeviceInstanceInfoProvider.h>
54 : #include <platform/KeyValueStoreManager.h>
55 : #include <platform/KvsPersistentStorageDelegate.h>
56 : #include <protocols/secure_channel/CASEServer.h>
57 : #include <protocols/secure_channel/MessageCounterManager.h>
58 : #include <protocols/secure_channel/PASESession.h>
59 : #include <protocols/secure_channel/RendezvousParameters.h>
60 : #include <protocols/secure_channel/UnsolicitedStatusHandler.h>
61 : #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
62 : #include <protocols/secure_channel/SimpleSessionResumptionStorage.h>
63 : #endif
64 : #include <protocols/user_directed_commissioning/UserDirectedCommissioning.h>
65 : #include <system/SystemClock.h>
66 : #include <transport/SessionManager.h>
67 : #include <transport/TransportMgr.h>
68 : #include <transport/TransportMgrBase.h>
69 : #if CONFIG_NETWORK_LAYER_BLE
70 : #include <transport/raw/BLE.h>
71 : #endif
72 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
73 : #include <transport/raw/WiFiPAF.h>
74 : #endif
75 : #include <app/reporting/ReportSchedulerImpl.h>
76 : #include <transport/raw/UDP.h>
77 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
78 : #include <transport/raw/NFC.h>
79 : #endif
80 :
81 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
82 : #include <app/icd/server/ICDManager.h> // nogncheck
83 :
84 : #if CHIP_CONFIG_ENABLE_ICD_CIP
85 : #include <app/icd/server/DefaultICDCheckInBackOffStrategy.h> // nogncheck
86 : #include <app/icd/server/ICDCheckInBackOffStrategy.h> // nogncheck
87 : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
88 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
89 :
90 : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
91 : #include <app/server/JointFabricAdministrator.h> //nogncheck
92 : #include <app/server/JointFabricDatastore.h> //nogncheck
93 : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
94 :
95 : namespace chip {
96 :
97 : inline constexpr size_t kMaxBlePendingPackets = 1;
98 :
99 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
100 : inline constexpr size_t kMaxTcpActiveConnectionCount = CHIP_CONFIG_MAX_ACTIVE_TCP_CONNECTIONS;
101 :
102 : inline constexpr size_t kMaxTcpPendingPackets = CHIP_CONFIG_MAX_TCP_PENDING_PACKETS;
103 : #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT
104 :
105 : //
106 : // NOTE: Please do not alter the order of template specialization here as the logic
107 : // in the Server impl depends on this.
108 : //
109 : using ServerTransportMgr = chip::TransportMgr<chip::Transport::UDP
110 : #if INET_CONFIG_ENABLE_IPV4
111 : ,
112 : chip::Transport::UDP
113 : #endif
114 : #if CONFIG_NETWORK_LAYER_BLE
115 : ,
116 : chip::Transport::BLE<kMaxBlePendingPackets>
117 : #endif
118 : #if INET_CONFIG_ENABLE_TCP_ENDPOINT
119 : ,
120 : chip::Transport::TCP<kMaxTcpActiveConnectionCount, kMaxTcpPendingPackets>
121 : #if INET_CONFIG_ENABLE_IPV4
122 : ,
123 : chip::Transport::TCP<kMaxTcpActiveConnectionCount, kMaxTcpPendingPackets>
124 : #endif
125 : #endif
126 : #if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF
127 : ,
128 : chip::Transport::WiFiPAFBase
129 : #endif
130 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
131 : ,
132 : chip::Transport::NFC
133 : #endif
134 : >;
135 :
136 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
137 : using UdcTransportMgr = TransportMgr<Transport::UDP /* IPv6 */
138 : #if INET_CONFIG_ENABLE_IPV4
139 : ,
140 : Transport::UDP /* IPv4 */
141 : #endif
142 : >;
143 : #endif
144 :
145 : struct ServerInitParams
146 : {
147 1 : ServerInitParams() = default;
148 :
149 : // Not copyable
150 : ServerInitParams(const ServerInitParams &) = delete;
151 : ServerInitParams & operator=(const ServerInitParams &) = delete;
152 :
153 : // Application delegate to handle some commissioning lifecycle events
154 : AppDelegate * appDelegate = nullptr;
155 : // device discovery timeout
156 1 : System::Clock::Seconds32 discoveryTimeout = System::Clock::Seconds32(CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS);
157 : // Port to use for Matter commissioning/operational traffic
158 : uint16_t operationalServicePort = CHIP_PORT;
159 : // Port to use for UDC if supported
160 : uint16_t userDirectedCommissioningPort = CHIP_UDC_PORT;
161 : // Interface on which to run daemon
162 : Inet::InterfaceId interfaceId = Inet::InterfaceId::Null();
163 :
164 : #if CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
165 : // Number of sequential port retries if binding fails with "address in use"
166 : // When > 0, if binding to operationalServicePort (or userDirectedCommissioningPort) fails,
167 : // the system will automatically try portRetryCount additional sequential ports.
168 : // For example: if operationalServicePort=5540 and portRetryCount=10, it will try
169 : // ports 5540, 5541, 5542, ... up to 5550 until one succeeds.
170 : // When set to 0 (default), no retry is attempted - implements single port behavior.
171 : uint16_t portRetryCount = CHIP_DEVICE_CONFIG_PORT_RETRY_COUNT;
172 : #endif // CHIP_DEVICE_CONFIG_ENABLE_PORT_RETRY
173 :
174 : // Persistent storage delegate: MUST be injected. Used to maintain storage by much common code.
175 : // Must be initialized before being provided.
176 : PersistentStorageDelegate * persistentStorageDelegate = nullptr;
177 : // Session resumption storage: Optional. Support session resumption when provided.
178 : // Must be initialized before being provided.
179 : SessionResumptionStorage * sessionResumptionStorage = nullptr;
180 : // Session resumption storage: Optional. Support session resumption when provided.
181 : // Must be initialized before being provided.
182 : app::SubscriptionResumptionStorage * subscriptionResumptionStorage = nullptr;
183 : // Certificate validity policy: Optional. If none is injected, CHIPCert
184 : // enforces a default policy.
185 : Credentials::CertificateValidityPolicy * certificateValidityPolicy = nullptr;
186 : // Group data provider: MUST be injected. Used to maintain critical keys such as the Identity
187 : // Protection Key (IPK) for CASE. Must be initialized before being provided.
188 : Credentials::GroupDataProvider * groupDataProvider = nullptr;
189 : // Session keystore: MUST be injected. Used to derive and manage lifecycle of symmetric keys.
190 : Crypto::SessionKeystore * sessionKeystore = nullptr;
191 : // Access control delegate: MUST be injected. Used to look up access control rules. Must be
192 : // initialized before being provided.
193 : Access::AccessControl::Delegate * accessDelegate = nullptr;
194 : // Access control auxiliary delegate: Optional. Used to look up auxiliary access control rules.
195 : // May be either pre-initialized (Initialize already called) or default-constructed:
196 : // Server::Init will call Initialize with its own FabricTable on a not-yet-initialized
197 : // delegate before registering it. Applications may substitute their own subclass of
198 : // Access::GroupAuxiliaryAccessControlDelegate rather than reusing the default Impl.
199 : Access::GroupAuxiliaryAccessControlDelegate * groupAuxiliaryAccessControlDelegate = nullptr;
200 : // ACL storage: MUST be injected. Used to store ACL entries in persistent storage. Must NOT
201 : // be initialized before being provided.
202 : app::AclStorage * aclStorage = nullptr;
203 :
204 : #if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
205 : // Access Restriction implementation: MUST be injected if MNGD feature enabled. Used to enforce
206 : // access restrictions that are managed by the device.
207 : Access::AccessRestrictionProvider * accessRestrictionProvider = nullptr;
208 : #endif
209 :
210 : // Network native params can be injected depending on the
211 : // selected Endpoint implementation
212 : void * endpointNativeParams = nullptr;
213 : // Optional. Support test event triggers when provided. Must be initialized before being
214 : // provided.
215 : TestEventTriggerDelegate * testEventTriggerDelegate = nullptr;
216 : // Operational keystore with access to the operational keys: MUST be injected.
217 : Crypto::OperationalKeystore * operationalKeystore = nullptr;
218 : // Operational certificate store with access to the operational certs in persisted storage:
219 : // must not be null at timne of Server::Init().
220 : Credentials::OperationalCertificateStore * opCertStore = nullptr;
221 : // Required, if not provided, the Server::Init() WILL fail.
222 : app::reporting::ReportScheduler * reportScheduler = nullptr;
223 : #if CHIP_CONFIG_ENABLE_ICD_CIP
224 : // Optional. Support for the ICD Check-In BackOff strategy. Must be initialized before being provided.
225 : // If the ICD Check-In protocol use-case is supported and no strategy is provided, server will use the default strategy.
226 : app::ICDCheckInBackOffStrategy * icdCheckInBackOffStrategy = nullptr;
227 : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
228 :
229 : // MUST NOT be null during initialization: every application must define the
230 : // data model it wants to use. Backwards-compatibility can use `CodegenDataModelProviderInstance`
231 : // for ember/zap-generated models.
232 : chip::app::DataModel::Provider * dataModelProvider = nullptr;
233 :
234 : bool advertiseCommissionableIfNoFabrics = CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART;
235 : };
236 :
237 : /**
238 : * Transitional version of ServerInitParams to assist SDK integrators in
239 : * transitioning to injecting product/platform-owned resources. This version
240 : * of `ServerInitParams` owns and initializes (via the `InitializeStaticResourcesBeforeServerInit()`
241 : * method) the persistent storage delegate, the group data provider, and the access control delegate.
242 : * This is to reduce the amount of copied boilerplate in all the example initializations
243 : * (e.g. AppTask.cpp, main.cpp).
244 : *
245 : * This version SHOULD BE USED ONLY FOR THE IN-TREE EXAMPLES.
246 : *
247 : * IMPORTANT: Instances of this class MUST outlive the Server because Server::Init()
248 : * stores pointers to resources owned by this class.
249 : *
250 : * ACTION ITEMS FOR TRANSITION from a example in-tree to a product:
251 : *
252 : * While this could be used indefinitely, it does not exemplify orderly management of
253 : * application-injected resources. It is recommended for actual products to instead:
254 : * - Use the basic ServerInitParams in the application
255 : * - Have the application own an instance of the resources being injected in its own
256 : * state (e.g. an implementation of PersistentStorageDelegate and GroupDataProvider
257 : * interfaces).
258 : * - Initialize the injected resources prior to calling Server::Init()
259 : * - De-initialize the injected resources after calling Server::Shutdown()
260 : *
261 : * WARNING: DO NOT replicate the pattern shown here of having a subclass of ServerInitParams
262 : * own the resources outside of examples. This was done to reduce the amount of change
263 : * to existing examples while still supporting non-example versions of the
264 : * resources to be injected.
265 : */
266 : struct CommonCaseDeviceServerInitParams : public ServerInitParams
267 : {
268 1 : CommonCaseDeviceServerInitParams() = default;
269 :
270 : // Not copyable
271 : CommonCaseDeviceServerInitParams(const CommonCaseDeviceServerInitParams &) = delete;
272 : CommonCaseDeviceServerInitParams & operator=(const CommonCaseDeviceServerInitParams &) = delete;
273 :
274 : /**
275 : * Call this before Server::Init() to initialize the internally-owned resources.
276 : * Server::Init() will fail if this is not done, since several params required to
277 : * be non-null will be null without calling this method. ** See the transition method
278 : * in the outer comment of this class **.
279 : *
280 : * @return CHIP_NO_ERROR on success or a CHIP_ERROR value from APIs called to initialize
281 : * resources on failure.
282 : */
283 1 : CHIP_ERROR InitializeStaticResourcesBeforeServerInit()
284 : {
285 : // KVS-based persistent storage delegate injection
286 1 : if (persistentStorageDelegate == nullptr)
287 : {
288 : chip::DeviceLayer::PersistedStorage::KeyValueStoreManager & kvsManager =
289 1 : DeviceLayer::PersistedStorage::KeyValueStoreMgr();
290 1 : ReturnErrorOnFailure(mKvsPersistentStorageDelegate.Init(&kvsManager));
291 1 : this->persistentStorageDelegate = &mKvsPersistentStorageDelegate;
292 : }
293 :
294 : // PersistentStorageDelegate "software-based" operational key access injection
295 1 : if (this->operationalKeystore == nullptr)
296 : {
297 : // WARNING: PersistentStorageOperationalKeystore::Finish() is never called. It's fine for
298 : // for examples and for now.
299 1 : ReturnErrorOnFailure(mPersistentStorageOperationalKeystore.Init(this->persistentStorageDelegate));
300 1 : this->operationalKeystore = &mPersistentStorageOperationalKeystore;
301 : }
302 :
303 : // OpCertStore can be injected but default to persistent storage default
304 : // for simplicity of the examples.
305 1 : if (this->opCertStore == nullptr)
306 : {
307 : // WARNING: PersistentStorageOpCertStore::Finish() is never called. It's fine for
308 : // for examples and for now, since all storage is immediate for that impl.
309 1 : ReturnErrorOnFailure(mPersistentStorageOpCertStore.Init(this->persistentStorageDelegate));
310 1 : this->opCertStore = &mPersistentStorageOpCertStore;
311 : }
312 :
313 : // Injection of report scheduler WILL lead to two schedulers being allocated. As recommended above, this should only be used
314 : // for IN-TREE examples. If a default scheduler is desired, the basic ServerInitParams should be used by the application and
315 : // CommonCaseDeviceServerInitParams should not be allocated.
316 1 : if (this->reportScheduler == nullptr)
317 : {
318 0 : this->reportScheduler = &mReportScheduler;
319 : }
320 :
321 : // Session Keystore injection
322 1 : if (this->sessionKeystore == nullptr)
323 : {
324 1 : this->sessionKeystore = &mSessionKeystore;
325 : }
326 :
327 : // Group Data provider injection
328 1 : if (this->groupDataProvider == nullptr)
329 : {
330 1 : mGroupDataProvider.SetStorageDelegate(this->persistentStorageDelegate);
331 1 : mGroupDataProvider.SetSessionKeystore(this->sessionKeystore);
332 1 : ReturnErrorOnFailure(mGroupDataProvider.Init());
333 1 : this->groupDataProvider = &mGroupDataProvider;
334 : }
335 :
336 : #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
337 1 : if (this->sessionResumptionStorage == nullptr)
338 : {
339 1 : ChipLogProgress(AppServer, "Initializing session resumption storage...");
340 1 : ReturnErrorOnFailure(mSessionResumptionStorage.Init(this->persistentStorageDelegate));
341 1 : this->sessionResumptionStorage = &mSessionResumptionStorage;
342 : }
343 : #endif
344 :
345 : // Inject access control delegate
346 1 : if (this->accessDelegate == nullptr)
347 : {
348 1 : this->accessDelegate = Access::Examples::GetAccessControlDelegate();
349 : }
350 :
351 1 : if (this->aclStorage == nullptr)
352 : {
353 : // Inject ACL storage. (Don't initialize it.)
354 1 : this->aclStorage = &mAclStorage;
355 : }
356 :
357 : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
358 1 : if (this->subscriptionResumptionStorage == nullptr)
359 : {
360 1 : ChipLogProgress(AppServer, "Initializing subscription resumption storage...");
361 1 : ReturnErrorOnFailure(mSubscriptionResumptionStorage.Init(this->persistentStorageDelegate));
362 1 : this->subscriptionResumptionStorage = &mSubscriptionResumptionStorage;
363 : }
364 : #endif
365 :
366 : #if CHIP_CONFIG_ENABLE_ICD_CIP
367 : if (this->icdCheckInBackOffStrategy == nullptr)
368 : {
369 : this->icdCheckInBackOffStrategy = &mICDCheckInBackOffStrategy;
370 : }
371 : #endif
372 :
373 : #if CHIP_CONFIG_ENABLE_GROUPCAST
374 : if (this->groupAuxiliaryAccessControlDelegate == nullptr)
375 : {
376 : // The delegate is left uninitialized here on purpose: Server::Init will call
377 : // Initialize on it with the Server-owned FabricTable, which is not reachable
378 : // from this scope.
379 : this->groupAuxiliaryAccessControlDelegate = &mGroupAuxiliaryAccessControlDelegate;
380 : }
381 : #endif // CHIP_CONFIG_ENABLE_GROUPCAST
382 :
383 1 : return CHIP_NO_ERROR;
384 : }
385 :
386 : private:
387 : // Owned resources - these are instance members (not static) so each
388 : // CommonCaseDeviceServerInitParams instance owns its own copy.
389 : // They must outlive Server::Init() because that method stores pointers to them.
390 : KvsPersistentStorageDelegate mKvsPersistentStorageDelegate;
391 : PersistentStorageOperationalKeystore mPersistentStorageOperationalKeystore;
392 : Credentials::PersistentStorageOpCertStore mPersistentStorageOpCertStore;
393 : Credentials::GroupDataProviderImpl mGroupDataProvider;
394 : app::DefaultTimerDelegate mTimerDelegate;
395 : app::reporting::ReportSchedulerImpl mReportScheduler{ &mTimerDelegate };
396 :
397 : #if CHIP_CONFIG_ENABLE_SESSION_RESUMPTION
398 : SimpleSessionResumptionStorage mSessionResumptionStorage;
399 : #endif
400 :
401 : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
402 : app::SimpleSubscriptionResumptionStorage mSubscriptionResumptionStorage;
403 : #endif
404 :
405 : app::DefaultAclStorage mAclStorage;
406 : Crypto::DefaultSessionKeystore mSessionKeystore;
407 :
408 : #if CHIP_CONFIG_ENABLE_ICD_CIP
409 : app::DefaultICDCheckInBackOffStrategy mICDCheckInBackOffStrategy;
410 : #endif
411 :
412 : #if CHIP_CONFIG_ENABLE_GROUPCAST
413 : // Default delegate used when the application does not provide its own. Concrete Impl,
414 : // exposed through the abstract base via groupAuxiliaryAccessControlDelegate above.
415 : Access::Examples::GroupAuxiliaryAccessControlDelegateImpl mGroupAuxiliaryAccessControlDelegate;
416 : #endif
417 : };
418 :
419 : /**
420 : * The `Server` singleton class is an aggregate for all the resources needed to run a
421 : * Node that is both Commissionable and mainly used as an end-node with server clusters.
422 : * In other words, it aggregates the state needed for the type of Node used for most
423 : * products that are not mainly controller/administrator role.
424 : *
425 : * This sington class expects `ServerInitParams` initialization parameters but does not
426 : * own the resources injected from `ServerInitParams`. Any object pointers/references
427 : * passed in ServerInitParams must be pre-initialized externally, and shutdown/finalized
428 : * after `Server::Shutdown()` is called.
429 : *
430 : * TODO: Separate lifecycle ownership for some more capabilities that should not belong to
431 : * common logic, such as `GenerateShutDownEvent`.
432 : *
433 : * TODO: Replace all uses of GetInstance() to "reach in" to this state from all cluster
434 : * server common logic that deal with global node state with either a common NodeState
435 : * compatible with OperationalDeviceProxy/DeviceProxy, or with injection at common
436 : * SDK logic init.
437 : */
438 : class Server
439 : {
440 : public:
441 : CHIP_ERROR Init(const ServerInitParams & initParams);
442 :
443 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
444 : CHIP_ERROR
445 : SendUserDirectedCommissioningRequest(chip::Transport::PeerAddress commissioner,
446 : Protocols::UserDirectedCommissioning::IdentificationDeclaration & id);
447 :
448 : Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient * GetUserDirectedCommissioningClient()
449 : {
450 : return gUDCClient;
451 : }
452 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
453 :
454 : /**
455 : * @brief Call this function to rejoin existing groups found in the GroupDataProvider
456 : */
457 : void RejoinExistingMulticastGroups();
458 :
459 1265 : FabricTable & GetFabricTable() { return mFabrics; }
460 :
461 : Access::AccessControl & GetAccessControl() { return mAccessControl; }
462 :
463 1239 : CASESessionManager * GetCASESessionManager() { return &mCASESessionManager; }
464 :
465 26 : Messaging::ExchangeManager & GetExchangeManager() { return mExchangeMgr; }
466 :
467 12 : SessionManager & GetSecureSessionManager() { return mSessions; }
468 :
469 0 : SessionResumptionStorage * GetSessionResumptionStorage() { return mSessionResumptionStorage; }
470 :
471 0 : app::SubscriptionResumptionStorage * GetSubscriptionResumptionStorage() { return mSubscriptionResumptionStorage; }
472 :
473 0 : TransportMgrBase & GetTransportManager() { return mTransports; }
474 :
475 2 : Credentials::GroupDataProvider * GetGroupDataProvider() { return mGroupsProvider; }
476 :
477 : Crypto::SessionKeystore * GetSessionKeystore() const { return mSessionKeystore; }
478 :
479 : #if CONFIG_NETWORK_LAYER_BLE
480 10 : Ble::BleLayer * GetBleLayerObject() { return mBleLayer; }
481 : #endif
482 :
483 27 : CommissioningWindowManager & GetCommissioningWindowManager() { return mCommissioningWindowManager; }
484 :
485 1 : PersistentStorageDelegate & GetPersistentStorage() { return *mDeviceStorage; }
486 :
487 33 : app::FailSafeContext & GetFailSafeContext() { return mFailSafeContext; }
488 :
489 : TestEventTriggerDelegate * GetTestEventTriggerDelegate() { return mTestEventTriggerDelegate; }
490 :
491 : Crypto::OperationalKeystore * GetOperationalKeystore() { return mOperationalKeystore; }
492 :
493 : Credentials::OperationalCertificateStore * GetOpCertStore() { return mOpCertStore; }
494 :
495 : app::DefaultSafeAttributePersistenceProvider & GetDefaultAttributePersister() { return mAttributePersister; }
496 :
497 : app::reporting::ReportScheduler * GetReportScheduler() { return mReportScheduler; }
498 :
499 : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
500 : app::JointFabricDatastore & GetJointFabricDatastore() { return mJointFabricDatastore; }
501 7 : app::JointFabricAdministrator & GetJointFabricAdministrator() { return mJointFabricAdministrator; }
502 : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
503 :
504 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
505 : app::ICDManager & GetICDManager() { return mICDManager; }
506 :
507 : #if CHIP_CONFIG_ENABLE_ICD_CIP
508 : /**
509 : * @brief Function to determine if a Check-In message would be sent at Boot up
510 : *
511 : * @param aFabricIndex client fabric index
512 : * @param subjectID client subject ID
513 : * @return true Check-In message would be sent on boot up.
514 : * @return false Device has a persisted subscription with the client. See CHIP_CONFIG_PERSIST_SUBSCRIPTIONS.
515 : */
516 : bool ShouldCheckInMsgsBeSentAtBootFunction(FabricIndex aFabricIndex, NodeId subjectID);
517 : #endif // CHIP_CONFIG_ENABLE_ICD_CIP
518 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
519 :
520 : /**
521 : * This function causes the ShutDown event to be generated async on the
522 : * Matter event loop. Should be called before stopping the event loop.
523 : */
524 : void GenerateShutDownEvent();
525 :
526 : void Shutdown();
527 :
528 : void ScheduleFactoryReset();
529 :
530 : System::Clock::Microseconds64 TimeSinceInit() const
531 : {
532 : return System::SystemClock().GetMonotonicMicroseconds64() - mInitTimestamp;
533 : }
534 :
535 2575 : static Server & GetInstance() { return sServer; }
536 :
537 : private:
538 142 : Server() {}
539 :
540 : static Server sServer;
541 :
542 : void InitFailSafe();
543 : void OnPlatformEvent(const DeviceLayer::ChipDeviceEvent & event);
544 : void CheckServerReadyEvent();
545 :
546 : void PostFactoryResetEvent();
547 :
548 : static void OnPlatformEventWrapper(const DeviceLayer::ChipDeviceEvent * event, intptr_t);
549 :
550 : #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
551 : /**
552 : * @brief Called at Server::Init time to resume persisted subscriptions if the feature flag is enabled
553 : */
554 : void ResumeSubscriptions();
555 : #endif
556 :
557 : class GroupDataProviderListener final : public Credentials::GroupDataProvider::GroupListener
558 : {
559 : public:
560 142 : GroupDataProviderListener() {}
561 :
562 1 : CHIP_ERROR Init(Server * server)
563 : {
564 1 : VerifyOrReturnError(server != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
565 :
566 1 : mServer = server;
567 1 : return CHIP_NO_ERROR;
568 : };
569 :
570 0 : void OnGroupAdded(chip::FabricIndex fabric_index, const Credentials::GroupDataProvider::GroupInfo & new_group) override
571 : {
572 0 : const FabricInfo * fabric = mServer->GetFabricTable().FindFabricWithIndex(fabric_index);
573 0 : if (fabric == nullptr)
574 : {
575 0 : ChipLogError(AppServer, "Group added to nonexistent fabric?");
576 0 : return;
577 : }
578 :
579 0 : const Transport::PeerAddress & address = new_group.UsePerGroupAddress()
580 0 : ? Transport::PeerAddress::BuildMatterPerGroupMulticastAddress(fabric->GetFabricId(), new_group.group_id)
581 0 : : Transport::PeerAddress::BuildMatterIanaMulticastAddress();
582 :
583 0 : if (CHIP_NO_ERROR != mServer->GetTransportManager().MulticastGroupJoinLeave(address, true))
584 : {
585 0 : ChipLogError(AppServer, "Unable to listen to group");
586 : }
587 : };
588 :
589 0 : void OnGroupRemoved(chip::FabricIndex fabric_index, const Credentials::GroupDataProvider::GroupInfo & old_group) override
590 : {
591 0 : if (old_group.UsePerGroupAddress())
592 : {
593 : // Per group address no longer in use, unsubscribe
594 0 : const FabricInfo * fabric = mServer->GetFabricTable().FindFabricWithIndex(fabric_index);
595 0 : if (fabric == nullptr)
596 : {
597 0 : ChipLogError(AppServer, "Group removed from nonexistent fabric?");
598 0 : return;
599 : }
600 : const Transport::PeerAddress & address =
601 0 : Transport::PeerAddress::BuildMatterPerGroupMulticastAddress(fabric->GetFabricId(), old_group.group_id);
602 0 : VerifyOrReturn(CHIP_NO_ERROR == mServer->GetTransportManager().MulticastGroupJoinLeave(address, false));
603 : }
604 : else
605 : {
606 : // Check if the address is still in use
607 0 : Credentials::GroupDataProvider * provider = mServer->GetGroupDataProvider();
608 0 : bool in_use = false;
609 0 : if (nullptr != provider)
610 : {
611 : // Check all groups from all fabrics
612 0 : Credentials::GroupDataProvider::GroupInfo group;
613 0 : for (const FabricInfo & fabric : mServer->GetFabricTable())
614 : {
615 0 : chip::AutoRelease iter(provider->IterateGroupInfo(fabric.GetFabricIndex()));
616 0 : while (!iter.IsNull() && iter->Next(group) && !in_use)
617 : {
618 0 : in_use = !group.UsePerGroupAddress();
619 : }
620 0 : if (in_use)
621 0 : break;
622 0 : }
623 : }
624 0 : if (!in_use)
625 : {
626 : // Groupcast address no longer in use, unsubscribe
627 0 : const Transport::PeerAddress & address = Transport::PeerAddress::BuildMatterIanaMulticastAddress();
628 0 : VerifyOrReturn(CHIP_NO_ERROR == mServer->GetTransportManager().MulticastGroupJoinLeave(address, false));
629 : }
630 : }
631 : };
632 :
633 : private:
634 : Server * mServer;
635 : };
636 :
637 : class ServerFabricDelegate final : public chip::FabricTable::Delegate
638 : {
639 : public:
640 142 : ServerFabricDelegate() {}
641 :
642 1 : CHIP_ERROR Init(Server * server)
643 : {
644 1 : VerifyOrReturnError(server != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
645 :
646 1 : mServer = server;
647 1 : return CHIP_NO_ERROR;
648 : }
649 :
650 0 : void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override
651 : {
652 : (void) fabricTable;
653 0 : ClearCASEResumptionStateOnFabricChange(fabricIndex);
654 0 : ClearSubscriptionResumptionStateOnFabricChange(fabricIndex);
655 :
656 0 : Credentials::GroupDataProvider * groupDataProvider = mServer->GetGroupDataProvider();
657 0 : if (groupDataProvider != nullptr)
658 : {
659 0 : CHIP_ERROR err = groupDataProvider->RemoveFabric(fabricIndex);
660 0 : if (err != CHIP_NO_ERROR)
661 : {
662 0 : ChipLogError(AppServer,
663 : "Warning, failed to delete GroupDataProvider state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
664 : static_cast<unsigned>(fabricIndex), err.Format());
665 : }
666 : }
667 :
668 : // Remove access control entries in reverse order (it could be any order, but reverse order
669 : // will cause less churn in persistent storage).
670 0 : CHIP_ERROR aclErr = Access::GetAccessControl().DeleteAllEntriesForFabric(fabricIndex);
671 0 : if (aclErr != CHIP_NO_ERROR)
672 : {
673 0 : ChipLogError(AppServer, "Warning, failed to delete access control state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
674 : static_cast<unsigned>(fabricIndex), aclErr.Format());
675 : }
676 :
677 : // Remove ACL extension entry for the given fabricIndex.
678 0 : auto & storage = mServer->GetPersistentStorage();
679 0 : aclErr = storage.SyncDeleteKeyValue(DefaultStorageKeyAllocator::AccessControlExtensionEntry(fabricIndex).KeyName());
680 :
681 0 : if (aclErr != CHIP_NO_ERROR && aclErr != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND)
682 : {
683 0 : ChipLogError(AppServer, "Warning, failed to delete ACL extension entry for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
684 : static_cast<unsigned>(fabricIndex), aclErr.Format());
685 : }
686 :
687 0 : mServer->GetCommissioningWindowManager().OnFabricRemoved(fabricIndex);
688 0 : }
689 :
690 0 : void OnFabricUpdated(const FabricTable & fabricTable, chip::FabricIndex fabricIndex) override
691 : {
692 : (void) fabricTable;
693 0 : ClearCASEResumptionStateOnFabricChange(fabricIndex);
694 0 : }
695 :
696 : private:
697 0 : void ClearCASEResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
698 : {
699 0 : auto * sessionResumptionStorage = mServer->GetSessionResumptionStorage();
700 0 : VerifyOrReturn(sessionResumptionStorage != nullptr);
701 0 : CHIP_ERROR err = sessionResumptionStorage->DeleteAll(fabricIndex);
702 0 : if (err != CHIP_NO_ERROR)
703 : {
704 0 : ChipLogError(AppServer,
705 : "Warning, failed to delete session resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
706 : static_cast<unsigned>(fabricIndex), err.Format());
707 : }
708 : }
709 :
710 0 : void ClearSubscriptionResumptionStateOnFabricChange(chip::FabricIndex fabricIndex)
711 : {
712 0 : auto * subscriptionResumptionStorage = mServer->GetSubscriptionResumptionStorage();
713 0 : VerifyOrReturn(subscriptionResumptionStorage != nullptr);
714 0 : CHIP_ERROR err = subscriptionResumptionStorage->DeleteAll(fabricIndex);
715 0 : if (err != CHIP_NO_ERROR)
716 : {
717 0 : ChipLogError(AppServer,
718 : "Warning, failed to delete subscription resumption state for fabric index 0x%x: %" CHIP_ERROR_FORMAT,
719 : static_cast<unsigned>(fabricIndex), err.Format());
720 : }
721 : }
722 :
723 : Server * mServer = nullptr;
724 : };
725 :
726 : /**
727 : * Since root certificates for Matter nodes cannot be updated in a reasonable
728 : * way, it doesn't make sense to enforce expiration time on root certificates.
729 : * This policy allows through root certificates, even if they're expired, and
730 : * otherwise delegates to the provided policy, or to the default policy if no
731 : * policy is provided.
732 : */
733 : class IgnoreRootExpirationValidityPolicy : public Credentials::CertificateValidityPolicy
734 : {
735 : public:
736 142 : IgnoreRootExpirationValidityPolicy() {}
737 :
738 1 : void Init(Credentials::CertificateValidityPolicy * providedPolicy) { mProvidedPolicy = providedPolicy; }
739 :
740 0 : CHIP_ERROR ApplyCertificateValidityPolicy(const Credentials::ChipCertificateData * cert, uint8_t depth,
741 : Credentials::CertificateValidityResult result) override
742 : {
743 0 : switch (result)
744 : {
745 0 : case Credentials::CertificateValidityResult::kExpired:
746 : case Credentials::CertificateValidityResult::kExpiredAtLastKnownGoodTime:
747 : case Credentials::CertificateValidityResult::kTimeUnknown: {
748 : Credentials::CertType certType;
749 0 : ReturnErrorOnFailure(cert->mSubjectDN.GetCertType(certType));
750 0 : if (certType == Credentials::CertType::kRoot)
751 : {
752 0 : return CHIP_NO_ERROR;
753 : }
754 :
755 0 : break;
756 : }
757 0 : default:
758 0 : break;
759 : }
760 :
761 0 : if (mProvidedPolicy)
762 : {
763 0 : return mProvidedPolicy->ApplyCertificateValidityPolicy(cert, depth, result);
764 : }
765 :
766 0 : return Credentials::CertificateValidityPolicy::ApplyDefaultPolicy(cert, depth, result);
767 : }
768 :
769 : private:
770 : Credentials::CertificateValidityPolicy * mProvidedPolicy = nullptr;
771 : };
772 :
773 : #if CONFIG_NETWORK_LAYER_BLE
774 : Ble::BleLayer * mBleLayer = nullptr;
775 : #endif
776 :
777 : // By default, use a certificate validation policy compatible with non-wall-clock-time-synced
778 : // embedded systems.
779 : static Credentials::IgnoreCertificateValidityPeriodPolicy sDefaultCertValidityPolicy;
780 :
781 : ServerTransportMgr mTransports;
782 : SessionManager mSessions;
783 : CASEServer mCASEServer;
784 :
785 : CASESessionManager mCASESessionManager;
786 : CASEClientPool<CHIP_CONFIG_DEVICE_MAX_ACTIVE_CASE_CLIENTS> mCASEClientPool;
787 : OperationalSessionSetupPool<CHIP_CONFIG_DEVICE_MAX_ACTIVE_DEVICES> mSessionSetupPool;
788 :
789 : Protocols::SecureChannel::UnsolicitedStatusHandler mUnsolicitedStatusHandler;
790 : Messaging::ExchangeManager mExchangeMgr;
791 : FabricTable mFabrics;
792 : secure_channel::MessageCounterManager mMessageCounterManager;
793 : #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
794 : Protocols::UserDirectedCommissioning::UserDirectedCommissioningClient * gUDCClient = nullptr;
795 : // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
796 : // specifically, the commissioner declaration message (sent by commissioner to commissionee)
797 : UdcTransportMgr * mUdcTransportMgr = nullptr;
798 : uint16_t mCdcListenPort = CHIP_UDC_COMMISSIONEE_PORT;
799 : #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
800 : CommissioningWindowManager mCommissioningWindowManager;
801 :
802 : IgnoreRootExpirationValidityPolicy mCertificateValidityPolicy;
803 :
804 : PersistentStorageDelegate * mDeviceStorage;
805 : SessionResumptionStorage * mSessionResumptionStorage;
806 : app::SubscriptionResumptionStorage * mSubscriptionResumptionStorage;
807 : Credentials::GroupDataProvider * mGroupsProvider;
808 : Crypto::SessionKeystore * mSessionKeystore;
809 : app::DefaultSafeAttributePersistenceProvider mAttributePersister;
810 : GroupDataProviderListener mListener;
811 : ServerFabricDelegate mFabricDelegate;
812 : app::reporting::ReportScheduler * mReportScheduler;
813 :
814 : Access::AccessControl mAccessControl;
815 : app::AclStorage * mAclStorage;
816 :
817 : #if CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
818 : app::JointFabricDatastore mJointFabricDatastore;
819 : app::JointFabricAdministrator mJointFabricAdministrator;
820 : #endif // CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC
821 :
822 : TestEventTriggerDelegate * mTestEventTriggerDelegate;
823 : Crypto::OperationalKeystore * mOperationalKeystore;
824 : Credentials::OperationalCertificateStore * mOpCertStore;
825 : app::FailSafeContext mFailSafeContext;
826 :
827 : bool mIsDnssdReady = false;
828 : uint16_t mOperationalServicePort;
829 : uint16_t mUserDirectedCommissioningPort;
830 : Inet::InterfaceId mInterfaceId;
831 :
832 : System::Clock::Microseconds64 mInitTimestamp;
833 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
834 : app::ICDManager mICDManager;
835 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
836 : };
837 :
838 : } // namespace chip
|