40
40
#include < lib/support/CodeUtils.h>
41
41
#include < lib/support/SpanSearchValue.h>
42
42
43
+ #include < memory>
43
44
#include < optional>
44
45
#include < variant>
45
46
@@ -837,6 +838,154 @@ std::optional<DataModel::CommandInfo> CodegenDataModelProvider::GetAcceptedComma
837
838
return CommandEntryFrom (path, commandId).info ;
838
839
}
839
840
841
+ MetadataList<DataModel::AcceptedCommandEntry> CodegenDataModelProvider::AcceptedCommands (const ConcreteClusterPath & path)
842
+ {
843
+ CommandHandlerInterface * interface =
844
+ CommandHandlerInterfaceRegistry::Instance ().GetCommandHandler (path.mEndpointId , path.mClusterId );
845
+ if (interface != nullptr )
846
+ {
847
+ size_t commandCount = 0 ;
848
+
849
+ CHIP_ERROR err = interface->EnumerateAcceptedCommands (
850
+ path,
851
+ [](CommandId id, void * context) -> Loop {
852
+ *reinterpret_cast <size_t *>(context) += 1 ;
853
+ return Loop::Continue;
854
+ },
855
+ reinterpret_cast <void *>(&commandCount));
856
+
857
+ if (err == CHIP_NO_ERROR)
858
+ {
859
+ typedef struct
860
+ {
861
+ ConcreteCommandPath commandPath;
862
+ MetadataList<DataModel::AcceptedCommandEntry> acceptedCommandList;
863
+ } EnumerationData;
864
+
865
+ EnumerationData enumerationData;
866
+ enumerationData.commandPath = ConcreteCommandPath (path.mEndpointId , path.mClusterId , kInvalidCommandId );
867
+
868
+ err = enumerationData.acceptedCommandList .reserve (commandCount);
869
+ if (err != CHIP_NO_ERROR)
870
+ {
871
+ #if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING
872
+ ChipLogError (DataManagement, " Failed to reserve space for %u generated commands: %" CHIP_ERROR_FORMAT,
873
+ (unsigned ) commandCount, err.Format ());
874
+ #endif
875
+ return {};
876
+ }
877
+
878
+ err = interface->EnumerateAcceptedCommands (
879
+ path,
880
+ [](CommandId commandId, void * context) -> Loop {
881
+ auto input = reinterpret_cast <EnumerationData *>(context);
882
+
883
+ input->commandPath .mCommandId = commandId;
884
+
885
+ DataModel::AcceptedCommandEntry entry;
886
+
887
+ entry.commandId = commandId;
888
+ entry.invokePrivilege = RequiredPrivilege::ForInvokeCommand (input->commandPath );
889
+ entry.flags .Set (DataModel::CommandQualityFlags::kTimed ,
890
+ CommandNeedsTimedInvoke (input->commandPath .mClusterId , commandId));
891
+
892
+ entry.flags .Set (DataModel::CommandQualityFlags::kFabricScoped ,
893
+ CommandIsFabricScoped (input->commandPath .mClusterId , commandId));
894
+
895
+ entry.flags .Set (DataModel::CommandQualityFlags::kLargeMessage ,
896
+
897
+ CommandHasLargePayload (input->commandPath .mClusterId , commandId));
898
+
899
+ CHIP_ERROR appendError = input->acceptedCommandList .Append (entry);
900
+ if (appendError != CHIP_NO_ERROR)
901
+ {
902
+ #if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING
903
+ ChipLogError (DataManagement, " Failed to append generated command: %" CHIP_ERROR_FORMAT,
904
+ appendError.Format ());
905
+ #endif
906
+ return Loop::Break;
907
+ }
908
+ return Loop::Continue;
909
+ },
910
+ reinterpret_cast <void *>(&enumerationData));
911
+
912
+ #if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING
913
+ if (err != CHIP_NO_ERROR)
914
+ {
915
+ ChipLogError (DataManagement, " Failed to run generated command appending: %" CHIP_ERROR_FORMAT, err.Format ());
916
+ }
917
+ if (enumerationData.acceptedCommandList .size () != commandCount)
918
+ {
919
+ ChipLogError (DataManagement, " Unexpected (likely short) number of generated commands fetched" );
920
+ }
921
+ #endif
922
+ return std::move (enumerationData.acceptedCommandList );
923
+ }
924
+
925
+ if (err != CHIP_ERROR_NOT_IMPLEMENTED)
926
+ {
927
+ #if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING
928
+ ChipLogError (DataManagement, " Failed to enumerate generated commands: %" CHIP_ERROR_FORMAT, err.Format ());
929
+ #endif
930
+ return {};
931
+ }
932
+ }
933
+
934
+ const EmberAfCluster * cluster = FindServerCluster (path);
935
+ if ((cluster == nullptr ) || (cluster->acceptedCommandList == nullptr ))
936
+ {
937
+ return {};
938
+ }
939
+ const chip::CommandId * endOfList = cluster->acceptedCommandList ;
940
+ while (*endOfList != kInvalidCommandId )
941
+ {
942
+ endOfList++;
943
+ }
944
+ const size_t commandCount = static_cast <size_t >(endOfList - cluster->acceptedCommandList );
945
+
946
+ MetadataList<DataModel::AcceptedCommandEntry> result;
947
+ CHIP_ERROR err = result.reserve (commandCount);
948
+
949
+ if (err != CHIP_NO_ERROR)
950
+ {
951
+ #if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING
952
+ ChipLogError (DataManagement, " Failed to reserve space for %u accepted commands: %" CHIP_ERROR_FORMAT,
953
+ (unsigned ) commandCount, err.Format ());
954
+ #endif
955
+ return {};
956
+ }
957
+
958
+ ConcreteCommandPath commandPath = ConcreteCommandPath (path.mEndpointId , path.mClusterId , kInvalidCommandId );
959
+
960
+ for (const chip::CommandId * p = cluster->acceptedCommandList ; p != endOfList; p++)
961
+ {
962
+ commandPath.mCommandId = *p;
963
+
964
+ DataModel::AcceptedCommandEntry entry;
965
+
966
+ entry.commandId = commandPath.mCommandId ;
967
+ entry.invokePrivilege = RequiredPrivilege::ForInvokeCommand (commandPath);
968
+ entry.flags .Set (DataModel::CommandQualityFlags::kTimed , CommandNeedsTimedInvoke (path.mClusterId , commandPath.mCommandId ));
969
+
970
+ entry.flags .Set (DataModel::CommandQualityFlags::kFabricScoped ,
971
+ CommandIsFabricScoped (path.mClusterId , commandPath.mCommandId ));
972
+
973
+ entry.flags .Set (DataModel::CommandQualityFlags::kLargeMessage ,
974
+ CommandHasLargePayload (path.mClusterId , commandPath.mCommandId ));
975
+
976
+ err = result.Append (entry);
977
+ if (err != CHIP_NO_ERROR)
978
+ {
979
+ #if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING
980
+ ChipLogError (DataManagement, " Failed to append accepted command value: %" CHIP_ERROR_FORMAT, err.Format ());
981
+ #endif
982
+ break ;
983
+ }
984
+ }
985
+
986
+ return result;
987
+ }
988
+
840
989
MetadataList<CommandId> CodegenDataModelProvider::GeneratedCommands (const ConcreteClusterPath & path)
841
990
{
842
991
CommandHandlerInterface * interface =
@@ -856,7 +1005,15 @@ MetadataList<CommandId> CodegenDataModelProvider::GeneratedCommands(const Concre
856
1005
if (err == CHIP_NO_ERROR)
857
1006
{
858
1007
MetadataList<CommandId> result;
859
- result.reserve (commandCount);
1008
+ err = result.reserve (commandCount);
1009
+ if (err != CHIP_NO_ERROR)
1010
+ {
1011
+ #if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING
1012
+ ChipLogError (DataManagement, " Failed to reserve space for %u generated commands: %" CHIP_ERROR_FORMAT,
1013
+ (unsigned ) commandCount, err.Format ());
1014
+ #endif
1015
+ return {};
1016
+ }
860
1017
861
1018
err = interface->EnumerateGeneratedCommands (
862
1019
path,
@@ -906,7 +1063,7 @@ MetadataList<CommandId> CodegenDataModelProvider::GeneratedCommands(const Concre
906
1063
{
907
1064
endOfList++;
908
1065
}
909
- size_t commandCount = static_cast <size_t >(endOfList - cluster->generatedCommandList );
1066
+ const size_t commandCount = static_cast <size_t >(endOfList - cluster->generatedCommandList );
910
1067
return MetadataList<CommandId>::FromConstSpan ({ cluster->generatedCommandList , commandCount });
911
1068
}
912
1069
0 commit comments