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

[controller] Use short lived CommandSender when no command sender is provided #7041

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -33,71 +33,116 @@ namespace Controller {
// OnOff Cluster Commands
CHIP_ERROR OnOffCluster::Off(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);
CHIP_ERROR err = CHIP_NO_ERROR;
app::CommandSender * sender = nullptr;
TLV::TLVWriter * writer = nullptr;
uint8_t argSeqNumber = 0;

if (mpCommandSender == nullptr)
{
ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&mpCommandSender));
}
// Used when encoding non-empty command. Suppress error message when encoding empty commands.
(void) writer;
(void) argSeqNumber;

VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOffCommandId,
(chip::app::CommandPathFlags::kEndpointIdValid) };
ReturnErrorOnFailure(mpCommandSender->PrepareCommand(&cmdParams));

SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

SuccessOrExit(err = sender->PrepareCommand(&cmdParams));

// Command takes no arguments.

ReturnErrorOnFailure(mpCommandSender->FinishCommand());
SuccessOrExit(err = sender->FinishCommand());

// #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
mDevice->AddIMResponseHandler(mpCommandSender, onSuccessCallback, onFailureCallback);
mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

err = mDevice->SendCommands(sender);

return mDevice->SendCommands(mpCommandSender);
exit:
// On error, we are responsible to close the sender.
if (err != CHIP_NO_ERROR && sender != nullptr)
{
sender->Shutdown();
}
return err;
}

CHIP_ERROR OnOffCluster::On(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);
CHIP_ERROR err = CHIP_NO_ERROR;
app::CommandSender * sender = nullptr;
TLV::TLVWriter * writer = nullptr;
uint8_t argSeqNumber = 0;

if (mpCommandSender == nullptr)
{
ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&mpCommandSender));
}
// Used when encoding non-empty command. Suppress error message when encoding empty commands.
(void) writer;
(void) argSeqNumber;

VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kOnCommandId,
(chip::app::CommandPathFlags::kEndpointIdValid) };
ReturnErrorOnFailure(mpCommandSender->PrepareCommand(&cmdParams));

SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

SuccessOrExit(err = sender->PrepareCommand(&cmdParams));

// Command takes no arguments.

ReturnErrorOnFailure(mpCommandSender->FinishCommand());
SuccessOrExit(err = sender->FinishCommand());

// #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
mDevice->AddIMResponseHandler(mpCommandSender, onSuccessCallback, onFailureCallback);
mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

return mDevice->SendCommands(mpCommandSender);
err = mDevice->SendCommands(sender);

exit:
// On error, we are responsible to close the sender.
if (err != CHIP_NO_ERROR && sender != nullptr)
{
sender->Shutdown();
}
return err;
}

CHIP_ERROR OnOffCluster::Toggle(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback)
{
VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);
CHIP_ERROR err = CHIP_NO_ERROR;
app::CommandSender * sender = nullptr;
TLV::TLVWriter * writer = nullptr;
uint8_t argSeqNumber = 0;

if (mpCommandSender == nullptr)
{
ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&mpCommandSender));
}
// Used when encoding non-empty command. Suppress error message when encoding empty commands.
(void) writer;
(void) argSeqNumber;

VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, kToggleCommandId,
(chip::app::CommandPathFlags::kEndpointIdValid) };
ReturnErrorOnFailure(mpCommandSender->PrepareCommand(&cmdParams));

SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

SuccessOrExit(err = sender->PrepareCommand(&cmdParams));

// Command takes no arguments.

ReturnErrorOnFailure(mpCommandSender->FinishCommand());
SuccessOrExit(err = sender->FinishCommand());

// #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
mDevice->AddIMResponseHandler(mpCommandSender, onSuccessCallback, onFailureCallback);
mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

return mDevice->SendCommands(mpCommandSender);
err = mDevice->SendCommands(sender);

exit:
// On error, we are responsible to close the sender.
if (err != CHIP_NO_ERROR && sender != nullptr)
{
sender->Shutdown();
}
return err;
}

