Skip to content

Commit 2510290

Browse files
jepenven-silabspull[bot]
authored andcommitted
[Group] Fabric removal sync (#15874)
* Fabric removal sync
1 parent 76898b1 commit 2510290

12 files changed

+187
-16
lines changed

src/app/server/Server.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint
184184
err = mSessions.Init(&DeviceLayer::SystemLayer(), &mTransports, &mMessageCounterManager, &mDeviceStorage, &GetFabricTable());
185185
SuccessOrExit(err);
186186

187+
err = mFabricDelegate.Init(&mSessions);
188+
SuccessOrExit(err);
189+
mFabrics.AddFabricDelegate(&mFabricDelegate);
190+
187191
err = mExchangeMgr.Init(&mSessions);
188192
SuccessOrExit(err);
189193
err = mMessageCounterManager.Init(&mExchangeMgr);

src/app/server/Server.h

+35
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,40 @@ class Server
170170
ServerTransportMgr * mTransports;
171171
};
172172

173+
class ServerFabricDelegate final : public FabricTableDelegate
174+
{
175+
public:
176+
ServerFabricDelegate() {}
177+
178+
CHIP_ERROR Init(SessionManager * sessionManager)
179+
{
180+
VerifyOrReturnError(sessionManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
181+
182+
mSessionManager = sessionManager;
183+
return CHIP_NO_ERROR;
184+
};
185+
186+
void OnFabricDeletedFromStorage(CompressedFabricId compressedId, FabricIndex fabricIndex) override
187+
{
188+
(void) compressedId;
189+
if (mSessionManager != nullptr)
190+
{
191+
mSessionManager->FabricRemoved(fabricIndex);
192+
}
193+
Credentials::GroupDataProvider * groupDataProvider = Credentials::GetGroupDataProvider();
194+
if (groupDataProvider != nullptr)
195+
{
196+
groupDataProvider->RemoveFabric(fabricIndex);
197+
}
198+
};
199+
void OnFabricRetrievedFromStorage(FabricInfo * fabricInfo) override { (void) fabricInfo; }
200+
201+
void OnFabricPersistedToStorage(FabricInfo * fabricInfo) override { (void) fabricInfo; }
202+
203+
private:
204+
SessionManager * mSessionManager = nullptr;
205+
};
206+
173207
#if CONFIG_NETWORK_LAYER_BLE
174208
Ble::BleLayer * mBleLayer = nullptr;
175209
#endif
@@ -198,6 +232,7 @@ class Server
198232
Credentials::GroupDataProviderImpl mGroupsProvider;
199233
app::DefaultAttributePersistenceProvider mAttributePersister;
200234
GroupDataProviderListener mListener;
235+
ServerFabricDelegate mFabricDelegate;
201236

202237
Access::AccessControl mAccessControl;
203238

src/controller/CHIPDeviceControllerFactory.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params)
146146

147147
ReturnErrorOnFailure(stateParams.fabricTable->Init(params.fabricIndependentStorage));
148148

149+
auto delegate = chip::Platform::MakeUnique<ControllerFabricDelegate>(stateParams.sessionMgr);
150+
ReturnErrorOnFailure(stateParams.fabricTable->AddFabricDelegate(delegate.get()));
151+
delegate.release();
152+
149153
ReturnErrorOnFailure(stateParams.sessionMgr->Init(stateParams.systemLayer, stateParams.transportMgr,
150154
stateParams.messageCounterManager, params.fabricIndependentStorage,
151155
stateParams.fabricTable));

src/controller/CHIPDeviceControllerFactory.h

+36
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <controller/CHIPDeviceController.h>
3333
#include <controller/CHIPDeviceControllerSystemState.h>
34+
#include <credentials/GroupDataProviderImpl.h>
3435
#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
3536

