Skip to content

Commit

Permalink
Applied suggestions in review and created FabricSceneIndo yaml test, …
Browse files Browse the repository at this point in the history
…still needs Multi fabric testing
  • Loading branch information
lpbeliveau-silabs committed Nov 6, 2023
1 parent a222bb1 commit 06c90d8
Show file tree
Hide file tree
Showing 7 changed files with 629 additions and 34 deletions.
52 changes: 28 additions & 24 deletions src/app/clusters/scenes-server/scenes-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,18 @@ CHIP_ERROR UpdateLastConfiguredBy(HandlerContext & ctx, ResponseType resp)
/// @brief Gets the SceneInfoStruct array associated to an endpoint
/// @param endpoint target endpoint
/// @param fabric target fabric
/// @return Nullptr if not found, pointer to the SceneInfoStruct array otherwise
Structs::SceneInfoStruct::Type * ScenesServer::FabricSceneInfo::GetFabricSceneInfo(EndpointId endpoint)
/// @return Optional with no value not found, Span of SceneInfoStruct
Span<Structs::SceneInfoStruct::Type> ScenesServer::FabricSceneInfo::GetFabricSceneInfo(EndpointId endpoint)
{
size_t endpointIndex = 0;
VerifyOrReturnValue(CHIP_NO_ERROR == FindFabricSceneInfoIndex(endpoint, endpointIndex), nullptr);
return mSceneInfoStructs[endpointIndex];
Span<Structs::SceneInfoStruct::Type> FabricSceneInfoSpan;
CHIP_ERROR status = FindFabricSceneInfoIndex(endpoint, endpointIndex);
if (CHIP_NO_ERROR == status)
{
FabricSceneInfoSpan =
Span<Structs::SceneInfoStruct::Type>(&mSceneInfoStructs[endpointIndex][0], mSceneInfoStructsCount[endpointIndex]);
}
return FabricSceneInfoSpan;
}

