Line data Source code
1 : /**
2 : * Copyright (c) 2024 Project CHIP Authors
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 : #include <app/CommandHandlerInterfaceRegistry.h>
17 :
18 : using namespace chip::app;
19 :
20 : namespace chip {
21 : namespace app {
22 :
23 917 : CommandHandlerInterfaceRegistry & CommandHandlerInterfaceRegistry::Instance()
24 : {
25 : static CommandHandlerInterfaceRegistry registry;
26 917 : return registry;
27 : }
28 :
29 281 : void CommandHandlerInterfaceRegistry::UnregisterAllHandlers()
30 : {
31 :
32 281 : CommandHandlerInterface * handlerIter = mCommandHandlerList;
33 :
34 : //
35 : // Walk our list of command handlers and de-register them, before finally
36 : // nulling out the list entirely.
37 : //
38 281 : while (handlerIter)
39 : {
40 0 : CommandHandlerInterface * nextHandler = handlerIter->GetNext();
41 0 : handlerIter->SetNext(nullptr);
42 0 : handlerIter = nextHandler;
43 : }
44 :
45 281 : mCommandHandlerList = nullptr;
46 281 : }
47 :
48 15 : CHIP_ERROR CommandHandlerInterfaceRegistry::RegisterCommandHandler(CommandHandlerInterface * handler)
49 : {
50 15 : VerifyOrReturnError(handler != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
51 :
52 27 : for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext())
53 : {
54 12 : if (cur->Matches(*handler))
55 : {
56 0 : ChipLogError(InteractionModel, "Duplicate command handler registration failed");
57 0 : return CHIP_ERROR_INCORRECT_STATE;
58 : }
59 : }
60 :
61 15 : handler->SetNext(mCommandHandlerList);
62 15 : mCommandHandlerList = handler;
63 :
64 15 : return CHIP_NO_ERROR;
65 : }
66 :
67 24 : void CommandHandlerInterfaceRegistry::UnregisterAllCommandHandlersForEndpoint(EndpointId endpointId)
68 : {
69 24 : CommandHandlerInterface * prev = nullptr;
70 :
71 34 : for (auto * cur = mCommandHandlerList; cur;)
72 : {
73 : // Fetch next node in the list before we remove this one.
74 10 : auto * next = cur->GetNext();
75 :
76 10 : if (cur->MatchesEndpoint(endpointId))
77 : {
78 2 : if (prev == nullptr)
79 : {
80 0 : mCommandHandlerList = cur->GetNext();
81 : }
82 : else
83 : {
84 2 : prev->SetNext(cur->GetNext());
85 : }
86 :
87 2 : cur->SetNext(nullptr);
88 : }
89 : else
90 : {
91 8 : prev = cur;
92 : }
93 :
94 10 : cur = next;
95 : }
96 24 : }
97 :
98 9 : CHIP_ERROR CommandHandlerInterfaceRegistry::UnregisterCommandHandler(CommandHandlerInterface * handler)
99 : {
100 9 : VerifyOrReturnError(handler != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
101 9 : CommandHandlerInterface * prev = nullptr;
102 :
103 14 : for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext())
104 : {
105 13 : if (cur->Matches(*handler))
106 : {
107 8 : if (prev == nullptr)
108 : {
109 7 : mCommandHandlerList = cur->GetNext();
110 : }
111 : else
112 : {
113 1 : prev->SetNext(cur->GetNext());
114 : }
115 :
116 8 : cur->SetNext(nullptr);
117 :
118 8 : return CHIP_NO_ERROR;
119 : }
120 :
121 5 : prev = cur;
122 : }
123 :
124 1 : return CHIP_ERROR_KEY_NOT_FOUND;
125 : }
126 :
127 619 : CommandHandlerInterface * CommandHandlerInterfaceRegistry::GetCommandHandler(EndpointId endpointId, ClusterId clusterId)
128 : {
129 642 : for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext())
130 : {
131 75 : if (cur->Matches(endpointId, clusterId))
132 : {
133 52 : return cur;
134 : }
135 : }
136 :
137 567 : return nullptr;
138 : }
139 :
140 : } // namespace app
141 : } // namespace chip
|