Skip to content
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

[ON-OFF] Increase the size of the onoff cluster's eventControl array to handl… #26254

Merged
merged 8 commits into from
May 16, 2023
6 changes: 4 additions & 2 deletions src/app/clusters/on-off-server/on-off-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ using chip::Protocols::InteractionModel::Status;
static OnOffEffect * firstEffect = nullptr;
OnOffServer OnOffServer::instance;

static EmberEventControl gEventControls[EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT];
static constexpr size_t kOnOffMaxEnpointCount =
EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
static EmberEventControl gEventControls[kOnOffMaxEnpointCount];
jmartinez-silabs marked this conversation as resolved.
Show resolved Hide resolved

/**********************************************************
* Function definition
Expand Down Expand Up @@ -652,7 +654,7 @@ bool OnOffServer::areStartUpOnOffServerAttributesNonVolatile(EndpointId endpoint
*/
EmberEventControl * OnOffServer::getEventControl(EndpointId endpoint)
{
uint16_t index = emberAfFindClusterServerEndpointIndex(endpoint, OnOff::Id);
uint16_t index = emberAfGetClusterServerEndpointIndex(endpoint, OnOff::Id, EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT);
if (index >= ArraySize(gEventControls))
{
return nullptr;
Expand Down
42 changes: 42 additions & 0 deletions src/app/util/af.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,48 @@ uint16_t emberAfIndexFromEndpointIncludingDisabledEndpoints(chip::EndpointId end
*/
uint16_t emberAfFindClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId clusterId);

/**
* @brief Returns the index of the given endpoint in the list of all endpoints that might support the given cluster server.
*
* Returns kEmberInvalidEndpointIndex if the given endpoint does not support the
* given cluster or if the given endpoint is disabled.
*
* Unlike emberAfFindClusterServerEndpointIndex, this function always returns the same index
* for a given endpointId instance, fixed or dynamic, if it does not return kEmberInvalidEndpointIndex.
*
* The return index is identical to emberAfFindClusterServerEndpointIndex for fixed endpoints,
* but for dynamic endpoints the indexing assumes that any dynamic endpoint could start supporting
* the given server cluster.
*
* For example, if a device has 4 fixed endpoints (ids 0-3) and 2 dynamic
* endpoints, and cluster X is supported on endpoints 1 and 3, then
* fixedClusterServerEndpointCount should be 2 and
*
* 1) emberAfGetClusterServerEndpointIndex(0, X) returns kEmberInvalidEndpointIndex
* 2) emberAfGetClusterServerEndpointIndex(1, X) returns 0
* 3) emberAfGetClusterServerEndpointIndex(2, X) returns kEmberInvalidEndpointIndex
* 4) emberAfGetClusterServerEndpointIndex(3, X) returns 1

* The Dynamic endpoints are placed after the fixed ones;
* therefore their return index will always be >= to fixedClusterServerEndpointCount
*
* If a dynamic endpoint, supporting cluster X, is defined to dynamic index 1 with endpoint id 7,
* (via emberAfSetDynamicEndpoint(1, 7, ...))
* then emberAfGetClusterServerEndpointIndex(7, X) returns 3 (fixedClusterServerEndpointCount{2} + DynamicEndpointIndex {1}).
*
* If now a second dynamic endpoint, also supporting cluster X, is defined to dynamic index 0
* with endpoint id 9 (via emberAfSetDynamicEndpoint(0, 9, ...)),
* emberAfGetClusterServerEndpointIndex(9, X) returns 2. (fixedClusterServerEndpointCount{2} + DynamicEndpointIndex {0}).
* and emberAfGetClusterServerEndpointIndex(7, X) still returns 3
*
* @param endpoint Endpoint number
* @param cluster Id the of the Cluster server you are interrested on
* @param fixedClusterServerEndpointCount The number of fixed endpoints containing this cluster server. Typically one of the
EMBER_AF_*_CLUSTER_SERVER_ENDPOINT_COUNT constants.
*/
uint16_t emberAfGetClusterServerEndpointIndex(chip::EndpointId endpoint, chip::ClusterId cluster,
uint16_t fixedClusterServerEndpointCount);

/**
* @brief Returns the total number of endpoints (dynamic and pre-compiled).
*/
Expand Down
47 changes: 47 additions & 0 deletions src/app/util/attribute-storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,53 @@ static uint16_t findIndexFromEndpoint(EndpointId endpoint, bool ignoreDisabledEn
return kEmberInvalidEndpointIndex;
}

uint16_t emberAfGetClusterServerEndpointIndex(EndpointId endpoint, ClusterId cluster, uint16_t fixedClusterServerEndpointCount)
{
VerifyOrDie(fixedClusterServerEndpointCount <= FIXED_ENDPOINT_COUNT);
uint16_t epIndex = findIndexFromEndpoint(endpoint, true /*ignoreDisabledEndpoints*/);
jmartinez-silabs marked this conversation as resolved.
Show resolved Hide resolved

// Endpoint must be configured and enabled
if (epIndex == kEmberInvalidEndpointIndex)
{
return kEmberInvalidEndpointIndex;
}

if (emberAfFindClusterInType(emAfEndpoints[epIndex].endpointType, cluster, CLUSTER_MASK_SERVER) == nullptr)
{
// The provided endpoint does not contain the given cluster server.
return kEmberInvalidEndpointIndex;
}

if (epIndex < FIXED_ENDPOINT_COUNT)
{
// This endpoint is a fixed one.
// Return the index of this endpoint in the list of fixed endpoints that support the given cluster.
uint16_t adjustedEndpointIndex = 0;
for (uint16_t i = 0; i < epIndex; i++)
{
// Increase adjustedEndpointIndex for every endpoint containing the cluster server
// before our endpoint of interest
if (emAfEndpoints[i].endpoint != kInvalidEndpointId &&
(emberAfFindClusterInType(emAfEndpoints[i].endpointType, cluster, CLUSTER_MASK_SERVER) != nullptr))
{
adjustedEndpointIndex++;
}
}

// If this asserts, the provided fixedClusterServerEndpointCount doesn't match the app data model.
VerifyOrDie(adjustedEndpointIndex < fixedClusterServerEndpointCount);
epIndex = adjustedEndpointIndex;
}
else
{
// This is a dynamic endpoint.
// Its index is just its index in the dynamic endpoint list, offset by fixedClusterServerEndpointCount.
epIndex = static_cast<uint16_t>(fixedClusterServerEndpointCount + (epIndex - FIXED_ENDPOINT_COUNT));
}

return epIndex;
}

bool emberAfEndpointIsEnabled(EndpointId endpoint)
{
uint16_t index = findIndexFromEndpoint(endpoint,
Expand Down