/// @brief Gets the SceneInfoStruct for a specific fabric for a specific endpoint
Expand Down Expand Up @@ -210,7 +216,8 @@ CHIP_ERROR ScenesServer::FabricSceneInfo::SetSceneInfoStruct(EndpointId endpoint
uint8_t sceneInfoStructIndex = 0;
if (CHIP_ERROR_NOT_FOUND == FindSceneInfoStructIndex(fabric, endpointIndex, sceneInfoStructIndex))
{
VerifyOrReturnError(mSceneInfoStructsCount[endpointIndex] < kScenesServerMaxFabricCount, CHIP_ERROR_NO_MEMORY);
VerifyOrReturnError(mSceneInfoStructsCount[endpointIndex] < ArraySize(mSceneInfoStructs[endpointIndex]),
CHIP_ERROR_NO_MEMORY);
sceneInfoStructIndex = mSceneInfoStructsCount[endpointIndex];

// Increment number of populated ScenesInfoStructs
Expand All @@ -232,19 +239,21 @@ void ScenesServer::FabricSceneInfo::ClearSceneInfoStruct(EndpointId endpoint, Fa
ReturnOnFailure(FindSceneInfoStructIndex(fabric, endpointIndex, sceneInfoStructIndex));

uint8_t nextIndex = static_cast<uint8_t>(sceneInfoStructIndex + 1);
uint8_t moveNum = static_cast<uint8_t>(kScenesServerMaxFabricCount - nextIndex);
uint8_t moveNum = static_cast<uint8_t>(ArraySize(mSceneInfoStructs[endpointIndex]) - nextIndex);
// Compress the endpoint's SceneInfoStruct array
if (moveNum)
{
memmove(&mSceneInfoStructs[endpointIndex][sceneInfoStructIndex], &mSceneInfoStructs[endpointIndex][nextIndex],
sizeof(Structs::SceneInfoStruct::Type) * moveNum);
for (size_t i = 0; i < moveNum; ++i)
{
mSceneInfoStructs[endpointIndex][sceneInfoStructIndex + i] = mSceneInfoStructs[endpointIndex][nextIndex + i];
}
}

// Decrement the SceneInfoStruct count
mSceneInfoStructsCount[endpointIndex]--;

// Clear the last populated SceneInfoStruct
mSceneInfoStructs[endpointIndex][mSceneInfoStructsCount[endpointIndex]].fabricIndex = 0;
mSceneInfoStructs[endpointIndex][mSceneInfoStructsCount[endpointIndex]].fabricIndex = kUndefinedFabricIndex;
mSceneInfoStructs[endpointIndex][mSceneInfoStructsCount[endpointIndex]].sceneCount = 0;
mSceneInfoStructs[endpointIndex][mSceneInfoStructsCount[endpointIndex]].currentScene = 0;
mSceneInfoStructs[endpointIndex][mSceneInfoStructsCount[endpointIndex]].currentGroup = 0;
Expand All @@ -262,7 +271,7 @@ CHIP_ERROR ScenesServer::FabricSceneInfo::FindFabricSceneInfoIndex(EndpointId en

uint16_t index = emberAfGetClusterServerEndpointIndex(endpoint, Scenes::Id, EMBER_AF_SCENES_CLUSTER_SERVER_ENDPOINT_COUNT);

if (index < kScenesServerMaxEndpointCount)
if (index < ArraySize(mSceneInfoStructs))
{
endpointIndex = index;
return CHIP_NO_ERROR;
Expand All @@ -274,11 +283,11 @@ CHIP_ERROR ScenesServer::FabricSceneInfo::FindFabricSceneInfoIndex(EndpointId en
/// @param[in] fabric target fabric index
/// @param[in] endpointIndex index of the corresponding FabricSceneInfo for an endpoint, corresponds to a row in the
/// mSceneInfoStructs array
/// @param[out] index index of the corresponding SceneInfoStruct if found, mFabricSceneInfo[endpoint] number of fabrics otherwise
/// @param[out] index index of the corresponding SceneInfoStruct if found, mFabricSceneInfo[endpoint] out of bounds index otherwise
/// @return CHIP_NO_ERROR or CHIP_ERROR_NOT_FOUND, CHIP_ERROR_INVALID_ARGUMENT if invalid fabric or endpoint
CHIP_ERROR ScenesServer::FabricSceneInfo::FindSceneInfoStructIndex(FabricIndex fabric, size_t endpointIndex, uint8_t & index)
{
VerifyOrReturnError(endpointIndex < kScenesServerMaxEndpointCount, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(endpointIndex < ArraySize(mSceneInfoStructs), CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(kUndefinedFabricIndex != fabric, CHIP_ERROR_INVALID_ARGUMENT);

index = 0;
Expand Down Expand Up @@ -353,9 +362,7 @@ CHIP_ERROR ScenesServer::Init()
ChipLogDetail(Zcl, "ERR: setting LastConfiguredBy on Endpoint %hu Status: %x", endpoint, status);
}

// Get Scene Table for a specific endpoint
sceneTable = scenes::GetSceneTableImpl(endpoint);
// Initialize the FabricSceneInfo list from data in Flash
// Initialize the FabricSceneInfo list by recovering the SceneCount and Remaining Capacity form the ScenTable
for (auto & info : chip::Server::GetInstance().GetFabricTable())
{
auto fabric = info.GetFabricIndex();
Expand Down Expand Up @@ -734,14 +741,10 @@ CHIP_ERROR ScenesServer::Read(const ConcreteReadAttributePath & aPath, Attribute
{
case Attributes::FabricSceneInfo::Id: {
return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR {
for (auto & info : Server::GetInstance().GetFabricTable())
Span<Structs::SceneInfoStruct::Type> FabricSceneInfoSpan = mFabricSceneInfo.GetFabricSceneInfo(aPath.mEndpointId);
for (auto & info : FabricSceneInfoSpan)
{
auto fabric = info.GetFabricIndex();
Structs::SceneInfoStruct::Type * SceneInfo = GetSceneInfoStruct(aPath.mEndpointId, fabric);
if (nullptr != SceneInfo)
{
ReturnErrorOnFailure(encoder.Encode(*SceneInfo));
}
ReturnErrorOnFailure(encoder.Encode(info));
}
return CHIP_NO_ERROR;
});
Expand Down Expand Up @@ -942,10 +945,11 @@ void ScenesServer::HandleRemoveAllScenes(HandlerContext & ctx, const Commands::R
// Update Attributes
Structs::SceneInfoStruct::Type * sceneInfo =
GetSceneInfoStruct(ctx.mRequestPath.mEndpointId, ctx.mCommandHandler.GetAccessingFabricIndex());

Optional<bool> sceneValid;
if (nullptr != sceneInfo)
if (nullptr != sceneInfo && req.groupID == sceneInfo->currentGroup)
{
sceneValid = (req.groupID == sceneInfo->currentGroup) ? Optional<bool>(false) : Optional<bool>();
sceneValid.Emplace(false);
}

ReturnOnFailure(
Expand Down
2 changes: 1 addition & 1 deletion src/app/clusters/scenes-server/scenes-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ScenesServer : public CommandHandlerInterface, public AttributeAccessInter
class FabricSceneInfo
{
public:
Structs::SceneInfoStruct::Type * GetFabricSceneInfo(EndpointId endpoint);
Span<Structs::SceneInfoStruct::Type> GetFabricSceneInfo(EndpointId endpoint);
Structs::SceneInfoStruct::Type * GetSceneInfoStruct(EndpointId endpoint, FabricIndex fabric);
CHIP_ERROR SetSceneInfoStruct(EndpointId endpoint, FabricIndex fabric, Structs::SceneInfoStruct::Type & sceneInfoStruct);
void ClearSceneInfoStruct(EndpointId endpoint, FabricIndex fabric);
Expand Down
Loading

0 comments on commit 06c90d8

Please sign in to comment.