Skip to content

Commit 0b8237f

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

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-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,102 @@
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) : CommandHandlerInterface(endpointId, clusterId)
35+
{}
36+
37+
// Just need this to compile
38+
void InvokeCommand(HandlerContext & handlerContext) override {}
39+
};
40+
41+
} // anonymous namespace
42+
43+
TEST(TestCommandHandlerInterfaceRegistry, TestRegisterUnregister)
44+
{
45+
TestCommandHandlerInterface a(Optional<EndpointId>(1), 1);
46+
TestCommandHandlerInterface b(Optional<EndpointId>(1), 2);
47+
TestCommandHandlerInterface c(Optional<EndpointId>(2), 1);
48+
TestCommandHandlerInterface d(NullOptional, 3);
49+
50+
CommandHandlerInterfaceRegistry registry;
51+
EXPECT_EQ(registry.RegisterCommandHandler(&a), CHIP_NO_ERROR);
52+
EXPECT_EQ(registry.RegisterCommandHandler(&b), CHIP_NO_ERROR);
53+
EXPECT_EQ(registry.RegisterCommandHandler(&c), CHIP_NO_ERROR);
54+
EXPECT_EQ(registry.RegisterCommandHandler(&d), CHIP_NO_ERROR);
55+
56+
EXPECT_EQ(registry.GetCommandHandler(1, 1), &a);
57+
EXPECT_EQ(registry.GetCommandHandler(1, 2), &b);
58+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
59+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
60+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
61+
62+
EXPECT_EQ(registry.UnregisterCommandHandler(&b), CHIP_NO_ERROR);
63+
64+
EXPECT_EQ(registry.GetCommandHandler(1, 1), &a);
65+
EXPECT_EQ(registry.GetCommandHandler(1, 2), nullptr);
66+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
67+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
68+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
69+
70+
EXPECT_EQ(registry.UnregisterCommandHandler(&b), CHIP_ERROR_KEY_NOT_FOUND);
71+
}
72+
73+
TEST(TestCommandHandlerInterfaceRegistry, TestUnregisterAll)
74+
{
75+
TestCommandHandlerInterface a(Optional<EndpointId>(1), 1);
76+
TestCommandHandlerInterface b(Optional<EndpointId>(1), 2);
77+
TestCommandHandlerInterface c(Optional<EndpointId>(2), 1);
78+
TestCommandHandlerInterface d(NullOptional, 3);
79+
80+
CommandHandlerInterfaceRegistry registry;
81+
EXPECT_EQ(registry.RegisterCommandHandler(&a), CHIP_NO_ERROR);
82+
EXPECT_EQ(registry.RegisterCommandHandler(&b), CHIP_NO_ERROR);
83+
EXPECT_EQ(registry.RegisterCommandHandler(&c), CHIP_NO_ERROR);
84+
EXPECT_EQ(registry.RegisterCommandHandler(&d), CHIP_NO_ERROR);
85+
86+
EXPECT_EQ(registry.GetCommandHandler(1, 1), &a);
87+
EXPECT_EQ(registry.GetCommandHandler(1, 2), &b);
88+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
89+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
90+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
91+
92+
registry.UnregisterAllCommandHandlersForEndpoint(1);
93+
94+
EXPECT_EQ(registry.GetCommandHandler(1, 1), nullptr);
95+
EXPECT_EQ(registry.GetCommandHandler(1, 2), nullptr);
96+
EXPECT_EQ(registry.GetCommandHandler(2, 1), &c);
97+
EXPECT_EQ(registry.GetCommandHandler(1, 3), &d);
98+
EXPECT_EQ(registry.GetCommandHandler(5, 3), &d);
99+
}
100+
101+
} // namespace app
102+
} // namespace chip

0 commit comments

Comments
 (0)