Skip to content

Added implementations for the JF Administrator and Datastore Servers #38842

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions scripts/tools/check_includes_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,8 @@
'src/access/AccessRestrictionProvider.h': {'vector', 'map'},
# nrfconnect test runner
'src/test_driver/nrfconnect/main/runner.cpp': {'vector'},

# Not intended for embedded clients
'src/app/server/JointFabricDatastore.cpp': {'vector'},
'src/app/server/JointFabricDatastore.h': {'vector'},
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,9 @@ CHIP_ERROR JointFabricAdministratorAttrAccess::Read(const ConcreteReadAttributeP
return CHIP_NO_ERROR;
}

// TODO
CHIP_ERROR JointFabricAdministratorAttrAccess::ReadAdministratorFabricIndex(AttributeValueEncoder & aEncoder)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
return aEncoder.Encode(Server::GetInstance().GetJointFabricDatastore().GetAdministratorFabricIndex());
}

void MatterJointFabricAdministratorPluginServerInitCallback()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ using chip::Protocols::InteractionModel::Status;

namespace JointFabricDatastoreCluster = chip::app::Clusters::JointFabricDatastore;

class JointFabricDatastoreAttrAccess : public AttributeAccessInterface
class JointFabricDatastoreAttrAccess : public AttributeAccessInterface, public app::JointFabricDatastore::Listener
{
public:
JointFabricDatastoreAttrAccess() : AttributeAccessInterface(Optional<EndpointId>::Missing(), JointFabricDatastoreCluster::Id) {}

CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override;

void MarkNodeListChanged() override;

private:
CHIP_ERROR ReadAnchorNodeId(AttributeValueEncoder & aEncoder);
CHIP_ERROR ReadAnchorVendorId(AttributeValueEncoder & aEncoder);
Expand Down Expand Up @@ -81,41 +83,94 @@ CHIP_ERROR JointFabricDatastoreAttrAccess::Read(const ConcreteReadAttributePath
return CHIP_NO_ERROR;
}

// TODO
CHIP_ERROR JointFabricDatastoreAttrAccess::ReadAnchorNodeId(AttributeValueEncoder & aEncoder)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
NodeId anchorNodeId = Server::GetInstance().GetJointFabricDatastore().GetAnchorNodeId();
ReturnErrorOnFailure(aEncoder.Encode(anchorNodeId));
return CHIP_NO_ERROR;
}

// TODO
CHIP_ERROR JointFabricDatastoreAttrAccess::ReadAnchorVendorId(AttributeValueEncoder & aEncoder)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
VendorId anchorVendorId = Server::GetInstance().GetJointFabricDatastore().GetAnchorVendorId();
ReturnErrorOnFailure(aEncoder.Encode(anchorVendorId));
return CHIP_NO_ERROR;
}

// TODO
CHIP_ERROR JointFabricDatastoreAttrAccess::ReadGroupKeySetList(AttributeValueEncoder & aEncoder)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR {
auto entries = Server::GetInstance().GetJointFabricDatastore().GetGroupKeySetList();

for (auto & entry : entries)
{
ReturnErrorOnFailure(encoder.Encode(entry));
}
return CHIP_NO_ERROR;
});
}

// TODO
CHIP_ERROR JointFabricDatastoreAttrAccess::ReadAdminList(AttributeValueEncoder & aEncoder)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR {
auto entries = Server::GetInstance().GetJointFabricDatastore().GetAdminEntries();

for (auto & entry : entries)
{
ReturnErrorOnFailure(encoder.Encode(entry));
}
return CHIP_NO_ERROR;
});
}

// TODO
CHIP_ERROR JointFabricDatastoreAttrAccess::ReadNodeList(AttributeValueEncoder & aEncoder)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR {
auto entries = Server::GetInstance().GetJointFabricDatastore().GetNodeInformationEntries();

for (auto & entry : entries)
{
ReturnErrorOnFailure(encoder.Encode(entry));
}
return CHIP_NO_ERROR;
});
}

void JointFabricDatastoreAttrAccess::MarkNodeListChanged()
{
MatterReportingAttributeChangeCallback(kRootEndpointId, JointFabricDatastoreCluster::Id,
JointFabricDatastoreCluster::Attributes::NodeList::Id);
}

