Skip to content

Commit

Permalink
Added shutdown and finish methods in scenetable and scenes-server to …
Browse files Browse the repository at this point in the history
…ensure memory is released
  • Loading branch information
lpbeliveau-silabs committed Jun 15, 2023
1 parent 1f2999f commit 27b8699
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 43 deletions.
70 changes: 30 additions & 40 deletions src/app/clusters/on-off-server/on-off-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ static bool LevelControlWithOnOffFeaturePresent(EndpointId endpoint)
}
#endif // EMBER_AF_PLUGIN_LEVEL_CONTROL

static constexpr size_t kOnOffMaxEnpointCount =
EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;

static EmberEventControl sceneHandlerEventControls[kOnOffMaxEnpointCount];

#ifdef EMBER_AF_PLUGIN_SCENES
static void sceneOnOffCallback(EndpointId endpoint);

Expand Down Expand Up @@ -144,7 +149,7 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl
}

uint16_t mPairCount;
EndpointStatePair mStatePairBuffer[MAX_ENDPOINT_COUNT];
EndpointStatePair mStatePairBuffer[kOnOffMaxEnpointCount];
};

StatePairBuffer mSceneEndpointStatePairs;
Expand Down Expand Up @@ -181,7 +186,6 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl
using AttributeValuePair = Scenes::Structs::AttributeValuePair::Type;

bool currentValue;

// read current on/off value
EmberAfStatus status = Attributes::OnOff::Get(endpoint, &currentValue);
if (status != EMBER_ZCL_STATUS_SUCCESS)
Expand All @@ -191,23 +195,13 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl
}

AttributeValuePair Pairs[scenableAttributeCount];

Pairs[0].attributeID.SetValue(Attributes::OnOff::Id);
Pairs[0].attributeValue = currentValue;

app::DataModel::List<const AttributeValuePair> attributeValueList(Pairs);

TLV::TLVWriter writer;
TLV::TLVType outer;
// Serialize Extension Field sets in a way consistent with the default Deserialize method from SceneTableImpl.h
writer.Init(serializedBytes);
ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outer));
ReturnErrorOnFailure(app::DataModel::Encode(
writer, TLV::ContextTag(to_underlying(Scenes::Structs::ExtensionFieldSet::Fields::kAttributeValueList)),
attributeValueList));
ReturnErrorOnFailure(writer.EndContainer(outer));
serializedBytes.reduce_size(writer.GetLengthWritten());
app::DataModel::List<AttributeValuePair> attributeValueList(Pairs);

return CHIP_NO_ERROR;
return EncodeAttributeValueList(attributeValueList, serializedBytes);
}

/// @brief Default EFS interaction when applying scene to the OnOff Cluster
Expand All @@ -221,21 +215,11 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl
{
app::DataModel::DecodableList<Scenes::Structs::AttributeValuePair::DecodableType> attributeValueList;

TLV::TLVReader reader;
TLV::TLVType outer;

size_t attributeCount = 0;

VerifyOrReturnError(cluster == OnOff::Id, CHIP_ERROR_INVALID_ARGUMENT);

reader.Init(serializedBytes);
ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()));
ReturnErrorOnFailure(reader.EnterContainer(outer));
ReturnErrorOnFailure(reader.Next(
TLV::kTLVType_Array, TLV::ContextTag(app::Clusters::Scenes::Structs::ExtensionFieldSet::Fields::kAttributeValueList)));
ReturnErrorOnFailure(attributeValueList.Decode(reader));
ReturnErrorOnFailure(reader.ExitContainer(outer));
ReturnErrorOnFailure(DecodeAttributeValueList(serializedBytes, attributeValueList));

size_t attributeCount = 0;
ReturnErrorOnFailure(attributeValueList.ComputeSize(&attributeCount));
VerifyOrReturnError(attributeCount <= scenableAttributeCount, CHIP_ERROR_BUFFER_TOO_SMALL);

Expand All @@ -252,7 +236,12 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl
mSceneEndpointStatePairs.InsertPair(EndpointStatePair(endpoint, static_cast<bool>(decodePair.attributeValue))));
}
// Verify that the EFS was completely read
ReturnErrorOnFailure(pair_iterator.GetStatus());
CHIP_ERROR err = pair_iterator.GetStatus();
if (CHIP_NO_ERROR != err)
{
mSceneEndpointStatePairs.RemovePair(endpoint);
return err;
}

OnOffServer::Instance().scheduleTimerCallbackMs(sceneEventControl(endpoint), timeMs);

