Skip to content

Commit

Permalink
fabric-bridge: Add ECOINFO to dynamic bridged endpoints (#34811)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: saurabhst <[email protected]>
  • Loading branch information
3 people authored Aug 7, 2024
1 parent a0fac9f commit e8186eb
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 3 deletions.
14 changes: 13 additions & 1 deletion examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,24 @@ config("config") {
include_dirs = [ "include" ]
}

chip_data_model("fabric-bridge-common") {
chip_data_model("fabric-bridge-common-zap") {
zap_file = "fabric-bridge-app.zap"
is_server = true
cflags = [ "-DDYNAMIC_ENDPOINT_COUNT=16" ]
}

# This includes all the clusters that only exist on the dynamic endpoint.
source_set("fabric-bridge-common") {
public_configs = [ ":config" ]

sources = [
"${chip_root}/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp",
"${chip_root}/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h",
]

public_deps = [ ":fabric-bridge-common-zap" ]
}

source_set("fabric-bridge-lib") {
public_configs = [ ":config" ]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(bridgedDeviceBasicAttrs)
kSoftwareVersionSize, 0),
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();

// Declare Ecosystem Information cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(ecosystemInformationBasicAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(EcosystemInformation::Attributes::RemovedOn::Id, EPOCH_US, kNodeLabelSize, ATTRIBUTE_MASK_NULLABLE),
DECLARE_DYNAMIC_ATTRIBUTE(EcosystemInformation::Attributes::DeviceDirectory::Id, ARRAY, kDescriptorAttributeArraySize, 0),
DECLARE_DYNAMIC_ATTRIBUTE(EcosystemInformation::Attributes::LocationDirectory::Id, ARRAY, kDescriptorAttributeArraySize, 0),
DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();

// Declare Administrator Commissioning cluster attributes
DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(AdministratorCommissioningAttrs)
DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::WindowStatus::Id, ENUM8, 1, 0),
Expand All @@ -131,6 +138,7 @@ constexpr CommandId administratorCommissioningCommands[] = {
DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedNodeClusters)
DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(EcosystemInformation::Id, ecosystemInformationBasicAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr),
DECLARE_DYNAMIC_CLUSTER(AdministratorCommissioning::Id, AdministratorCommissioningAttrs, ZAP_CLUSTER_MASK(SERVER),
administratorCommissioningCommands, nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END;

Expand Down
5 changes: 5 additions & 0 deletions examples/fabric-bridge-app/linux/RpcServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "pw_rpc_system_server/rpc_server.h"
#include "pw_rpc_system_server/socket.h"

#include <app/clusters/ecosystem-information-server/ecosystem-information-server.h>
#include <lib/core/CHIPError.h>

#include <string>
Expand Down Expand Up @@ -62,6 +63,10 @@ pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice
return pw::Status::Unknown();
}

CHIP_ERROR err = EcosystemInformation::EcosystemInformationServer::Instance().AddEcosystemInformationClusterToEndpoint(
device->GetEndpointId());
VerifyOrDie(err == CHIP_NO_ERROR);

return pw::OkStatus();
}

Expand Down
11 changes: 10 additions & 1 deletion examples/fabric-bridge-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <app/AttributeAccessInterfaceRegistry.h>
#include <app/CommandHandlerInterfaceRegistry.h>
#include <app/clusters/ecosystem-information-server/ecosystem-information-server.h>

#if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE
#include "RpcClient.h"
Expand All @@ -35,8 +36,15 @@
#include <sys/ioctl.h>
#include <thread>

using namespace chip;
// This is declared here and not in a header because zap/embr assumes all clusters
// are defined in a static endpoint in the .zap file. From there, the codegen will
// automatically use PluginApplicationCallbacksHeader.jinja to declare and call
// the respective Init callbacks. However, because EcosystemInformation cluster is only
// ever on a dynamic endpoint, this doesn't get declared and called for us, so we
// need to declare and call it ourselves where the application is initialized.
void MatterEcosystemInformationPluginServerInitCallback();

using namespace chip;
using namespace chip::app;
using namespace chip::app::Clusters;
using namespace chip::app::Clusters::AdministratorCommissioning;
Expand Down Expand Up @@ -177,6 +185,7 @@ void ApplicationInit()
{
ChipLogDetail(NotSpecified, "Fabric-Bridge: ApplicationInit()");

MatterEcosystemInformationPluginServerInitCallback();
CommandHandlerInterfaceRegistry::RegisterCommandHandler(&gAdministratorCommissioningCommandHandler);
registerAttributeAccessOverride(&gBridgedDeviceBasicInformationAttributes);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ EcosystemInformationServer & EcosystemInformationServer::Instance()
return mInstance;
}

CHIP_ERROR EcosystemInformationServer::AddEcosystemInformationClusterToEndpoint(EndpointId aEndpoint)
{
VerifyOrReturnError((aEndpoint != kRootEndpointId && aEndpoint != kInvalidEndpointId), CHIP_ERROR_INVALID_ARGUMENT);
auto it = mDevicesMap.find(aEndpoint);
// We expect that the device has not been previously added.
VerifyOrReturnError((it == mDevicesMap.end()), CHIP_ERROR_INCORRECT_STATE);
// This create an empty DeviceInfo in mDevicesMap.
mDevicesMap[aEndpoint] = DeviceInfo();
return CHIP_NO_ERROR;
}

CHIP_ERROR EcosystemInformationServer::AddDeviceInfo(EndpointId aEndpoint, std::unique_ptr<EcosystemDeviceStruct> aDevice)
{
VerifyOrReturnError(aDevice, CHIP_ERROR_INVALID_ARGUMENT);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,24 @@ class EcosystemInformationServer
public:
static EcosystemInformationServer & Instance();

/**
* @brief Add EcosystemInformation Cluster to endpoint so we respond appropriately on endpoint
*
* EcosystemInformation cluster is only ever on dynamic bridge endpoint. If cluster is added
* to a new endpoint, but does not contain any ecosystem information presently,
* this is called to let ECOINFO cluster code know it is supposed to provide blank attribute
* information on this endpoint.
*
* This approach was intentionally taken instead of relying on emberAfDeviceTypeListFromEndpoint
* to keep this cluster more unit testable. This does add burden to application but is worth
* the trade-off.
*
* @param[in] aEndpoint Which endpoint is the device being added to the device directory.
* @return #CHIP_NO_ERROR on success.
* @return Other CHIP_ERROR associated with issue.
*/
CHIP_ERROR AddEcosystemInformationClusterToEndpoint(EndpointId aEndpoint);

/**
* @brief Adds device as entry to DeviceDirectory list Attribute.
*
Expand Down Expand Up @@ -187,7 +205,7 @@ class EcosystemInformationServer
private:
struct DeviceInfo
{
Optional<uint64_t> mRemovedOn;
Optional<uint64_t> mRemovedOn = NullOptional;
std::vector<std::unique_ptr<EcosystemDeviceStruct>> mDeviceDirectory;
// Map key is using the UniqueLocationId
std::map<std::string, std::unique_ptr<EcosystemLocationStruct>> mLocationDirectory;
Expand Down

0 comments on commit e8186eb

Please sign in to comment.