// TODO
bool emberAfJointFabricDatastoreClusterAddAdminCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::AddAdmin::DecodableType & commandData)
{
CHIP_ERROR err = CHIP_NO_ERROR;
app::JointFabricDatastore & jointFabricDatastore = Server::GetInstance().GetJointFabricDatastore();

auto nodeID = commandData.nodeID;
auto friendlyName = commandData.friendlyName;
auto vendorID = commandData.vendorID;
auto icac = commandData.icac;

JointFabricDatastoreCluster::Structs::DatastoreAdministratorInformationEntryStruct::DecodableType adminInformationEntry = {
.nodeID = nodeID, .friendlyName = friendlyName, .vendorID = vendorID, .icac = icac
};

SuccessOrExit(err = jointFabricDatastore.AddAdmin(adminInformationEntry));

exit:
if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

Expand All @@ -127,43 +182,121 @@ bool emberAfJointFabricDatastoreClusterAddGroupCallback(
return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterAddKeySetCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::AddKeySet::DecodableType & commandData)
{
CHIP_ERROR err = CHIP_NO_ERROR;
JointFabricDatastoreCluster::Structs::DatastoreGroupKeySetStruct::DecodableType groupKeySet = commandData.groupKeySet;
app::JointFabricDatastore & jointFabricDatastore = Server::GetInstance().GetJointFabricDatastore();

VerifyOrExit(jointFabricDatastore.IsGroupKeySetEntryPresent(groupKeySet.groupKeySetID) == false,
err = CHIP_ERROR_INVALID_ARGUMENT);
SuccessOrExit(err = jointFabricDatastore.AddGroupKeySetEntry(groupKeySet));

exit:
if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterRemoveNodeCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::RemoveNode::DecodableType & commandData)
{
NodeId nodeId = commandData.nodeID;

CHIP_ERROR err = Server::GetInstance().GetJointFabricDatastore().RemoveNode(nodeId);

if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterUpdateNodeCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::UpdateNode::DecodableType & commandData)
{
NodeId nodeId = commandData.nodeID;
const CharSpan & friendlyName = commandData.friendlyName;

CHIP_ERROR err = Server::GetInstance().GetJointFabricDatastore().UpdateNode(nodeId, friendlyName);

if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterRefreshNodeCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::RefreshNode::DecodableType & commandData)
{
CHIP_ERROR err = CHIP_NO_ERROR;
NodeId nodeId = commandData.nodeID;

app::JointFabricDatastore & jointFabricDatastore = Server::GetInstance().GetJointFabricDatastore();

SuccessOrExit(err = jointFabricDatastore.RefreshNode(nodeId));

exit:
if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterRemoveAdminCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::RemoveAdmin::DecodableType & commandData)
{
CHIP_ERROR err = CHIP_NO_ERROR;
auto nodeId = commandData.nodeID;
app::JointFabricDatastore & jointFabricDatastore = Server::GetInstance().GetJointFabricDatastore();

SuccessOrExit(err = jointFabricDatastore.RemoveAdmin(nodeId));

exit:
if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

Expand All @@ -175,11 +308,29 @@ bool emberAfJointFabricDatastoreClusterRemoveGroupCallback(
return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterUpdateAdminCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::UpdateAdmin::DecodableType & commandData)
{
CHIP_ERROR err = CHIP_NO_ERROR;
auto nodeId = commandData.nodeID.Value();
auto friendlyName = commandData.friendlyName.Value();
auto icac = commandData.icac.Value();
app::JointFabricDatastore & jointFabricDatastore = Server::GetInstance().GetJointFabricDatastore();

SuccessOrExit(err = jointFabricDatastore.UpdateAdmin(nodeId, friendlyName, icac));

exit:
if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

Expand All @@ -199,11 +350,27 @@ bool emberAfJointFabricDatastoreClusterAddACLToNodeCallback(
return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterRemoveKeySetCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::RemoveKeySet::DecodableType & commandData)
{
CHIP_ERROR err = CHIP_NO_ERROR;
uint16_t groupKeySetId = commandData.groupKeySetID;
app::JointFabricDatastore & jointFabricDatastore = Server::GetInstance().GetJointFabricDatastore();

SuccessOrExit(err = jointFabricDatastore.RemoveGroupKeySetEntry(groupKeySetId));

exit:
if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

Expand All @@ -215,11 +382,25 @@ bool emberAfJointFabricDatastoreClusterUpdateKeySetCallback(
return true;
}

// TODO
bool emberAfJointFabricDatastoreClusterAddPendingNodeCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const JointFabricDatastoreCluster::Commands::AddPendingNode::DecodableType & commandData)
{
NodeId nodeId = commandData.nodeID;
const CharSpan & friendlyName = commandData.friendlyName;

CHIP_ERROR err = Server::GetInstance().GetJointFabricDatastore().AddPendingNode(nodeId, friendlyName);

if (err == CHIP_NO_ERROR)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Success);
}
else
{
ChipLogError(DataManagement, "JointFabricDatastoreCluster: failed with error: %" CHIP_ERROR_FORMAT, err.Format());
commandObj->AddStatus(commandPath, Protocols::InteractionModel::ClusterStatusCode(err));
}

return true;
}

Expand Down Expand Up @@ -275,4 +456,6 @@ void MatterJointFabricDatastorePluginServerInitCallback()
{
ChipLogProgress(Zcl, "Initiating Joint Fabric Datastore cluster.");
AttributeAccessInterfaceRegistry::Instance().Register(&gJointFabricDatastoreAttrAccess);

Server::GetInstance().GetJointFabricDatastore().AddListener(gJointFabricDatastoreAttrAccess);
}
2 changes: 2 additions & 0 deletions src/app/server/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ static_library("server") {
"Dnssd.h",
"EchoHandler.cpp",
"EchoHandler.h",
"JointFabricDatastore.cpp",
"JointFabricDatastore.h",
"Server.cpp",
"Server.h",
]
Expand Down
Loading
Loading