Skip to content

Commit c53ccdd

Browse files
Fix UnregisterAllCommandHandlersForEndpoint to work correctly.
Fixes #34953
1 parent 96ee61e commit c53ccdd

File tree

3 files changed

+110
-1
lines changed

3 files changed

+110
-1
lines changed

src/app/CommandHandlerInterfaceRegistry.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ void CommandHandlerInterfaceRegistry::UnregisterAllCommandHandlersForEndpoint(En
6868
{
6969
CommandHandlerInterface * prev = nullptr;
7070

71-
for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext())
71+
for (auto * cur = mCommandHandlerList; cur;)
7272
{
73+
// Fetch next node in the list before we remove this one.
74+
auto * next = cur->GetNext();
75+
7376
if (cur->MatchesEndpoint(endpointId))
7477
{
7578
if (prev == nullptr)
@@ -87,6 +90,8 @@ void CommandHandlerInterfaceRegistry::UnregisterAllCommandHandlersForEndpoint(En
8790
{
8891
prev = cur;
8992
}
93+
94+
cur = next;
9095
}
9196
}
9297

src/app/tests/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ chip_test_suite("tests") {
194194
"TestBasicCommandPathRegistry.cpp",
195195
"TestBindingTable.cpp",
196196
"TestBuilderParser.cpp",
197+
"TestCommandHandlerInterfaceRegistry.cpp",
197198
"TestCommandInteraction.cpp",
198199
"TestCommandPathParams.cpp",
199200
"TestConcreteAttributePath.cpp",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
*
3+
* Copyright (c) 2021 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include <lib/core/StringBuilderAdapters.h>
20+
#include <pw_unit_test/framework.h>
21+
22+
#include <app/CommandHandlerInterfaceRegistry.h>
23+
24+
#include <type_traits>
25+
26+
namespace chip {
27+
namespace app {
28+
29+
namespace {
30+
31+
class TestCommandHandlerInterface : public CommandHandlerInterface
32+
{
33+
public:
34+
TestCommandHandlerInterface(Optional<EndpointId> endpointId, ClusterId clusterId) :
35+
CommandHandlerInterface(endpointId, clusterId)
36+
{}
37+
38+
// Just need this to compile
39+
void InvokeCommand(HandlerContext & handlerContext) override {}
40+
};
41+
42+
} // anonymous namespace
43+
44+
TEST(TestCommandHandlerInterfaceRegistry, TestRegisterUnregister)
45+
{
46+
TestCommandHandlerInterface a(Optional<EndpointId>(1), 1);
47+
TestCommandHandlerInterface b(Optional<EndpointId>(1), 2);
48+
TestCommandHandlerInterface c(Optional<EndpointId>(2), 1);
49+
TestCommandHandlerInterface d(NullOptional, 3);
50+
51+
CommandHandlerInterfaceRegistry registry;
52+
EXPECT_EQ(registry.RegisterCommandHandler(&a), CHIP_NO_ERROR);
53+
EXPECT_EQ(registry.RegisterCommandHandler(&b), CHIP_NO_ERROR);
54+
EXPECT_EQ(registry.RegisterCommandHandler(&c), CHIP_NO_ERROR);
55+
EXPECT_EQ(registry.RegisterCommandHandler(&d), CHIP_NO_ERROR);
56+
57+
EXPECT_EQ(registry.GetCommandHandler(1, 1), &a);
58+
EXPECT_EQ(registry.GetCommandHandler(1, 2), &b);
59+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
60+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
61+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
62+
63+
EXPECT_EQ(registry.UnregisterCommandHandler(&b), CHIP_NO_ERROR);
64+
65+
EXPECT_EQ(registry.GetCommandHandler(1, 1), &a);
66+
EXPECT_EQ(registry.GetCommandHandler(1, 2), nullptr);
67+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
68+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
69+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
70+
71+
EXPECT_EQ(registry.UnregisterCommandHandler(&b), CHIP_ERROR_KEY_NOT_FOUND);
72+
}
73+
74+
TEST(TestCommandHandlerInterfaceRegistry, TestUnregisterAll)
75+
{
76+
TestCommandHandlerInterface a(Optional<EndpointId>(1), 1);
77+
TestCommandHandlerInterface b(Optional<EndpointId>(1), 2);
78+
TestCommandHandlerInterface c(Optional<EndpointId>(2), 1);
79+
TestCommandHandlerInterface d(NullOptional, 3);
80+
81+
CommandHandlerInterfaceRegistry registry;
82+
EXPECT_EQ(registry.RegisterCommandHandler(&a), CHIP_NO_ERROR);
83+
EXPECT_EQ(registry.RegisterCommandHandler(&b), CHIP_NO_ERROR);
84+
EXPECT_EQ(registry.RegisterCommandHandler(&c), CHIP_NO_ERROR);
85+
EXPECT_EQ(registry.RegisterCommandHandler(&d), CHIP_NO_ERROR);
86+
87+
EXPECT_EQ(registry.GetCommandHandler(1, 1), &a);
88+
EXPECT_EQ(registry.GetCommandHandler(1, 2), &b);
89+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
90+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
91+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
92+
93+
registry.UnregisterAllCommandHandlersForEndpoint(1);
94+
95+
EXPECT_EQ(registry.GetCommandHandler(1, 1), nullptr);
96+
EXPECT_EQ(registry.GetCommandHandler(1, 2), nullptr);
97+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
98+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
99+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
100+
}
101+
102+
} // namespace app
103+
} // namespace chip

0 commit comments

Comments
 (0)