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