Skip to content

Commit 9934b77

Browse files
committed
Move out common fabric-scoped table-like storage from SceneTableImpl to a templatized class, chip::common::FabricTableImpl, to allow re-use in other clusters (specifically, TlsClientManagementServer)
1 parent 09dd3ac commit 9934b77

File tree

9 files changed

+1362
-919
lines changed

9 files changed

+1362
-919
lines changed

src/app/clusters/scenes-server/BUILD.gn

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ static_library("scenes") {
2727
"SceneTableImpl.h",
2828
]
2929

30-
deps = [ "${chip_root}/src/app" ]
30+
deps = [
31+
"${chip_root}/src/app",
32+
"${chip_root}/src/app/common:fabric-table"
33+
]
3134

3235
cflags = [
3336
"-Wconversion",

src/app/clusters/scenes-server/SceneTable.h

+109-132
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <app-common/zap-generated/cluster-objects.h>
2020
#include <app/clusters/scenes-server/ExtensionFieldSets.h>
21+
#include <app/common/FabricTable.h>
2122
#include <lib/support/CHIPMemString.h>
2223
#include <lib/support/CommonIterator.h>
2324
#include <lib/support/IntrusiveList.h>
@@ -28,14 +29,13 @@ namespace chip {
2829
namespace scenes {
2930

3031
// Storage index for scenes in nvm
31-
typedef uint16_t SceneIndex;
32+
typedef app::common::EntryIndex SceneIndex;
3233

3334
typedef uint32_t TransitionTimeMs;
3435
typedef uint32_t SceneTransitionTime;
3536

36-
inline constexpr GroupId kGlobalGroupSceneId = 0x0000;
37-
inline constexpr SceneIndex kUndefinedSceneIndex = 0xffff;
38-
inline constexpr SceneId kUndefinedSceneId = 0xff;
37+
inline constexpr GroupId kGlobalGroupSceneId = 0x0000;
38+
inline constexpr SceneId kUndefinedSceneId = 0xff;
3939

4040
static constexpr size_t kIteratorsMax = CHIP_CONFIG_MAX_SCENES_CONCURRENT_ITERATORS;
4141
static constexpr size_t kSceneNameMaxLength = CHIP_CONFIG_SCENES_CLUSTER_MAXIMUM_NAME_LENGTH;
@@ -127,148 +127,137 @@ class SceneHandler : public IntrusiveListNodeBase<>
127127
TransitionTimeMs timeMs) = 0;
128128
};
129129

130-
template <class EFStype>
131-
class SceneTable
130+
namespace scene_table_elements {
131+
/// @brief struct used to identify a scene in storage by 3 ids, endpoint, group and scene
132+
struct SceneStorageId
132133
{
133-
public:
134-
/// @brief struct used to identify a scene in storage by 3 ids, endpoint, group and scene
135-
struct SceneStorageId
136-
{
137-
// Identifies group within the scope of the given fabric
138-
GroupId mGroupId = kGlobalGroupSceneId;
139-
SceneId mSceneId = kUndefinedSceneId;
134+
// Identifies group within the scope of the given fabric
135+
GroupId mGroupId = kGlobalGroupSceneId;
136+
SceneId mSceneId = kUndefinedSceneId;
140137

141-
SceneStorageId() = default;
142-
SceneStorageId(SceneId id, GroupId groupId = kGlobalGroupSceneId) : mGroupId(groupId), mSceneId(id) {}
143-
144-
void Clear()
145-
{
146-
mGroupId = kGlobalGroupSceneId;
147-
mSceneId = kUndefinedSceneId;
148-
}
138+
SceneStorageId() = default;
139+
SceneStorageId(SceneId id, GroupId groupId = kGlobalGroupSceneId) : mGroupId(groupId), mSceneId(id) {}
149140

150-
bool IsValid() { return (mSceneId != kUndefinedSceneId); }
141+
void Clear()
142+
{
143+
mGroupId = kGlobalGroupSceneId;
144+
mSceneId = kUndefinedSceneId;
145+
}
151146

152-
bool operator==(const SceneStorageId & other) const { return (mGroupId == other.mGroupId && mSceneId == other.mSceneId); }
153-
};
147+
bool IsValid() { return (mSceneId != kUndefinedSceneId); }
154148

155-
/// @brief struct used to store data held in a scene
156-
/// Members:
157-
/// mName: char buffer holding the name of the scene, only serialized when mNameLenght is greater than 0
158-
/// mNameLength: lentgh of the name if a name was provided at scene creation
159-
/// mSceneTransitionTimeSeconds: Time in seconds it will take a cluster to change to the scene
160-
/// mExtensionFieldSets: class holding the different field sets of each cluster values to store with the scene
161-
/// mTransitionTime100ms: Transition time in tenths of a second, allows for more precise transition when combiened with
162-
/// mSceneTransitionTimeSeconds in enhanced scene commands
163-
struct SceneData
164-
{
165-
char mName[kSceneNameMaxLength] = { 0 };
166-
size_t mNameLength = 0;
167-
SceneTransitionTime mSceneTransitionTimeMs = 0;
168-
EFStype mExtensionFieldSets;
149+
bool operator==(const SceneStorageId & other) const { return (mGroupId == other.mGroupId && mSceneId == other.mSceneId); }
150+
};
169151

170-
SceneData(const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0) : mSceneTransitionTimeMs(time)
171-
{
172-
SetName(sceneName);
173-
}
174-
SceneData(EFStype fields, const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0) :
175-
mSceneTransitionTimeMs(time)
176-
{
177-
SetName(sceneName);
152+
/// @brief struct used to store data held in a scene
153+
/// Members:
154+
/// mName: char buffer holding the name of the scene, only serialized when mNameLenght is greater than 0
155+
/// mNameLength: lentgh of the name if a name was provided at scene creation
156+
/// mSceneTransitionTimeSeconds: Time in seconds it will take a cluster to change to the scene
157+
/// mExtensionFieldSets: class holding the different field sets of each cluster values to store with the scene
158+
/// mTransitionTime100ms: Transition time in tenths of a second, allows for more precise transition when combiened with
159+
/// mSceneTransitionTimeSeconds in enhanced scene commands
160+
template <class EFStype>
161+
struct SceneData
162+
{
163+
char mName[kSceneNameMaxLength] = { 0 };
164+
size_t mNameLength = 0;
165+
SceneTransitionTime mSceneTransitionTimeMs = 0;
166+
EFStype mExtensionFieldSets;
178167

179-
mExtensionFieldSets = fields;
180-
}
181-
SceneData(const SceneData & other) : mSceneTransitionTimeMs(other.mSceneTransitionTimeMs)
182-
{
183-
SetName(CharSpan(other.mName, other.mNameLength));
168+
SceneData(const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0) : mSceneTransitionTimeMs(time)
169+
{
170+
SetName(sceneName);
171+
}
172+
SceneData(EFStype fields, const CharSpan & sceneName = CharSpan(), SceneTransitionTime time = 0) : mSceneTransitionTimeMs(time)
173+
{
174+
SetName(sceneName);
184175

185-
mExtensionFieldSets = other.mExtensionFieldSets;
186-
}
187-
~SceneData(){};
176+
mExtensionFieldSets = fields;
177+
}
178+
SceneData(const SceneData & other) : mSceneTransitionTimeMs(other.mSceneTransitionTimeMs)
179+
{
180+
SetName(CharSpan(other.mName, other.mNameLength));
188181

189-
bool operator==(const SceneData & other) const
190-
{
191-
return ((CharSpan(mName, mNameLength).data_equal(CharSpan(other.mName, other.mNameLength))) &&
192-
(mSceneTransitionTimeMs == other.mSceneTransitionTimeMs) && (mExtensionFieldSets == other.mExtensionFieldSets));
193-
}
182+
mExtensionFieldSets = other.mExtensionFieldSets;
183+
}
184+
~SceneData(){};
194185

195-
void SetName(const CharSpan & sceneName)
196-
{
197-
if (nullptr == sceneName.data())
198-
{
199-
mName[0] = 0;
200-
mNameLength = 0;
201-
}
202-
else
203-
{
204-
size_t maxChars = std::min(sceneName.size(), kSceneNameMaxLength);
205-
memcpy(mName, sceneName.data(), maxChars);
206-
mNameLength = maxChars;
207-
}
208-
}
186+
bool operator==(const SceneData & other) const
187+
{
188+
return ((CharSpan(mName, mNameLength).data_equal(CharSpan(other.mName, other.mNameLength))) &&
189+
(mSceneTransitionTimeMs == other.mSceneTransitionTimeMs) && (mExtensionFieldSets == other.mExtensionFieldSets));
190+
}
209191

210-
void Clear()
192+
void SetName(const CharSpan & sceneName)
193+
{
194+
if (nullptr == sceneName.data())
211195
{
212-
SetName(CharSpan());
213-
mSceneTransitionTimeMs = 0;
214-
mExtensionFieldSets.Clear();
196+
mName[0] = 0;
197+
mNameLength = 0;
215198
}
216-
217-
void operator=(const SceneData & other)
199+
else
218200
{
219-
SetName(CharSpan(other.mName, other.mNameLength));
220-
mExtensionFieldSets = other.mExtensionFieldSets;
221-
mSceneTransitionTimeMs = other.mSceneTransitionTimeMs;
201+
size_t maxChars = std::min(sceneName.size(), kSceneNameMaxLength);
202+
memcpy(mName, sceneName.data(), maxChars);
203+
mNameLength = maxChars;
222204
}
223-
};
205+
}
224206

225-
/// @brief Struct combining both ID and data of a table entry
226-
struct SceneTableEntry
207+
void Clear()
227208
{
228-
// ID
229-
SceneStorageId mStorageId;
230-
231-
// DATA
232-
SceneData mStorageData;
209+
SetName(CharSpan());
210+
mSceneTransitionTimeMs = 0;
211+
mExtensionFieldSets.Clear();
212+
}
233213

234-
SceneTableEntry() = default;
235-
SceneTableEntry(SceneStorageId id) : mStorageId(id) {}
236-
SceneTableEntry(const SceneStorageId id, const SceneData data) : mStorageId(id), mStorageData(data) {}
237-
238-
bool operator==(const SceneTableEntry & other) const
239-
{
240-
return (mStorageId == other.mStorageId && mStorageData == other.mStorageData);
241-
}
214+
void operator=(const SceneData & other)
215+
{
216+
SetName(CharSpan(other.mName, other.mNameLength));
217+
mExtensionFieldSets = other.mExtensionFieldSets;
218+
mSceneTransitionTimeMs = other.mSceneTransitionTimeMs;
219+
}
220+
};
221+
} // namespace scene_table_elements
242222

243-
void operator=(const SceneTableEntry & other)
244-
{
245-
mStorageId = other.mStorageId;
246-
mStorageData = other.mStorageData;
247-
}
248-
};
223+
template <class EFStype>
224+
class SceneTable
225+
: public virtual app::common::FabricTable<scene_table_elements::SceneStorageId, scene_table_elements::SceneData<EFStype>>
226+
{
227+
public:
228+
using Super = app::common::FabricTable<scene_table_elements::SceneStorageId, scene_table_elements::SceneData<EFStype>>;
229+
using SceneTableEntry = typename Super::TableEntry;
230+
using SceneStorageId = scene_table_elements::SceneStorageId;
231+
using SceneData = scene_table_elements::SceneData<EFStype>;
249232

250233
SceneTable(){};
251234

252235
virtual ~SceneTable(){};
253236

254-
// Not copyable
255-
SceneTable(const SceneTable &) = delete;
256-
257-
SceneTable & operator=(const SceneTable &) = delete;
258-
259-
virtual CHIP_ERROR Init(PersistentStorageDelegate * storage) = 0;
260-
virtual void Finish() = 0;
261-
262237
// Global scene count
263-
virtual CHIP_ERROR GetEndpointSceneCount(uint8_t & scene_count) = 0;
264-
virtual CHIP_ERROR GetFabricSceneCount(FabricIndex fabric_index, uint8_t & scene_count) = 0;
238+
inline CHIP_ERROR GetEndpointSceneCount(uint8_t & scene_count) { return this->GetEndpointEntryCount(scene_count); }
239+
inline CHIP_ERROR GetFabricSceneCount(FabricIndex fabric_index, uint8_t & scene_count)
240+
{
241+
return this->GetFabricEntryCount(fabric_index, scene_count);
242+
}
265243

266244
// Data
267-
virtual CHIP_ERROR GetRemainingCapacity(FabricIndex fabric_index, uint8_t & capacity) = 0;
268-
virtual CHIP_ERROR SetSceneTableEntry(FabricIndex fabric_index, const SceneTableEntry & entry) = 0;
269-
virtual CHIP_ERROR GetSceneTableEntry(FabricIndex fabric_index, SceneStorageId scene_id, SceneTableEntry & entry) = 0;
270-
virtual CHIP_ERROR RemoveSceneTableEntry(FabricIndex fabric_index, SceneStorageId scene_id) = 0;
271-
virtual CHIP_ERROR RemoveSceneTableEntryAtPosition(EndpointId endpoint, FabricIndex fabric_index, SceneIndex scene_idx) = 0;
245+
inline CHIP_ERROR SetSceneTableEntry(FabricIndex fabric_index, const SceneTableEntry & entry)
246+
{
247+
return this->SetTableEntry(fabric_index, entry);
248+
}
249+
inline CHIP_ERROR GetSceneTableEntry(FabricIndex fabric_index, SceneStorageId scene_id, SceneTableEntry & entry)
250+
{
251+
return this->GetTableEntry(fabric_index, scene_id, entry);
252+
}
253+
inline CHIP_ERROR RemoveSceneTableEntry(FabricIndex fabric_index, SceneStorageId scene_id)
254+
{
255+
return this->RemoveTableEntry(fabric_index, scene_id);
256+
}
257+
inline CHIP_ERROR RemoveSceneTableEntryAtPosition(EndpointId endpoint, FabricIndex fabric_index, SceneIndex scene_idx)
258+
{
259+
return this->RemoveTableEntryAtPosition(endpoint, fabric_index, scene_idx);
260+
}
272261

273262
// Groups
274263
virtual CHIP_ERROR GetAllSceneIdsInGroup(FabricIndex fabric_index, GroupId group_id, Span<SceneId> & scene_list) = 0;
@@ -283,22 +272,10 @@ class SceneTable
283272
virtual CHIP_ERROR SceneSaveEFS(SceneTableEntry & scene) = 0;
284273
virtual CHIP_ERROR SceneApplyEFS(const SceneTableEntry & scene) = 0;
285274

286-
// Fabrics
287-
288-
/**
289-
* @brief Removes all scenes associated with a fabric index and the stored FabricSceneData that maps them
290-
* @param fabric_index Fabric index to remove
291-
* @return CHIP_ERROR, CHIP_NO_ERROR if successful or if the Fabric was not found, specific CHIP_ERROR otherwise
292-
* @note This function is meant to be used after a fabric is removed from the device, the implementation MUST ensure that it
293-
* won't interact with the actual fabric table as it will be removed beforehand.
294-
*/
295-
virtual CHIP_ERROR RemoveFabric(FabricIndex fabric_index) = 0;
296-
virtual CHIP_ERROR RemoveEndpoint() = 0;
297-
298275
// Iterators
299276
using SceneEntryIterator = CommonIterator<SceneTableEntry>;
300277

301-
virtual SceneEntryIterator * IterateSceneEntries(FabricIndex fabric_index) = 0;
278+
SceneEntryIterator * IterateSceneEntries(FabricIndex fabric_index) { return this->IterateTableEntries(fabric_index); }
302279

303280
// Handlers
304281
virtual bool HandlerListEmpty() { return mHandlerList.Empty(); }

0 commit comments

Comments
 (0)