// OnOff Cluster Attributes
Expand Down
2 changes: 2 additions & 0 deletions src/app/CommandSender.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class CommandSender : public Command, public Messaging::ExchangeDelegate
{
public:
// TODO: issue #6792 - the secure session parameter should be made non-optional and passed by reference.
// If SendCommandRequest finished with success, the caller should drop the reference of the CommandSender, and no longer holds
// the ownership of CommandSender.
CHIP_ERROR SendCommandRequest(NodeId aNodeId, Transport::AdminId aAdminId, SecureSessionHandle * secureSession = nullptr);

void OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PacketHeader & aPacketHeader,
Expand Down
38 changes: 26 additions & 12 deletions src/app/zap-templates/templates/app/CHIPClusters-src.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,48 @@ namespace Controller {
{{#chip_server_cluster_commands}}
CHIP_ERROR {{asCamelCased clusterName false}}Cluster::{{asCamelCased name false}}(Callback::Cancelable * onSuccessCallback, Callback::Cancelable * onFailureCallback{{#chip_server_cluster_command_arguments}}, {{chipType}} {{asCamelCased label}}{{/chip_server_cluster_command_arguments}})
{
VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);
CHIP_ERROR err = CHIP_NO_ERROR;
app::CommandSender * sender = nullptr;
TLV::TLVWriter * writer = nullptr;
uint8_t argSeqNumber = 0;

if (mpCommandSender == nullptr)
{
ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&mpCommandSender));
}
// Used when encoding non-empty command. Suppress error message when encoding empty commands.
(void) writer;
(void) argSeqNumber;
erjiaqing marked this conversation as resolved.
Show resolved Hide resolved

VerifyOrReturnError(mDevice != nullptr, CHIP_ERROR_INCORRECT_STATE);

app::CommandPathParams cmdParams = { mEndpoint, /* group id */ 0, mClusterId, k{{asCamelCased name false}}CommandId,
(chip::app::CommandPathFlags::kEndpointIdValid) };
ReturnErrorOnFailure(mpCommandSender->PrepareCommand(&cmdParams));

SuccessOrExit(err = chip::app::InteractionModelEngine::GetInstance()->NewCommandSender(&sender));

SuccessOrExit(err = sender->PrepareCommand(&cmdParams));

{{#chip_server_cluster_command_arguments}}
{{#first}}
TLV::TLVWriter * writer = mpCommandSender->GetCommandDataElementTLVWriter();
uint8_t argSeqNumber = 0;
VerifyOrExit((writer = sender->GetCommandDataElementTLVWriter()) != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
{{/first}}
// {{asCamelCased label}}: {{asCamelCased type}}
ReturnErrorOnFailure(writer->Put(TLV::ContextTag(argSeqNumber++), {{asCamelCased label}}));
SuccessOrExit(err = writer->Put(TLV::ContextTag(argSeqNumber++), {{asCamelCased label}}));
{{else}}
// Command takes no arguments.
{{/chip_server_cluster_command_arguments}}

ReturnErrorOnFailure(mpCommandSender->FinishCommand());
SuccessOrExit(err = sender->FinishCommand());

// #6308: This is a temporary solution before we fully support IM on application side and should be replaced by IMDelegate.
mDevice->AddIMResponseHandler(mpCommandSender, onSuccessCallback, onFailureCallback);
mDevice->AddIMResponseHandler(sender, onSuccessCallback, onFailureCallback);

err = mDevice->SendCommands(sender);

return mDevice->SendCommands(mpCommandSender);
exit:
// On error, we are responsible to close the sender.
if (err != CHIP_NO_ERROR && sender != nullptr)
{
sender->Shutdown();
}
return err;
}

{{/chip_server_cluster_commands}}
Expand Down
10 changes: 4 additions & 6 deletions src/controller/CHIPCluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,20 @@
namespace chip {
namespace Controller {

CHIP_ERROR ClusterBase::Associate(Device * device, EndpointId endpoint, app::CommandSender * commandSender)
CHIP_ERROR ClusterBase::Associate(Device * device, EndpointId endpoint)
{
CHIP_ERROR err = CHIP_NO_ERROR;
// TODO: Check if the device supports mCluster at the requested endpoint

mDevice = device;
mEndpoint = endpoint;
mpCommandSender = commandSender;
mDevice = device;
mEndpoint = endpoint;

return err;
}

void ClusterBase::Dissociate()
{
mDevice = nullptr;
mpCommandSender = nullptr;
mDevice = nullptr;
}

CHIP_ERROR ClusterBase::SendCommand(uint8_t seqNum, chip::System::PacketBufferHandle && payload,
Expand Down
3 changes: 1 addition & 2 deletions src/controller/CHIPCluster.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class DLL_EXPORT ClusterBase
public:
virtual ~ClusterBase() {}

CHIP_ERROR Associate(Device * device, EndpointId endpoint, app::CommandSender * commandSender = nullptr);
CHIP_ERROR Associate(Device * device, EndpointId endpoint);

void Dissociate();

Expand Down Expand Up @@ -73,7 +73,6 @@ class DLL_EXPORT ClusterBase

const ClusterId mClusterId;
Device * mDevice;
app::CommandSender * mpCommandSender = nullptr;
EndpointId mEndpoint;
};

Expand Down
Loading