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