3637
namespace chip {
@@ -137,6 +138,41 @@ class DeviceControllerFactory
137138
//
138139
void ReleaseSystemState() { mSystemState->Release(); }
139140

141+
class ControllerFabricDelegate final : public FabricTableDelegate
142+
{
143+
public:
144+
ControllerFabricDelegate() {}
145+
ControllerFabricDelegate(SessionManager * sessionManager) : FabricTableDelegate(true), mSessionManager(sessionManager) {}
146+
147+
CHIP_ERROR Init(SessionManager * sessionManager)
148+
{
149+
VerifyOrReturnError(sessionManager != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
150+
151+
mSessionManager = sessionManager;
152+
return CHIP_NO_ERROR;
153+
};
154+
155+
void OnFabricDeletedFromStorage(CompressedFabricId compressedId, FabricIndex fabricIndex) override
156+
{
157+
if (mSessionManager != nullptr)
158+
{
159+
mSessionManager->FabricRemoved(fabricIndex);
160+
}
161+
Credentials::GroupDataProvider * groupDataProvider = Credentials::GetGroupDataProvider();
162+
if (groupDataProvider != nullptr)
163+
{
164+
groupDataProvider->RemoveFabric(fabricIndex);
165+
}
166+
};
167+
168+
void OnFabricRetrievedFromStorage(FabricInfo * fabricInfo) override { (void) fabricInfo; }
169+
170+
void OnFabricPersistedToStorage(FabricInfo * fabricInfo) override { (void) fabricInfo; }
171+
172+
private:
173+
SessionManager * mSessionManager = nullptr;
174+
};
175+
140176
private:
141177
DeviceControllerFactory(){};
142178
void PopulateInitParams(ControllerInitParams & controllerParams, const SetupParams & params);

src/credentials/FabricTable.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,20 @@ CHIP_ERROR FabricInfo::MatchDestinationID(const ByteSpan & targetDestinationId,
401401
return CHIP_ERROR_CERT_NOT_TRUSTED;
402402
}
403403

404+
FabricTable::~FabricTable()
405+
{
406+
FabricTableDelegate * delegate = mDelegate;
407+
while (delegate)
408+
{
409+
FabricTableDelegate * temp = delegate->mNext;
410+
if (delegate->mOwnedByFabricTable)
411+
{
412+
chip::Platform::Delete(delegate);
413+
}
414+
delegate = temp;
415+
}
416+
}
417+
404418
void FabricTable::ReleaseFabricIndex(FabricIndex fabricIndex)
405419
{
406420
FabricInfo * fabric = FindFabricWithIndex(fabricIndex);
@@ -629,6 +643,7 @@ CHIP_ERROR FabricTable::Delete(FabricIndex index)
629643
mFabricCount--;
630644
}
631645
ChipLogProgress(Discovery, "Fabric (%d) deleted. Calling OnFabricDeletedFromStorage", index);
646+
632647
FabricTableDelegate * delegate = mDelegate;
633648
while (delegate)
634649
{
@@ -651,6 +666,7 @@ void FabricTable::DeleteAllFabrics()
651666
CHIP_ERROR FabricTable::Init(PersistentStorageDelegate * storage)
652667
{
653668
VerifyOrReturnError(storage != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
669+
654670
mStorage = storage;
655671
ChipLogDetail(Discovery, "Init fabric pairing table with server storage");
656672

src/credentials/FabricTable.h

+4
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ class DLL_EXPORT FabricTableDelegate
274274
friend class FabricTable;
275275

276276
public:
277+
FabricTableDelegate(bool ownedByFabricTable = false) : mOwnedByFabricTable(ownedByFabricTable) {}
277278
virtual ~FabricTableDelegate() {}
278279
/**
279280
* Gets called when a fabric is deleted from KVS store.
@@ -292,6 +293,7 @@ class DLL_EXPORT FabricTableDelegate
292293

293294
private:
294295
FabricTableDelegate * mNext = nullptr;
296+
bool mOwnedByFabricTable = false;
295297
};
296298

297299
/**
@@ -365,6 +367,8 @@ class DLL_EXPORT FabricTable
365367
{
366368
public:
367369
FabricTable() { Reset(); }
370+
~FabricTable();
371+
368372
CHIP_ERROR Store(FabricIndex index);
369373
CHIP_ERROR LoadFromStorage(FabricInfo * info);
370374

src/credentials/GroupDataProvider.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class GroupDataProvider
166166
/**
167167
* Callback invoked when an existing group is removed.
168168
*
169-
* @param[in] removed_state GroupInfo structure of the removed group.
169+
* @param[in] old_group GroupInfo structure of the removed group.
170170
*/
171171
virtual void OnGroupRemoved(FabricIndex fabric_index, const GroupInfo & old_group) = 0;
172172
};

src/transport/GroupPeerMessageCounter.cpp

+45-14
Original file line numberDiff line numberDiff line change
@@ -151,27 +151,36 @@ CHIP_ERROR GroupPeerTable::RemovePeer(FabricIndex fabricIndex, NodeId nodeId, bo
151151
{
152152
if (mGroupFabrics[fabricIt].mDataPeerCount == 0 && mGroupFabrics[fabricIt].mControlPeerCount == 0)
153153
{
154-
mGroupFabrics[fabricIt].mFabricIndex = kUndefinedFabricIndex;
155-
// To maintain logic integrity Fabric array cannot have empty slot in between data
156-
// Find the last non empty element
157-
for (uint32_t i = CHIP_CONFIG_MAX_FABRICS - 1; i > fabricIt; i--)
158-
{
159-
if (mGroupFabrics[i].mFabricIndex != kUndefinedFabricIndex)
160-
{
161-
// Logic works since all buffer are static
162-
// move it up front
163-
new (&mGroupFabrics[fabricIt]) GroupFabric(mGroupFabrics[i]);
164-
new (&mGroupFabrics[i]) GroupFabric();
165-
break;
166-
}
167-
}
154+
RemoveAndCompactFabric(fabricIt);
168155
}
169156
}
170157

171158
// Cannot find Peer to remove
172159
return err;
173160
}
174161

162+
CHIP_ERROR GroupPeerTable::FabricRemoved(FabricIndex fabricIndex)
163+
{
164+
CHIP_ERROR err = CHIP_ERROR_NOT_FOUND;
165+
166+
if (fabricIndex == kUndefinedFabricIndex)
167+
{
168+
return CHIP_ERROR_INVALID_ARGUMENT;
169+
}
170+
171+
for (uint32_t it = 0; it < CHIP_CONFIG_MAX_FABRICS; it++)
172+
{
173+
if (fabricIndex == mGroupFabrics[it].mFabricIndex)
174+
{
175+
RemoveAndCompactFabric(it);
176+
return CHIP_NO_ERROR;
177+
}
178+
}
179+
180+
// Cannot find Fabric to remove
181+
return err;
182+
}
183+
175184
bool GroupPeerTable::RemoveSpecificPeer(GroupSender * list, NodeId nodeId, uint32_t size)
176185
{
177186
bool removed = false;
@@ -222,6 +231,28 @@ void GroupPeerTable::CompactPeers(GroupSender * list, uint32_t size)
222231
}
223232
}
224233

234+
void GroupPeerTable::RemoveAndCompactFabric(uint32_t tableIndex)
235+
{
236+
if (tableIndex >= CHIP_CONFIG_MAX_FABRICS)
237+
{
238+
return;
239+
}
240+
mGroupFabrics[tableIndex].mFabricIndex = kUndefinedFabricIndex;
241+
// To maintain logic integrity Fabric array cannot have empty slot in between data
242+
// Find the last non empty element
243+
for (uint32_t i = CHIP_CONFIG_MAX_FABRICS - 1; i > tableIndex; i--)
244+
{
245+
if (mGroupFabrics[i].mFabricIndex != kUndefinedFabricIndex)
246+
{
247+
// Logic works since all buffer are static
248+
// move it up front
249+
new (&mGroupFabrics[tableIndex]) GroupFabric(mGroupFabrics[i]);
250+
new (&mGroupFabrics[i]) GroupFabric();
251+
break;
252+
}
253+
}
254+
}
255+
225256
GroupOutgoingCounters::GroupOutgoingCounters(chip::PersistentStorageDelegate * storage_delegate)
226257
{
227258
Init(storage_delegate);

src/transport/GroupPeerMessageCounter.h

+3
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,13 @@ class GroupPeerTable
6262
// Used in case of MCSP failure
6363
CHIP_ERROR RemovePeer(FabricIndex fabricIndex, NodeId nodeId, bool isControl);
6464

65+
CHIP_ERROR FabricRemoved(FabricIndex fabricIndex);
66+
6567
// Protected for Unit Tests inheritance
6668
protected:
6769
bool RemoveSpecificPeer(GroupSender * list, NodeId nodeId, uint32_t size);
6870
void CompactPeers(GroupSender * list, uint32_t size);
71+
void RemoveAndCompactFabric(uint32_t tableIndex);
6972

7073
GroupFabric mGroupFabrics[CHIP_CONFIG_MAX_FABRICS];
7174
};

src/transport/SessionManager.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ void SessionManager::Shutdown()
117117
mCB = nullptr;
118118
}
119119

120+
/**
121+
* @brief Notification that a fabric was removed.
122+
* This function doesn't call ExpireAllPairingsForFabric
123+
* since the CASE session might still be open to send a response
124+
* on the removed fabric.
125+
*/
126+
void SessionManager::FabricRemoved(FabricIndex fabricIndex)
127+
{
128+
mGroupPeerMsgCounter.FabricRemoved(fabricIndex);
129+
}
130+
120131
CHIP_ERROR SessionManager::PrepareMessage(const SessionHandle & sessionHandle, PayloadHeader & payloadHeader,
121132
System::PacketBufferHandle && message, EncryptedPacketBufferHandle & preparedMessage)
122133
{

src/transport/SessionManager.h

+5
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate
197197
*/
198198
void Shutdown();
199199

200+
/**
201+
* @brief Notification that a fabric was removed.
202+
*/
203+
void FabricRemoved(FabricIndex fabricIndex);
204+
200205
TransportMgrBase * GetTransportManager() const { return mTransportMgr; }
201206

202207
/**

src/transport/tests/TestGroupMessageCounter.cpp

+23-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void RemovePeerTest(nlTestSuite * inSuite, void * inContext)
134134
FabricIndex fabricIndex = 1;
135135
CHIP_ERROR err = CHIP_NO_ERROR;
136136
chip::Transport::PeerMessageCounter * counter = nullptr;
137-
chip::Transport::GroupPeerTable mGroupPeerMsgCounter;
137+
TestGroupPeerTable mGroupPeerMsgCounter;
138138

139139
// Fill table up (max fabric and mac peer)
140140
for (uint32_t it = 0; it < CHIP_CONFIG_MAX_FABRICS; it++)
@@ -165,6 +165,28 @@ void RemovePeerTest(nlTestSuite * inSuite, void * inContext)
165165
// Try re-adding the previous peer without any error
166166
err = mGroupPeerMsgCounter.FindOrAddPeer(99, 99, true, counter);
167167
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
168+
169+
err = mGroupPeerMsgCounter.FindOrAddPeer(104, 99, true, counter);
170+
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
171+
172+
err = mGroupPeerMsgCounter.FindOrAddPeer(105, 99, true, counter);
173+
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
174+
175+
err = mGroupPeerMsgCounter.FindOrAddPeer(106, 99, true, counter);
176+
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
177+
178+
// Fabric removal test
179+
err = mGroupPeerMsgCounter.FabricRemoved(123);
180+
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_NOT_FOUND);
181+
182+
err = mGroupPeerMsgCounter.FabricRemoved(99);
183+
NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
184+
185+
err = mGroupPeerMsgCounter.FabricRemoved(99);
186+
NL_TEST_ASSERT(inSuite, err == CHIP_ERROR_NOT_FOUND);
187+
188+
// Verify that the Fabric List was compacted.
189+
NL_TEST_ASSERT(inSuite, 106 == mGroupPeerMsgCounter.GetFabricIndexAt(0));
168190
}
169191

170192
void PeerRetrievalTest(nlTestSuite * inSuite, void * inContext)

0 commit comments

Comments
 (0)