Skip to content

Commit

Permalink
[attribute storage] apply suggestions from PR review
Browse files Browse the repository at this point in the history
  • Loading branch information
plan44 committed Oct 14, 2024
1 parent 87259f0 commit 40c48f2
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 7 deletions.
29 changes: 24 additions & 5 deletions src/app/util/attribute-storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ uint16_t emberAfGetDynamicIndexFromEndpoint(EndpointId id)
return kEmberInvalidEndpointIndex;
}

namespace {

const EmberAfCluster * getClusterTypeDefinition(EndpointId endpointId, ClusterId clusterId, EmberAfClusterMask mask)
{
uint16_t index = emberAfIndexFromEndpointIncludingDisabledEndpoints(endpointId);
Expand All @@ -272,27 +274,44 @@ const EmberAfCluster * getClusterTypeDefinition(EndpointId endpointId, ClusterId
return nullptr;
}

CHIP_ERROR setupDynamicEndpointDeclaration(EmberAfEndpointType & endpointType, EndpointId templateEndpointId,
const Span<const ClusterId> & templateClusterIds)
} // anonymous namespace

void emberAfSetupDynamicEndpointDeclaration(EmberAfEndpointType & endpointType, EndpointId templateEndpointId,
const Span<const ClusterId> & templateClusterIds)
{
// allocate cluster list
endpointType.clusterCount = static_cast<uint8_t>(templateClusterIds.size());
size_t clusterCount = templateClusterIds.size();
VerifyOrDieWithMsg(clusterCount <= 255, Support, "max 255 clusters per endpoint!");
endpointType.clusterCount = static_cast<uint8_t>(clusterCount);
endpointType.cluster = new EmberAfCluster[endpointType.clusterCount];
endpointType.endpointSize = 0;
// get the actual cluster pointers and sum up memory size
for (size_t i = 0; i < templateClusterIds.size(); i++)
{
auto cluster = getClusterTypeDefinition(templateEndpointId, templateClusterIds.data()[i], 0);
auto cluster = getClusterTypeDefinition(templateEndpointId, templateClusterIds[i], 0); // 0 = not filtered by a mask
VerifyOrDieWithMsg(cluster, Support, "cluster 0x%04x template in endpoint %u does not exist",
(unsigned int) templateClusterIds.data()[i], (unsigned int) templateEndpointId);
// for now, we need to copy the cluster definition, unfortunately.
// TODO: make endpointType use a pointer to a list of EmberAfCluster* instead, so we can re-use cluster definitions
// instead of duplicating them here once for every instance.
// Note: we cannot struct assignment here, because cluster in EmberAfEndpointType is const due
// to the way static cluster code generation works. So we have to resort to memcpy as a workaround
// until the much more intrusive changes as suggested by the TODO above can be applied.
memcpy((void *) &endpointType.cluster[i], cluster, sizeof(EmberAfCluster));
// sum up the needed storage
endpointType.endpointSize = (uint16_t) (endpointType.endpointSize + cluster->clusterSize);
}
return CHIP_NO_ERROR;
}

void emberAfResetDynamicEndpointDeclaration(EmberAfEndpointType & endpointType)
{
if (endpointType.cluster)
{
delete[] endpointType.cluster;
endpointType.cluster = nullptr;
}
endpointType.clusterCount = 0;
endpointType.endpointSize = 0;
}

CHIP_ERROR emberAfSetDynamicEndpoint(uint16_t index, EndpointId id, const EmberAfEndpointType * ep,
Expand Down
26 changes: 24 additions & 2 deletions src/app/util/attribute-storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,30 @@ void emberAfEndpointConfigure();
// metadata including all attributes already exists and can be re-used this way,
// without error prone manual duplicating with DECLARE_DYNAMIC_*
//
CHIP_ERROR setupDynamicEndpointDeclaration(EmberAfEndpointType & endpointType, chip::EndpointId templateEndpointId,
const chip::Span<const chip::ClusterId> & templateClusterIds);
// templateEndpointId specifies a endpoint which is usually disabled, but containing
// cluster definitions that should be used for instantiating active endpoints.
//
// templateClusterIds is a list of clusterIds to be used for the new endpoint.
//
// endpointType will be setup with the specified clusters and their storage size so
// it can be used in a subsequent call to emberAfSetDynamicEndpoint instead of
// an endpoint manually constructed with DECLARE_DYNAMIC_*.
//
// Note: passing invalid templateEndpointId/templateClusterIds combinations, i.e. clusters
// not present in the specified template endpoint, will cause the function will die with
// an error message as this indicates severe internal inconsistency of the setup.
//
// Note: function may allocate memory for the endpoint declaration.
// Use emberAfResetEndpointDeclaration to properly dispose of an endpoint declaration.
void emberAfSetupDynamicEndpointDeclaration(EmberAfEndpointType & endpointType, chip::EndpointId templateEndpointId,
const chip::Span<const chip::ClusterId> & templateClusterIds);

// reset an endpoint declaration that was setup with emberAfSetupDynamicEndpointDeclaration
// to free all extra memory that might have been allocated.
//
// Warning: passing endpoint declarations that are not set up with
// emberAfSetupDynamicEndpointDeclaration is NOT allowed and likely causes undefined crashes.
void emberAfResetDynamicEndpointDeclaration(EmberAfEndpointType & endpointType);

// Register a dynamic endpoint. This involves registering descriptors that describe
// the composition of the endpoint (encapsulated in the 'ep' argument) as well as providing
Expand Down

0 comments on commit 40c48f2

Please sign in to comment.