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