Skip to content

Commit 4428cc9

Browse files
Groupcast: Testing events. (#43621)
* Groupcast: Testing events. * Code review.
1 parent ef634e9 commit 4428cc9

File tree

10 files changed

+337
-7
lines changed

10 files changed

+337
-7
lines changed

src/app/CommandHandlerImpl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <platform/LockTracker.h>
3535
#include <protocols/interaction_model/StatusCode.h>
3636
#include <protocols/secure_channel/Constants.h>
37+
#include <transport/raw/GroupcastTesting.h>
3738

3839
namespace chip {
3940
namespace app {
@@ -525,6 +526,15 @@ Status CommandHandlerImpl::ProcessGroupCommandDataIB(CommandDataIB::Parser & aCo
525526
mapping.endpoint_id, ChipLogValueMEI(clusterId), ChipLogValueMEI(commandId));
526527

527528
const ConcreteCommandPath concretePath(mapping.endpoint_id, clusterId, commandId);
529+
// Groupcast Testing
530+
auto & testing = Groupcast::GetTesting();
531+
if (testing.IsEnabled() && testing.IsFabricUnderTest(fabric))
532+
{
533+
testing.SetGroupID(groupId);
534+
testing.SetEndpointID(mapping.endpoint_id);
535+
testing.SetClusterID(clusterId);
536+
testing.SetElementID(static_cast<uint32_t>(commandId));
537+
}
528538

529539
{
530540
Access::SubjectDescriptor subjectDescriptor = GetSubjectDescriptor();

src/app/InteractionModelEngine.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include <lib/support/FibonacciUtils.h>
5252
#include <lib/support/ReadOnlyBuffer.h>
5353
#include <protocols/interaction_model/StatusCode.h>
54+
#include <transport/raw/GroupcastTesting.h>
5455

5556
#include <cinttypes>
5657

@@ -1097,6 +1098,27 @@ CHIP_ERROR InteractionModelEngine::OnMessageReceived(Messaging::ExchangeContext
10971098
status = Status::InvalidAction;
10981099
}
10991100

1101+
// Groupcast Testing
1102+
if (apExchangeContext->IsGroupExchangeContext())
1103+
{
1104+
auto & testing = Groupcast::GetTesting();
1105+
if (testing.IsEnabled() && testing.IsFabricUnderTest(apExchangeContext->GetSessionHandle()->GetFabricIndex()))
1106+
{
1107+
Clusters::Groupcast::Events::GroupcastTesting::Type event;
1108+
if ((testing.GetTestResultEnum() == Groupcast::Testing::Result::kSuccess) && (status != Status::Success))
1109+
{
1110+
testing.SetTestResult(Groupcast::Testing::Result::kGeneralError);
1111+
}
1112+
// Convert to event type
1113+
testing.ToEventType(event);
1114+
testing.Clear();
1115+
// Generate event
1116+
DataModel::EventsGenerator & eventGenerator = EventManagement::GetInstance();
1117+
eventGenerator.GenerateEvent(event, kRootEndpointId);
1118+
eventGenerator.ScheduleUrgentEventDeliverySync();
1119+
}
1120+
}
1121+
11001122
if (status != Status::Success && !apExchangeContext->IsGroupExchangeContext())
11011123
{
11021124
return StatusResponse::Send(status, apExchangeContext, false /*aExpectResponse*/);
@@ -1817,6 +1839,16 @@ Protocols::InteractionModel::Status InteractionModelEngine::ValidateCommandCanBe
18171839
Access::Privilege privilegeToCheck = commandExists ? acceptedCommandEntry.GetInvokePrivilege() : Access::Privilege::kOperate;
18181840

18191841
Status accessStatus = CheckCommandAccess(request, privilegeToCheck);
1842+
// Groupcast Testing
1843+
auto & testing = Groupcast::GetTesting();
1844+
if (testing.IsEnabled() && testing.IsFabricUnderTest(request.GetAccessingFabricIndex()))
1845+
{
1846+
testing.SetAccessAllowed(Status::Success == accessStatus);
1847+
if (!testing.GetAccessAllowed().ValueOr(false))
1848+
{
1849+
testing.SetTestResult(Groupcast::Testing::Result::kFailedAuth);
1850+
}
1851+
}
18201852
VerifyOrReturnValue(accessStatus == Status::Success, accessStatus);
18211853

18221854
if (!commandExists)

src/app/WriteHandler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <lib/support/logging/TextOnlyLogging.h>
4141
#include <messaging/ExchangeContext.h>
4242
#include <protocols/interaction_model/StatusCode.h>
43+
#include <transport/raw/GroupcastTesting.h>
4344

4445
#include <optional>
4546

@@ -503,6 +504,15 @@ CHIP_ERROR WriteHandler::ProcessGroupAttributeDataIBs(TLV::TLVReader & aAttribut
503504
}
504505

505506
dataAttributePath.mEndpointId = mapping.endpoint_id;
507+
// Groupcast Testing
508+
auto & testing = Groupcast::GetTesting();
509+
if (testing.IsEnabled() && testing.IsFabricUnderTest(fabric))
510+
{
511+
testing.SetGroupID(groupId);
512+
testing.SetEndpointID(dataAttributePath.mEndpointId);
513+
testing.SetClusterID(dataAttributePath.mClusterId);
514+
testing.SetElementID(static_cast<uint32_t>(dataAttributePath.mAttributeId));
515+
}
506516

507517
// Try to get the metadata from for the attribute from one of the expanded endpoints (it doesn't really matter which
508518
// endpoint we pick, as long as it's valid) and update the path info according to it and recheck if we need to report

src/app/clusters/groupcast/GroupcastCluster.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
#include <credentials/GroupDataProvider.h>
99
#include <lib/core/CHIPError.h>
1010
#include <lib/support/CodeUtils.h>
11+
#include <transport/raw/GroupcastTesting.h>
1112

1213
using chip::Protocols::InteractionModel::Status;
1314

1415
using namespace chip::Credentials;
15-
using GroupDataProvider = GroupDataProvider;
1616
using GroupInfo = GroupDataProvider::GroupInfo;
1717
using GroupEndpoint = GroupDataProvider::GroupEndpoint;
1818
using GroupInfoIterator = GroupDataProvider::GroupInfoIterator;
@@ -89,7 +89,7 @@ DataModel::ActionReturnStatus GroupcastCluster::ReadAttribute(const DataModel::R
8989
case Groupcast::Attributes::UsedMcastAddrCount::Id:
9090
return ReadUsedMcastAddrCount(request.path.mEndpointId, encoder);
9191
case Groupcast::Attributes::FabricUnderTest::Id:
92-
return encoder.Encode(mFabricUnderTest);
92+
return encoder.Encode(chip::Groupcast::GetTesting().GetFabricIndex());
9393
}
9494
return Protocols::InteractionModel::Status::UnsupportedAttribute;
9595
}
@@ -174,7 +174,8 @@ CHIP_ERROR GroupcastCluster::GeneratedCommands(const ConcreteClusterPath & path,
174174

175175
Status GroupcastCluster::GroupcastTesting(FabricIndex fabricIndex, Groupcast::Commands::GroupcastTesting::DecodableType data)
176176
{
177-
VerifyOrReturnError(mFabricUnderTest == kUndefinedFabricIndex || mFabricUnderTest == fabricIndex, Status::ConstraintError);
177+
FabricIndex fabricUnderTest = chip::Groupcast::GetTesting().GetFabricIndex();
178+
VerifyOrReturnError(fabricUnderTest == kUndefinedFabricIndex || fabricUnderTest == fabricIndex, Status::ConstraintError);
178179

179180
if (data.testOperation == Groupcast::GroupcastTestingEnum::kDisableTesting)
180181
{
@@ -205,7 +206,14 @@ Status GroupcastCluster::GroupcastTesting(FabricIndex fabricIndex, Groupcast::Co
205206

206207
void GroupcastCluster::SetFabricUnderTest(FabricIndex fabricUnderTest)
207208
{
208-
SetAttributeValue(mFabricUnderTest, fabricUnderTest, Groupcast::Attributes::FabricUnderTest::Id);
209+
auto & testing = chip::Groupcast::GetTesting();
210+
if (fabricUnderTest != testing.GetFabricIndex())
211+
{
212+
testing.Clear();
213+
testing.SetFabricIndex(fabricUnderTest);
214+
NotifyAttributeChanged(Groupcast::Attributes::FabricUnderTest::Id);
215+
}
216+
testing.SetEnabled(fabricUnderTest != kUndefinedFabricIndex);
209217
}
210218

211219
// MembershipChangedTimer implementation

src/app/clusters/groupcast/GroupcastCluster.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class GroupcastCluster : public DefaultServerCluster, public Credentials::GroupD
7070
Protocols::InteractionModel::Status GroupcastTesting(FabricIndex fabricIndex,
7171
Groupcast::Commands::GroupcastTesting::DecodableType data);
7272

73-
inline FabricIndex GetFabricUnderTest() const { return mFabricUnderTest; }
7473
const BitFlags<Groupcast::Feature> & Features() const { return mFeatures; }
7574

7675
// Methods moved from GroupcastLogic
@@ -129,7 +128,6 @@ class GroupcastCluster : public DefaultServerCluster, public Credentials::GroupD
129128
bool mIanaAddressUsed = false;
130129

131130
Groupcast::GroupcastTestingEnum mTestingState = Groupcast::GroupcastTestingEnum::kDisableTesting;
132-
FabricIndex mFabricUnderTest = kUndefinedFabricIndex;
133131
class MembershipChangedTimer : public TimerContext
134132
{
135133
public:

src/transport/SessionManager.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <transport/SecureMessageCodec.h>
4949
#include <transport/TracingStructs.h>
5050
#include <transport/TransportMgr.h>
51+
#include <transport/raw/GroupcastTesting.h>
5152

5253
namespace chip {
5354

@@ -1166,7 +1167,16 @@ void SessionManager::SecureGroupMessageDispatch(const PacketHeader & partialPack
11661167
#endif // CHIP_CONFIG_PRIVACY_ACCEPT_NONSPEC_SVE2
11671168
}
11681169
iter.Release();
1169-
1170+
// Groupcast Testing
1171+
auto & testing = chip::Groupcast::GetTesting();
1172+
if (testing.IsEnabled() && testing.IsFabricUnderTest(groupContext.fabric_index))
1173+
{
1174+
testing.SetGroupID(packetHeaderCopy.GetDestinationGroupId().Value());
1175+
if (!decrypted)
1176+
{
1177+
testing.SetTestResult(chip::Groupcast::Testing::Result::kNoAvailableKey);
1178+
}
1179+
}
11701180
if (!decrypted)
11711181
{
11721182
ChipLogError(Inet, "Failed to decrypt group message. Discarding everything");

src/transport/raw/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ static_library("raw") {
2626

2727
sources = [
2828
"Base.h",
29+
"GroupcastTesting.cpp",
30+
"GroupcastTesting.h",
2931
"MessageHeader.cpp",
3032
"MessageHeader.h",
3133
"PeerAddress.cpp",
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2026 Project CHIP Authors
3+
* All rights reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "GroupcastTesting.h"
19+
20+
namespace chip {
21+
namespace Groupcast {
22+
23+
Testing & GetTesting()
24+
{
25+
static Testing sInstance;
26+
return sInstance;
27+
}
28+
29+
} // namespace Groupcast
30+
} // namespace chip

0 commit comments

Comments
 (0)