Skip to content

Commit fa29225

Browse files
TBRM: Add missing PendingDatasetTimestamp attribute and CASE session check (#34768)
* TBRM: Add missing PendingDatasetTimestamp attribute and CASE session check * review change * zap regenerate and update the Test_TC_TBRM_2_1.yaml * Restyled by clang-format * Read function error map to IM-space error * Add attribute report for PendingDatasetTimestamp * review changes --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent e0a765b commit fa29225

File tree

33 files changed

+564
-86
lines changed

33 files changed

+564
-86
lines changed

examples/network-manager-app/network-manager-common/network-manager-app.matter

+2
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,7 @@ provisional cluster ThreadBorderRouterManagement = 1106 {
15181518
provisional readonly attribute int16u threadVersion = 2;
15191519
provisional readonly attribute boolean interfaceEnabled = 3;
15201520
provisional readonly attribute nullable int64u activeDatasetTimestamp = 4;
1521+
provisional readonly attribute nullable int64u pendingDatasetTimestamp = 5;
15211522
readonly attribute command_id generatedCommandList[] = 65528;
15221523
readonly attribute command_id acceptedCommandList[] = 65529;
15231524
readonly attribute event_id eventList[] = 65530;
@@ -1879,6 +1880,7 @@ endpoint 1 {
18791880
callback attribute threadVersion;
18801881
callback attribute interfaceEnabled;
18811882
callback attribute activeDatasetTimestamp;
1883+
callback attribute pendingDatasetTimestamp;
18821884
callback attribute generatedCommandList;
18831885
callback attribute acceptedCommandList;
18841886
callback attribute eventList;

examples/network-manager-app/network-manager-common/network-manager-app.zap

+25-9
Original file line numberDiff line numberDiff line change
@@ -3420,7 +3420,7 @@
34203420
"storageOption": "External",
34213421
"singleton": 0,
34223422
"bounded": 0,
3423-
"defaultValue": "",
3423+
"defaultValue": null,
34243424
"reportable": 1,
34253425
"minInterval": 1,
34263426
"maxInterval": 65534,
@@ -3436,7 +3436,7 @@
34363436
"storageOption": "External",
34373437
"singleton": 0,
34383438
"bounded": 0,
3439-
"defaultValue": "",
3439+
"defaultValue": null,
34403440
"reportable": 1,
34413441
"minInterval": 1,
34423442
"maxInterval": 65534,
@@ -3452,7 +3452,7 @@
34523452
"storageOption": "External",
34533453
"singleton": 0,
34543454
"bounded": 0,
3455-
"defaultValue": "",
3455+
"defaultValue": null,
34563456
"reportable": 1,
34573457
"minInterval": 1,
34583458
"maxInterval": 65534,
@@ -3468,7 +3468,7 @@
34683468
"storageOption": "External",
34693469
"singleton": 0,
34703470
"bounded": 0,
3471-
"defaultValue": "",
3471+
"defaultValue": null,
34723472
"reportable": 1,
34733473
"minInterval": 1,
34743474
"maxInterval": 65534,
@@ -3484,6 +3484,22 @@
34843484
"storageOption": "External",
34853485
"singleton": 0,
34863486
"bounded": 0,
3487+
"defaultValue": null,
3488+
"reportable": 1,
3489+
"minInterval": 1,
3490+
"maxInterval": 65534,
3491+
"reportableChange": 0
3492+
},
3493+
{
3494+
"name": "PendingDatasetTimestamp",
3495+
"code": 5,
3496+
"mfgCode": null,
3497+
"side": "server",
3498+
"type": "int64u",
3499+
"included": 1,
3500+
"storageOption": "External",
3501+
"singleton": 0,
3502+
"bounded": 0,
34873503
"defaultValue": "",
34883504
"reportable": 1,
34893505
"minInterval": 1,
@@ -3500,7 +3516,7 @@
35003516
"storageOption": "External",
35013517
"singleton": 0,
35023518
"bounded": 0,
3503-
"defaultValue": "",
3519+
"defaultValue": null,
35043520
"reportable": 1,
35053521
"minInterval": 1,
35063522
"maxInterval": 65534,
@@ -3516,7 +3532,7 @@
35163532
"storageOption": "External",
35173533
"singleton": 0,
35183534
"bounded": 0,
3519-
"defaultValue": "",
3535+
"defaultValue": null,
35203536
"reportable": 1,
35213537
"minInterval": 1,
35223538
"maxInterval": 65534,
@@ -3532,7 +3548,7 @@
35323548
"storageOption": "External",
35333549
"singleton": 0,
35343550
"bounded": 0,
3535-
"defaultValue": "",
3551+
"defaultValue": null,
35363552
"reportable": 1,
35373553
"minInterval": 1,
35383554
"maxInterval": 65534,
@@ -3548,7 +3564,7 @@
35483564
"storageOption": "External",
35493565
"singleton": 0,
35503566
"bounded": 0,
3551-
"defaultValue": "",
3567+
"defaultValue": null,
35523568
"reportable": 1,
35533569
"minInterval": 1,
35543570
"maxInterval": 65534,
@@ -3564,7 +3580,7 @@
35643580
"storageOption": "External",
35653581
"singleton": 0,
35663582
"bounded": 0,
3567-
"defaultValue": "",
3583+
"defaultValue": null,
35683584
"reportable": 1,
35693585
"minInterval": 1,
35703586
"maxInterval": 65534,

src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp

+45-21
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "platform/CHIPDeviceEvent.h"
3939
#include "platform/PlatformManager.h"
4040
#include "protocols/interaction_model/StatusCode.h"
41+
#include <optional>
4142

4243
namespace chip {
4344
namespace app {
@@ -46,21 +47,24 @@ namespace ThreadBorderRouterManagement {
4647

4748
using Protocols::InteractionModel::Status;
4849

49-
static bool IsCommandOverCASESession(CommandHandlerInterface::HandlerContext & ctx)
50+
bool ServerInstance::IsCommandOverCASESession(CommandHandlerInterface::HandlerContext & ctx)
5051
{
52+
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
53+
if (mSkipCASESessionCheck)
54+
{
55+
return true;
56+
}
57+
#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST
5158
Messaging::ExchangeContext * exchangeCtx = ctx.mCommandHandler.GetExchangeContext();
5259
return exchangeCtx && exchangeCtx->HasSessionHandle() && exchangeCtx->GetSessionHandle()->IsSecureSession() &&
5360
exchangeCtx->GetSessionHandle()->AsSecureSession()->GetSecureSessionType() == Transport::SecureSession::Type::kCASE;
5461
}
5562

56-
Status ServerInstance::HandleGetDatasetRequest(bool isOverCASESession, Delegate::DatasetType type,
63+
Status ServerInstance::HandleGetDatasetRequest(CommandHandlerInterface::HandlerContext & ctx, Delegate::DatasetType type,
5764
Thread::OperationalDataset & dataset)
5865
{
5966
VerifyOrDie(mDelegate);
60-
if (!isOverCASESession)
61-
{
62-
return Status::UnsupportedAccess;
63-
}
67+
VerifyOrReturnValue(IsCommandOverCASESession(ctx), Status::UnsupportedAccess);
6468

6569
CHIP_ERROR err = mDelegate->GetDataset(dataset, type);
6670
if (err != CHIP_NO_ERROR)
@@ -70,7 +74,7 @@ Status ServerInstance::HandleGetDatasetRequest(bool isOverCASESession, Delegate:
7074
return Status::Success;
7175
}
7276

73-
Status ServerInstance::HandleSetActiveDatasetRequest(CommandHandler * commandHandler,
77+
Status ServerInstance::HandleSetActiveDatasetRequest(CommandHandlerInterface::HandlerContext & ctx,
7478
const Commands::SetActiveDatasetRequest::DecodableType & req)
7579
{
7680
// The SetActiveDatasetRequest command SHALL be FailSafeArmed. Upon receiving this command, the Thread BR will set its
@@ -80,7 +84,8 @@ Status ServerInstance::HandleSetActiveDatasetRequest(CommandHandler * commandHan
8084
// reverted. If the FailSafe timer expires before the Thread BR responds, the Thread BR will respond with a timeout status and
8185
// the active dataset should also be reverted.
8286
VerifyOrDie(mDelegate);
83-
VerifyOrReturnValue(mFailsafeContext.IsFailSafeArmed(commandHandler->GetAccessingFabricIndex()), Status::FailsafeRequired);
87+
VerifyOrReturnValue(IsCommandOverCASESession(ctx), Status::UnsupportedAccess);
88+
VerifyOrReturnValue(mFailsafeContext.IsFailSafeArmed(ctx.mCommandHandler.GetAccessingFabricIndex()), Status::FailsafeRequired);
8489

8590
Thread::OperationalDataset activeDataset;
8691
Thread::OperationalDataset currentActiveDataset;
@@ -101,17 +106,19 @@ Status ServerInstance::HandleSetActiveDatasetRequest(CommandHandler * commandHan
101106
{
102107
return Status::Busy;
103108
}
104-
commandHandler->FlushAcksRightAwayOnSlowCommand();
105-
mAsyncCommandHandle = CommandHandler::Handle(commandHandler);
109+
ctx.mCommandHandler.FlushAcksRightAwayOnSlowCommand();
110+
mAsyncCommandHandle = CommandHandler::Handle(&ctx.mCommandHandler);
106111
mBreadcrumb = req.breadcrumb;
107112
mSetActiveDatasetSequenceNumber++;
108113
mDelegate->SetActiveDataset(activeDataset, mSetActiveDatasetSequenceNumber, this);
109114
return Status::Success;
110115
}
111116

112-
Status ServerInstance::HandleSetPendingDatasetRequest(const Commands::SetPendingDatasetRequest::DecodableType & req)
117+
Status ServerInstance::HandleSetPendingDatasetRequest(CommandHandlerInterface::HandlerContext & ctx,
118+
const Commands::SetPendingDatasetRequest::DecodableType & req)
113119
{
114120
VerifyOrDie(mDelegate);
121+
VerifyOrReturnValue(IsCommandOverCASESession(ctx), Status::UnsupportedAccess);
115122
if (!mDelegate->GetPanChangeSupported())
116123
{
117124
return Status::UnsupportedCommand;
@@ -143,21 +150,21 @@ void ServerInstance::InvokeCommand(HandlerContext & ctxt)
143150
case Commands::GetActiveDatasetRequest::Id:
144151
HandleCommand<Commands::GetActiveDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
145152
Thread::OperationalDataset dataset;
146-
Status status = HandleGetActiveDatasetRequest(IsCommandOverCASESession(ctx), dataset);
153+
Status status = HandleGetActiveDatasetRequest(ctx, dataset);
147154
AddDatasetResponse(ctx, status, dataset);
148155
});
149156
break;
150157
case Commands::GetPendingDatasetRequest::Id:
151158
HandleCommand<Commands::GetPendingDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
152159
Thread::OperationalDataset dataset;
153-
Status status = HandleGetPendingDatasetRequest(IsCommandOverCASESession(ctx), dataset);
160+
Status status = HandleGetPendingDatasetRequest(ctx, dataset);
154161
AddDatasetResponse(ctx, status, dataset);
155162
});
156163
break;
157164
case Commands::SetActiveDatasetRequest::Id:
158165
HandleCommand<Commands::SetActiveDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
159166
mPath = ctx.mRequestPath;
160-
Status status = HandleSetActiveDatasetRequest(&ctx.mCommandHandler, req);
167+
Status status = HandleSetActiveDatasetRequest(ctx, req);
161168
if (status != Status::Success)
162169
{
163170
// If status is not Success, we should immediately report the status. Otherwise the async work will report the
@@ -168,7 +175,8 @@ void ServerInstance::InvokeCommand(HandlerContext & ctxt)
168175
break;
169176
case Commands::SetPendingDatasetRequest::Id:
170177
HandleCommand<Commands::SetPendingDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
171-
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, HandleSetPendingDatasetRequest(req));
178+
Status status = HandleSetPendingDatasetRequest(ctx, req);
179+
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status);
172180
});
173181
break;
174182
default:
@@ -199,16 +207,28 @@ CHIP_ERROR ServerInstance::ReadBorderAgentID(MutableByteSpan & outBorderAgentId)
199207
return CHIP_NO_ERROR;
200208
}
201209

202-
Optional<uint64_t> ServerInstance::ReadActiveDatasetTimestamp()
210+
std::optional<uint64_t> ServerInstance::ReadActiveDatasetTimestamp()
203211
{
204212
uint64_t activeDatasetTimestampValue = 0;
205213
Thread::OperationalDataset activeDataset;
206214
if ((mDelegate->GetDataset(activeDataset, Delegate::DatasetType::kActive) == CHIP_NO_ERROR) &&
207215
(activeDataset.GetActiveTimestamp(activeDatasetTimestampValue) == CHIP_NO_ERROR))
208216
{
209-
return MakeOptional(activeDatasetTimestampValue);
217+
return std::make_optional(activeDatasetTimestampValue);
218+
}
219+
return std::nullopt;
220+
}
221+
222+
std::optional<uint64_t> ServerInstance::ReadPendingDatasetTimestamp()
223+
{
224+
uint64_t pendingDatasetTimestampValue = 0;
225+
Thread::OperationalDataset pendingDataset;
226+
if ((mDelegate->GetDataset(pendingDataset, Delegate::DatasetType::kPending) == CHIP_NO_ERROR) &&
227+
(pendingDataset.GetActiveTimestamp(pendingDatasetTimestampValue) == CHIP_NO_ERROR))
228+
{
229+
return std::make_optional(pendingDatasetTimestampValue);
210230
}
211-
return NullOptional;
231+
return std::nullopt;
212232
}
213233

214234
CHIP_ERROR ServerInstance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
@@ -259,9 +279,13 @@ CHIP_ERROR ServerInstance::Read(const ConcreteReadAttributePath & aPath, Attribu
259279
break;
260280
}
261281
case Attributes::ActiveDatasetTimestamp::Id: {
262-
Optional<uint64_t> activeDatasetTimestamp = ReadActiveDatasetTimestamp();
263-
status = activeDatasetTimestamp.HasValue() ? aEncoder.Encode(DataModel::MakeNullable(activeDatasetTimestamp.Value()))
264-
: aEncoder.EncodeNull();
282+
std::optional<uint64_t> activeDatasetTimestamp = ReadActiveDatasetTimestamp();
283+
status = activeDatasetTimestamp.has_value() ? aEncoder.Encode(activeDatasetTimestamp.value()) : aEncoder.EncodeNull();
284+
break;
285+
}
286+
case Attributes::PendingDatasetTimestamp::Id: {
287+
std::optional<uint64_t> pendingDatasetTimestamp = ReadPendingDatasetTimestamp();
288+
status = pendingDatasetTimestamp.has_value() ? aEncoder.Encode(pendingDatasetTimestamp.value()) : aEncoder.EncodeNull();
265289
break;
266290
}
267291
default:

src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.h

+14-9
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,30 @@ class ServerInstance : public CommandHandlerInterface,
6464
// TODO: Split the business logic from the unit test class
6565
friend class TestThreadBorderRouterManagementCluster;
6666
// Command Handlers
67-
Status HandleGetActiveDatasetRequest(bool isOverCASESession, Thread::OperationalDataset & dataset)
67+
Status HandleGetActiveDatasetRequest(HandlerContext & ctx, Thread::OperationalDataset & dataset)
6868
{
69-
return HandleGetDatasetRequest(isOverCASESession, Delegate::DatasetType::kActive, dataset);
69+
return HandleGetDatasetRequest(ctx, Delegate::DatasetType::kActive, dataset);
7070
}
71-
Status HandleGetPendingDatasetRequest(bool isOverCASESession, Thread::OperationalDataset & dataset)
71+
Status HandleGetPendingDatasetRequest(HandlerContext & ctx, Thread::OperationalDataset & dataset)
7272
{
73-
return HandleGetDatasetRequest(isOverCASESession, Delegate::DatasetType::kPending, dataset);
73+
return HandleGetDatasetRequest(ctx, Delegate::DatasetType::kPending, dataset);
7474
}
75-
Status HandleSetActiveDatasetRequest(CommandHandler * commandHandler,
76-
const Commands::SetActiveDatasetRequest::DecodableType & req);
77-
Status HandleSetPendingDatasetRequest(const Commands::SetPendingDatasetRequest::DecodableType & req);
78-
Status HandleGetDatasetRequest(bool isOverCASESession, Delegate::DatasetType type, Thread::OperationalDataset & dataset);
75+
Status HandleSetActiveDatasetRequest(HandlerContext & ctx, const Commands::SetActiveDatasetRequest::DecodableType & req);
76+
Status HandleSetPendingDatasetRequest(HandlerContext & ctx, const Commands::SetPendingDatasetRequest::DecodableType & req);
77+
Status HandleGetDatasetRequest(HandlerContext & ctx, Delegate::DatasetType type, Thread::OperationalDataset & dataset);
7978

8079
// Attribute Read handlers
8180
void ReadFeatureMap(BitFlags<Feature> & feature);
82-
Optional<uint64_t> ReadActiveDatasetTimestamp();
81+
std::optional<uint64_t> ReadActiveDatasetTimestamp();
82+
std::optional<uint64_t> ReadPendingDatasetTimestamp();
8383
CHIP_ERROR ReadBorderRouterName(MutableCharSpan & borderRouterName);
8484
CHIP_ERROR ReadBorderAgentID(MutableByteSpan & borderAgentId);
8585

86+
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
87+
void SetSkipCASESessionCheck(bool skipCheck) { mSkipCASESessionCheck = skipCheck; }
88+
bool mSkipCASESessionCheck;
89+
#endif
90+
bool IsCommandOverCASESession(CommandHandlerInterface::HandlerContext & ctx);
8691
static void OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
8792
void OnFailSafeTimerExpired();
8893
void CommitSavedBreadcrumb();

0 commit comments

Comments
 (0)