@@ -66,6 +66,10 @@ CHIP_ERROR AddResponseOnError(CommandHandlerInterface::HandlerContext & ctx, Res
66
66
{
67
67
resp.status = to_underlying (Protocols::InteractionModel::Status::NotFound);
68
68
}
69
+ else if (CHIP_ERROR_NO_MEMORY == err)
70
+ {
71
+ resp.status = to_underlying (Protocols::InteractionModel::Status::ResourceExhausted);
72
+ }
69
73
else
70
74
{
71
75
resp.status = to_underlying (StatusIB (err).mStatus );
@@ -168,7 +172,6 @@ CHIP_ERROR UpdateFabricSceneInfo(EndpointId endpoint, FabricIndex fabric, Option
168
172
169
173
// / @brief Gets the SceneInfoStruct array associated to an endpoint
170
174
// / @param endpoint target endpoint
171
- // / @param fabric target fabric
172
175
// / @return Optional with no value not found, Span of SceneInfoStruct
173
176
Span<Structs::SceneInfoStruct::Type> ScenesServer::FabricSceneInfo::GetFabricSceneInfo (EndpointId endpoint)
174
177
{
@@ -675,13 +678,21 @@ void ScenesServer::InvokeCommand(HandlerContext & ctxt)
675
678
// AttributeAccessInterface
676
679
CHIP_ERROR ScenesServer::Read (const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
677
680
{
681
+ uint16_t endpointTableSize = 0 ;
682
+ ReturnErrorOnFailure (StatusIB (Attributes::SceneTableSize::Get (aPath.mEndpointId , &endpointTableSize)).ToChipError ());
683
+
684
+ // Get Scene Table Instance
685
+ SceneTable * sceneTable = scenes::GetSceneTableImpl (aPath.mEndpointId , endpointTableSize);
686
+
678
687
switch (aPath.mAttributeId )
679
688
{
680
689
case Attributes::FabricSceneInfo::Id: {
681
- return aEncoder.EncodeList ([&](const auto & encoder) -> CHIP_ERROR {
690
+ return aEncoder.EncodeList ([&, sceneTable ](const auto & encoder) -> CHIP_ERROR {
682
691
Span<Structs::SceneInfoStruct::Type> fabricSceneInfoSpan = mFabricSceneInfo .GetFabricSceneInfo (aPath.mEndpointId );
683
692
for (auto & info : fabricSceneInfoSpan)
684
693
{
694
+ // Update the SceneInfoStruct's Capacity in case it's capacity was limited by other fabrics
695
+ sceneTable->GetRemainingCapacity (info.fabricIndex , info.remainingCapacity );
685
696
ReturnErrorOnFailure (encoder.Encode (info));
686
697
}
687
698
return CHIP_NO_ERROR;
@@ -918,12 +929,10 @@ void ScenesServer::HandleStoreScene(HandlerContext & ctx, const Commands::StoreS
918
929
CHIP_ERROR err = StoreSceneParse (ctx.mCommandHandler .GetAccessingFabricIndex (), ctx.mRequestPath .mEndpointId , req.groupID ,
919
930
req.sceneID , mGroupProvider );
920
931
921
- if (CHIP_NO_ERROR == err)
922
- {
923
- ReturnOnFailure (UpdateLastConfiguredBy (ctx, response));
924
- }
932
+ ReturnOnFailure (AddResponseOnError (ctx, response, err));
925
933
926
- response.status = to_underlying (StatusIB (err).mStatus );
934
+ ReturnOnFailure (UpdateLastConfiguredBy (ctx, response));
935
+ response.status = to_underlying (Protocols::InteractionModel::Status::Success);
927
936
ctx.mCommandHandler .AddResponse (ctx.mRequestPath , response);
928
937
}
929
938
@@ -1031,6 +1040,13 @@ void ScenesServer::HandleCopyScene(HandlerContext & ctx, const Commands::CopySce
1031
1040
ReturnOnFailure (AddResponseOnError (ctx, response,
1032
1041
sceneTable->GetRemainingCapacity (ctx.mCommandHandler .GetAccessingFabricIndex (), capacity)));
1033
1042
1043
+ if (0 == capacity)
1044
+ {
1045
+ response.status = to_underlying (Protocols::InteractionModel::Status::ResourceExhausted);
1046
+ ctx.mCommandHandler .AddResponse (ctx.mRequestPath , response);
1047
+ return ;
1048
+ }
1049
+
1034
1050
// Checks if we copy a single scene or all of them
1035
1051
if (req.mode .GetField (app::Clusters::ScenesManagement::CopyModeBitmap::kCopyAllScenes ))
1036
1052
{
@@ -1043,13 +1059,6 @@ void ScenesServer::HandleCopyScene(HandlerContext & ctx, const Commands::CopySce
1043
1059
ctx, response,
1044
1060
sceneTable->GetAllSceneIdsInGroup (ctx.mCommandHandler .GetAccessingFabricIndex (), req.groupIdentifierFrom , sceneList)));
1045
1061
1046
- if (0 == capacity)
1047
- {
1048
- response.status = to_underlying (Protocols::InteractionModel::Status::ResourceExhausted);
1049
- ctx.mCommandHandler .AddResponse (ctx.mRequestPath , response);
1050
- return ;
1051
- }
1052
-
1053
1062
for (auto & sceneId : sceneList)
1054
1063
{
1055
1064
SceneTableEntry scene (SceneStorageId (sceneId, req.groupIdentifierFrom ));
@@ -1062,13 +1071,13 @@ void ScenesServer::HandleCopyScene(HandlerContext & ctx, const Commands::CopySce
1062
1071
1063
1072
ReturnOnFailure (AddResponseOnError (
1064
1073
ctx, response, sceneTable->SetSceneTableEntry (ctx.mCommandHandler .GetAccessingFabricIndex (), scene)));
1065
- }
1066
1074
1067
- // Update SceneInfoStruct Attributes
1068
- ReturnOnFailure (
1069
- AddResponseOnError (ctx, response,
1070
- UpdateFabricSceneInfo (ctx.mRequestPath .mEndpointId , ctx.mCommandHandler .GetAccessingFabricIndex (),
1071
- Optional<GroupId>(), Optional<SceneId>(), Optional<bool >())));
1075
+ // Update SceneInfoStruct Attributes after each insert in case we hit max capacity in the middle of the loop
1076
+ ReturnOnFailure (AddResponseOnError (
1077
+ ctx, response,
1078
+ UpdateFabricSceneInfo (ctx.mRequestPath .mEndpointId , ctx.mCommandHandler .GetAccessingFabricIndex (),
1079
+ Optional<GroupId>(), Optional<SceneId>(), Optional<bool >() /* = sceneValid*/ )));
1080
+ }
1072
1081
1073
1082
ReturnOnFailure (UpdateLastConfiguredBy (ctx, response));
1074
1083
0 commit comments