Skip to content

Commit

Permalink
TBRM: Add missing PendingDatasetTimestamp attribute and CASE session …
Browse files Browse the repository at this point in the history
…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 <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Oct 22, 2024
1 parent 4ebe543 commit 1078512
Show file tree
Hide file tree
Showing 33 changed files with 564 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,7 @@ provisional cluster ThreadBorderRouterManagement = 1106 {
provisional readonly attribute int16u threadVersion = 2;
provisional readonly attribute boolean interfaceEnabled = 3;
provisional readonly attribute nullable int64u activeDatasetTimestamp = 4;
provisional readonly attribute nullable int64u pendingDatasetTimestamp = 5;
readonly attribute command_id generatedCommandList[] = 65528;
readonly attribute command_id acceptedCommandList[] = 65529;
readonly attribute event_id eventList[] = 65530;
Expand Down Expand Up @@ -1879,6 +1880,7 @@ endpoint 1 {
callback attribute threadVersion;
callback attribute interfaceEnabled;
callback attribute activeDatasetTimestamp;
callback attribute pendingDatasetTimestamp;
callback attribute generatedCommandList;
callback attribute acceptedCommandList;
callback attribute eventList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3420,7 +3420,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3436,7 +3436,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3452,7 +3452,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3468,7 +3468,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3484,6 +3484,22 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "PendingDatasetTimestamp",
"code": 5,
"mfgCode": null,
"side": "server",
"type": "int64u",
"included": 1,
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"reportable": 1,
"minInterval": 1,
Expand All @@ -3500,7 +3516,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3516,7 +3532,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3532,7 +3548,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3548,7 +3564,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand All @@ -3564,7 +3580,7 @@
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "platform/CHIPDeviceEvent.h"
#include "platform/PlatformManager.h"
#include "protocols/interaction_model/StatusCode.h"
#include <optional>

namespace chip {
namespace app {
Expand All @@ -46,21 +47,24 @@ namespace ThreadBorderRouterManagement {

using Protocols::InteractionModel::Status;

static bool IsCommandOverCASESession(CommandHandlerInterface::HandlerContext & ctx)
bool ServerInstance::IsCommandOverCASESession(CommandHandlerInterface::HandlerContext & ctx)
{
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
if (mSkipCASESessionCheck)
{
return true;
}
#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST
Messaging::ExchangeContext * exchangeCtx = ctx.mCommandHandler.GetExchangeContext();
return exchangeCtx && exchangeCtx->HasSessionHandle() && exchangeCtx->GetSessionHandle()->IsSecureSession() &&
exchangeCtx->GetSessionHandle()->AsSecureSession()->GetSecureSessionType() == Transport::SecureSession::Type::kCASE;
}

Status ServerInstance::HandleGetDatasetRequest(bool isOverCASESession, Delegate::DatasetType type,
Status ServerInstance::HandleGetDatasetRequest(CommandHandlerInterface::HandlerContext & ctx, Delegate::DatasetType type,
Thread::OperationalDataset & dataset)
{
VerifyOrDie(mDelegate);
if (!isOverCASESession)
{
return Status::UnsupportedAccess;
}
VerifyOrReturnValue(IsCommandOverCASESession(ctx), Status::UnsupportedAccess);

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

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

Thread::OperationalDataset activeDataset;
Thread::OperationalDataset currentActiveDataset;
Expand All @@ -101,17 +106,19 @@ Status ServerInstance::HandleSetActiveDatasetRequest(CommandHandler * commandHan
{
return Status::Busy;
}
commandHandler->FlushAcksRightAwayOnSlowCommand();
mAsyncCommandHandle = CommandHandler::Handle(commandHandler);
ctx.mCommandHandler.FlushAcksRightAwayOnSlowCommand();
mAsyncCommandHandle = CommandHandler::Handle(&ctx.mCommandHandler);
mBreadcrumb = req.breadcrumb;
mSetActiveDatasetSequenceNumber++;
mDelegate->SetActiveDataset(activeDataset, mSetActiveDatasetSequenceNumber, this);
return Status::Success;
}

Status ServerInstance::HandleSetPendingDatasetRequest(const Commands::SetPendingDatasetRequest::DecodableType & req)
Status ServerInstance::HandleSetPendingDatasetRequest(CommandHandlerInterface::HandlerContext & ctx,
const Commands::SetPendingDatasetRequest::DecodableType & req)
{
VerifyOrDie(mDelegate);
VerifyOrReturnValue(IsCommandOverCASESession(ctx), Status::UnsupportedAccess);
if (!mDelegate->GetPanChangeSupported())
{
return Status::UnsupportedCommand;
Expand Down Expand Up @@ -143,21 +150,21 @@ void ServerInstance::InvokeCommand(HandlerContext & ctxt)
case Commands::GetActiveDatasetRequest::Id:
HandleCommand<Commands::GetActiveDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
Thread::OperationalDataset dataset;
Status status = HandleGetActiveDatasetRequest(IsCommandOverCASESession(ctx), dataset);
Status status = HandleGetActiveDatasetRequest(ctx, dataset);
AddDatasetResponse(ctx, status, dataset);
});
break;
case Commands::GetPendingDatasetRequest::Id:
HandleCommand<Commands::GetPendingDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
Thread::OperationalDataset dataset;
Status status = HandleGetPendingDatasetRequest(IsCommandOverCASESession(ctx), dataset);
Status status = HandleGetPendingDatasetRequest(ctx, dataset);
AddDatasetResponse(ctx, status, dataset);
});
break;
case Commands::SetActiveDatasetRequest::Id:
HandleCommand<Commands::SetActiveDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
mPath = ctx.mRequestPath;
Status status = HandleSetActiveDatasetRequest(&ctx.mCommandHandler, req);
Status status = HandleSetActiveDatasetRequest(ctx, req);
if (status != Status::Success)
{
// If status is not Success, we should immediately report the status. Otherwise the async work will report the
Expand All @@ -168,7 +175,8 @@ void ServerInstance::InvokeCommand(HandlerContext & ctxt)
break;
case Commands::SetPendingDatasetRequest::Id:
HandleCommand<Commands::SetPendingDatasetRequest::DecodableType>(ctxt, [this](HandlerContext & ctx, const auto & req) {
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, HandleSetPendingDatasetRequest(req));
Status status = HandleSetPendingDatasetRequest(ctx, req);
ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status);
});
break;
default:
Expand Down Expand Up @@ -199,16 +207,28 @@ CHIP_ERROR ServerInstance::ReadBorderAgentID(MutableByteSpan & outBorderAgentId)
return CHIP_NO_ERROR;
}

Optional<uint64_t> ServerInstance::ReadActiveDatasetTimestamp()
std::optional<uint64_t> ServerInstance::ReadActiveDatasetTimestamp()
{
uint64_t activeDatasetTimestampValue = 0;
Thread::OperationalDataset activeDataset;
if ((mDelegate->GetDataset(activeDataset, Delegate::DatasetType::kActive) == CHIP_NO_ERROR) &&
(activeDataset.GetActiveTimestamp(activeDatasetTimestampValue) == CHIP_NO_ERROR))
{
return MakeOptional(activeDatasetTimestampValue);
return std::make_optional(activeDatasetTimestampValue);
}
return std::nullopt;
}

std::optional<uint64_t> ServerInstance::ReadPendingDatasetTimestamp()
{
uint64_t pendingDatasetTimestampValue = 0;
Thread::OperationalDataset pendingDataset;
if ((mDelegate->GetDataset(pendingDataset, Delegate::DatasetType::kPending) == CHIP_NO_ERROR) &&
(pendingDataset.GetActiveTimestamp(pendingDatasetTimestampValue) == CHIP_NO_ERROR))
{
return std::make_optional(pendingDatasetTimestampValue);
}
return NullOptional;
return std::nullopt;
}

CHIP_ERROR ServerInstance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
Expand Down Expand Up @@ -259,9 +279,13 @@ CHIP_ERROR ServerInstance::Read(const ConcreteReadAttributePath & aPath, Attribu
break;
}
case Attributes::ActiveDatasetTimestamp::Id: {
Optional<uint64_t> activeDatasetTimestamp = ReadActiveDatasetTimestamp();
status = activeDatasetTimestamp.HasValue() ? aEncoder.Encode(DataModel::MakeNullable(activeDatasetTimestamp.Value()))
: aEncoder.EncodeNull();
std::optional<uint64_t> activeDatasetTimestamp = ReadActiveDatasetTimestamp();
status = activeDatasetTimestamp.has_value() ? aEncoder.Encode(activeDatasetTimestamp.value()) : aEncoder.EncodeNull();
break;
}
case Attributes::PendingDatasetTimestamp::Id: {
std::optional<uint64_t> pendingDatasetTimestamp = ReadPendingDatasetTimestamp();
status = pendingDatasetTimestamp.has_value() ? aEncoder.Encode(pendingDatasetTimestamp.value()) : aEncoder.EncodeNull();
break;
}
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,30 @@ class ServerInstance : public CommandHandlerInterface,
// TODO: Split the business logic from the unit test class
friend class TestThreadBorderRouterManagementCluster;
// Command Handlers
Status HandleGetActiveDatasetRequest(bool isOverCASESession, Thread::OperationalDataset & dataset)
Status HandleGetActiveDatasetRequest(HandlerContext & ctx, Thread::OperationalDataset & dataset)
{
return HandleGetDatasetRequest(isOverCASESession, Delegate::DatasetType::kActive, dataset);
return HandleGetDatasetRequest(ctx, Delegate::DatasetType::kActive, dataset);
}
Status HandleGetPendingDatasetRequest(bool isOverCASESession, Thread::OperationalDataset & dataset)
Status HandleGetPendingDatasetRequest(HandlerContext & ctx, Thread::OperationalDataset & dataset)
{
return HandleGetDatasetRequest(isOverCASESession, Delegate::DatasetType::kPending, dataset);
return HandleGetDatasetRequest(ctx, Delegate::DatasetType::kPending, dataset);
}
Status HandleSetActiveDatasetRequest(CommandHandler * commandHandler,
const Commands::SetActiveDatasetRequest::DecodableType & req);
Status HandleSetPendingDatasetRequest(const Commands::SetPendingDatasetRequest::DecodableType & req);
Status HandleGetDatasetRequest(bool isOverCASESession, Delegate::DatasetType type, Thread::OperationalDataset & dataset);
Status HandleSetActiveDatasetRequest(HandlerContext & ctx, const Commands::SetActiveDatasetRequest::DecodableType & req);
Status HandleSetPendingDatasetRequest(HandlerContext & ctx, const Commands::SetPendingDatasetRequest::DecodableType & req);
Status HandleGetDatasetRequest(HandlerContext & ctx, Delegate::DatasetType type, Thread::OperationalDataset & dataset);

// Attribute Read handlers
void ReadFeatureMap(BitFlags<Feature> & feature);
Optional<uint64_t> ReadActiveDatasetTimestamp();
std::optional<uint64_t> ReadActiveDatasetTimestamp();
std::optional<uint64_t> ReadPendingDatasetTimestamp();
CHIP_ERROR ReadBorderRouterName(MutableCharSpan & borderRouterName);
CHIP_ERROR ReadBorderAgentID(MutableByteSpan & borderAgentId);

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
void SetSkipCASESessionCheck(bool skipCheck) { mSkipCASESessionCheck = skipCheck; }
bool mSkipCASESessionCheck;
#endif
bool IsCommandOverCASESession(CommandHandlerInterface::HandlerContext & ctx);
static void OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
void OnFailSafeTimerExpired();
void CommitSavedBreadcrumb();
Expand Down
Loading

0 comments on commit 1078512

Please sign in to comment.