Expand All @@ -268,7 +257,8 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl
*/
EmberEventControl * sceneEventControl(EndpointId endpoint)
{
EmberEventControl * controller = OnOffServer::Instance().getEventControl(endpoint);
EmberEventControl * controller =
OnOffServer::Instance().getEventControl(endpoint, sceneHandlerEventControls, ArraySize(sceneHandlerEventControls));
VerifyOrReturnValue(controller != nullptr, nullptr);

controller->endpoint = endpoint;
Expand All @@ -295,9 +285,6 @@ static void sceneOnOffCallback(EndpointId endpoint)

static OnOffEffect * firstEffect = nullptr;
OnOffServer OnOffServer::instance;

static constexpr size_t kOnOffMaxEnpointCount =
EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT;
static EmberEventControl gEventControls[kOnOffMaxEnpointCount];

/**********************************************************
Expand Down Expand Up @@ -333,7 +320,7 @@ void OnOffServer::cancelEndpointTimerCallback(EmberEventControl * control)

void OnOffServer::cancelEndpointTimerCallback(EndpointId endpoint)
{
auto control = OnOffServer::getEventControl(endpoint);
auto control = OnOffServer::getEventControl(endpoint, gEventControls, ArraySize(gEventControls));
if (control)
{
cancelEndpointTimerCallback(control);
Expand Down Expand Up @@ -440,7 +427,7 @@ EmberAfStatus OnOffServer::setOnOffValue(chip::EndpointId endpoint, chip::Comman
Attributes::OffWaitTime::Set(endpoint, 0);

// Stop timer on the endpoint
EmberEventControl * event = getEventControl(endpoint);
EmberEventControl * event = getEventControl(endpoint, gEventControls, ArraySize(gEventControls));
if (event != nullptr)
{
cancelEndpointTimerCallback(event);
Expand Down Expand Up @@ -881,7 +868,7 @@ void OnOffServer::updateOnOffTimeCommand(chip::EndpointId endpoint)
ChipLogProgress(Zcl, "Timer Callback - wait Off Time cycle finished");

// Stop timer on the endpoint
cancelEndpointTimerCallback(getEventControl(endpoint));
cancelEndpointTimerCallback(getEventControl(endpoint, gEventControls, ArraySize(gEventControls)));
}
}
}
Expand All @@ -897,17 +884,20 @@ bool OnOffServer::areStartUpOnOffServerAttributesNonVolatile(EndpointId endpoint
/**
* @brief event control object for an endpoint
*
* @param[in] endpoint
* @param[in] endpoint target endpoint
* @param[in] eventControlArray Array where to find the event control
* @param[in] eventControlArraySize Size of the event control array
* @return EmberEventControl* configured event control
*/
EmberEventControl * OnOffServer::getEventControl(EndpointId endpoint)
EmberEventControl * OnOffServer::getEventControl(chip::EndpointId endpoint, EmberEventControl * eventControlArray,
size_t eventControlArraySize)
{
uint16_t index = emberAfGetClusterServerEndpointIndex(endpoint, OnOff::Id, EMBER_AF_ON_OFF_CLUSTER_SERVER_ENDPOINT_COUNT);
if (index >= ArraySize(gEventControls))
if (index >= eventControlArraySize)
{
return nullptr;
}
return &gEventControls[index];
return &eventControlArray[index];
}

/**
Expand All @@ -918,7 +908,7 @@ EmberEventControl * OnOffServer::getEventControl(EndpointId endpoint)
*/
EmberEventControl * OnOffServer::configureEventControl(EndpointId endpoint)
{
EmberEventControl * controller = getEventControl(endpoint);
EmberEventControl * controller = getEventControl(endpoint, gEventControls, ArraySize(gEventControls));
VerifyOrReturnError(controller != nullptr, nullptr);

controller->endpoint = endpoint;
Expand Down
3 changes: 2 additions & 1 deletion src/app/clusters/on-off-server/on-off-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ class OnOffServer
#ifndef IGNORE_ON_OFF_CLUSTER_START_UP_ON_OFF
bool areStartUpOnOffServerAttributesNonVolatile(chip::EndpointId endpoint);
#endif
EmberEventControl * getEventControl(chip::EndpointId endpoint);
EmberEventControl * getEventControl(chip::EndpointId endpoint, EmberEventControl * eventControlArray,
size_t eventControlArraySize);
EmberEventControl * configureEventControl(chip::EndpointId endpoint);

uint32_t calculateNextWaitTimeMS(void);
Expand Down
2 changes: 1 addition & 1 deletion src/app/clusters/scenes-server/SceneTableImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class DefaultSceneTableImpl : public SceneTable<scenes::ExtensionFieldSetsImpl>
public:
DefaultSceneTableImpl() {}

~DefaultSceneTableImpl() override {}
~DefaultSceneTableImpl() override { Finish(); }

CHIP_ERROR Init(PersistentStorageDelegate * storage) override;
void Finish() override;
Expand Down
2 changes: 1 addition & 1 deletion src/app/clusters/scenes-server/scenes-server.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class ScenesServer : public CommandHandlerInterface, public AttributeAccessInter

private:
ScenesServer() : CommandHandlerInterface(Optional<EndpointId>(), Id), AttributeAccessInterface(Optional<EndpointId>(), Id) {}
~ScenesServer() {}
~ScenesServer() { Shutdown(); }

bool mIsInitialized = false;

Expand Down

0 comments on commit 27b8699

Please sign in to comment.