Skip to content

Commit

Permalink
Add CommandResponseStatus, CommandResponseProtocolError, and CommandR…
Browse files Browse the repository at this point in the history
…esponseError Callback in IM delegate (project-chip#5477)

Problems:
Consumer SDK need to get to know the status code when invoke command
response has status code inside, and also need to know error when sender
fails to process command element and response timeout

Summary of Changes:
-- After receive status code from invoke command reponse, command sender
notify this status code via CommandStatus callback to Consumer SDK.
-- When response timeout happens, notify the timeout error
to consumer sdk.
-- When command element fails to process, notify the protocol error to
consuder sdk
  • Loading branch information
yunhanw-google authored Mar 30, 2021
1 parent 281ecea commit d925b47
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 18 deletions.
10 changes: 7 additions & 3 deletions src/app/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
namespace chip {
namespace app {

CHIP_ERROR Command::Init(Messaging::ExchangeManager * apExchangeMgr)
CHIP_ERROR Command::Init(Messaging::ExchangeManager * apExchangeMgr, InteractionModelDelegate * apDelegate)
{
CHIP_ERROR err = CHIP_NO_ERROR;
// Error if already initialized.
Expand All @@ -40,8 +40,8 @@ CHIP_ERROR Command::Init(Messaging::ExchangeManager * apExchangeMgr)
VerifyOrExit(mpExchangeCtx == nullptr, err = CHIP_ERROR_INCORRECT_STATE);

mpExchangeMgr = apExchangeMgr;

err = Reset();
mpDelegate = apDelegate;
err = Reset();
SuccessOrExit(err);

exit:
Expand Down Expand Up @@ -69,6 +69,8 @@ CHIP_ERROR Command::Reset()
mInvokeCommandBuilder.CreateCommandListBuilder();
MoveToState(CommandState::Initialized);

mCommandIndex = 0;

exit:
ChipLogFunctError(err);

Expand Down Expand Up @@ -134,8 +136,10 @@ void Command::Shutdown()
ClearExistingExchangeContext();

mpExchangeMgr = nullptr;
mpDelegate = nullptr;
MoveToState(CommandState::Uninitialized);

mCommandIndex = 0;
exit:
return;
}
Expand Down
6 changes: 5 additions & 1 deletion src/app/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <system/SystemPacketBuffer.h>
#include <system/TLVPacketBufferBackingStore.h>

#include <app/InteractionModelDelegate.h>
#include <app/MessageDef/CommandDataElement.h>
#include <app/MessageDef/CommandList.h>
#include <app/MessageDef/InvokeCommand.h>
Expand Down Expand Up @@ -92,13 +93,14 @@ class Command
* instance.
*
* @param[in] apExchangeMgr A pointer to the ExchangeManager object.
* @param[in] apDelegate InteractionModelDelegate set by application.
*
* @retval #CHIP_ERROR_INCORRECT_STATE If the state is not equal to
* CommandState::NotInitialized.
* @retval #CHIP_NO_ERROR On success.
*
*/
CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr);
CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr, InteractionModelDelegate * apDelegate);

/**
* Shutdown the CommandSender. This terminates this instance
Expand Down Expand Up @@ -147,7 +149,9 @@ class Command

Messaging::ExchangeManager * mpExchangeMgr = nullptr;
Messaging::ExchangeContext * mpExchangeCtx = nullptr;
InteractionModelDelegate * mpDelegate = nullptr;
chip::System::PacketBufferHandle mCommandMessageBuf;
uint8_t mCommandIndex = 0;

private:
chip::System::PacketBufferHandle mpBufHandle;
Expand Down
41 changes: 29 additions & 12 deletions src/app/CommandSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ void CommandSender::OnResponseTimeout(Messaging::ExchangeContext * apExchangeCon
ChipLogProgress(DataManagement, "Time out! failed to receive invoke command response from Exchange: %d",
apExchangeContext->GetExchangeId());
Reset();

if (mpDelegate != nullptr)
{
mpDelegate->CommandResponseTimeout(this);
}
}

CHIP_ERROR CommandSender::ProcessCommandDataElement(CommandDataElement::Parser & aCommandElement)
Expand All @@ -118,6 +123,20 @@ CHIP_ERROR CommandSender::ProcessCommandDataElement(CommandDataElement::Parser &
uint16_t protocolCode = 0;
StatusElement::Parser statusElementParser;

mCommandIndex++;

err = aCommandElement.GetCommandPath(&commandPath);
SuccessOrExit(err);

err = commandPath.GetClusterId(&clusterId);
SuccessOrExit(err);

err = commandPath.GetCommandId(&commandId);
SuccessOrExit(err);

err = commandPath.GetEndpointId(&endpointId);
SuccessOrExit(err);

err = aCommandElement.GetStatusElement(&statusElementParser);
if (CHIP_NO_ERROR == err)
{
Expand All @@ -127,21 +146,14 @@ CHIP_ERROR CommandSender::ProcessCommandDataElement(CommandDataElement::Parser &

err = statusElementParser.DecodeStatusElement(&generalCode, &protocolId, &protocolCode, &clusterId);
SuccessOrExit(err);
if (mpDelegate != nullptr)
{
mpDelegate->CommandResponseStatus(this, generalCode, protocolId, protocolCode, endpointId, clusterId, commandId,
mCommandIndex);
}
}
else if (CHIP_END_OF_TLV == err)
{
err = aCommandElement.GetCommandPath(&commandPath);
SuccessOrExit(err);

err = commandPath.GetClusterId(&clusterId);
SuccessOrExit(err);

err = commandPath.GetCommandId(&commandId);
SuccessOrExit(err);

err = commandPath.GetEndpointId(&endpointId);
SuccessOrExit(err);

err = aCommandElement.GetData(&commandDataReader);
if (CHIP_END_OF_TLV == err)
{
Expand All @@ -155,6 +167,11 @@ CHIP_ERROR CommandSender::ProcessCommandDataElement(CommandDataElement::Parser &
}

exit:
ChipLogFunctError(err);
if (err != CHIP_NO_ERROR && mpDelegate != nullptr)
{
mpDelegate->CommandResponseProtocolError(this, mCommandIndex);
}
return err;
}

Expand Down
43 changes: 43 additions & 0 deletions src/app/InteractionModelDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
namespace chip {
namespace app {
class ReadClient;
class CommandSender;
struct EventPathParams;

/**
Expand Down Expand Up @@ -75,6 +76,48 @@ class InteractionModelDelegate
*/
virtual CHIP_ERROR ReportError(const ReadClient * apReadClient, CHIP_ERROR aError) { return CHIP_ERROR_NOT_IMPLEMENTED; }

/**
* Notification that a Command Send has received an Invoke Command Response containing a status code.
* @param[in] apCommandSender A current command sender which can identify the command sender to the consumer, particularly
* during multiple command interactions
* @param[in] aGeneralCode Status code defined by the standard
* @param[in] aProtocolId Protocol Id
* @param[in] aProtocolCode Detailed error information, protocol-specific.
* @param[in] aEndpointId Endpoint identifier
* @param[in] aClusterId Cluster identifier
* @param[in] aCommandId Command identifier
* @param[in] aCommandIndex Current processing command index which can identify command if there exists multiple commands with
* same command Id
* @retval # CHIP_ERROR_NOT_IMPLEMENTED if not implemented
*/
virtual CHIP_ERROR CommandResponseStatus(const CommandSender * apCommandSender, const uint16_t aGeneralCode,
const uint32_t aProtocolId, const uint16_t aProtocolCode, chip::EndpointId aEndpointId,
const chip::ClusterId aClusterId, chip::CommandId aCommandId, uint8_t aCommandIndex)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

/**
* Notification that a Command Send has received an Invoke Command Response and fails to process a command data element in that
* command response
* @param[in] apCommandSender A current command sender which can identify the command sender to the consumer, particularly
* during multiple command interactions
* @param[in] aCommandIndex Current processing command index which can identify failed command
* @retval # CHIP_ERROR_NOT_IMPLEMENTED if not implemented
*/
virtual CHIP_ERROR CommandResponseProtocolError(const CommandSender * apCommandSender, uint8_t aCommandIndex)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
}

/**
* Notification that a command sender encountered an asynchronous failure.
* @param[in] apCommandSender A current command sender which can identify the command sender to the consumer, particularly
* during multiple command interactions
* @retval # CHIP_ERROR_NOT_IMPLEMENTED if not implemented
*/
virtual CHIP_ERROR CommandResponseTimeout(const CommandSender * apCommandSender) { return CHIP_ERROR_NOT_IMPLEMENTED; }

virtual ~InteractionModelDelegate() = default;
};

Expand Down
4 changes: 2 additions & 2 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ CHIP_ERROR InteractionModelEngine::NewCommandSender(CommandSender ** const apCom
if (commandSender.IsFree())
{
*apCommandSender = &commandSender;
err = commandSender.Init(mpExchangeMgr);
err = commandSender.Init(mpExchangeMgr, mpDelegate);
if (CHIP_NO_ERROR != err)
{
*apCommandSender = nullptr;
Expand Down Expand Up @@ -155,7 +155,7 @@ void InteractionModelEngine::OnInvokeCommandRequest(Messaging::ExchangeContext *
{
if (commandHandler.IsFree())
{
err = commandHandler.Init(mpExchangeMgr);
err = commandHandler.Init(mpExchangeMgr, mpDelegate);
SuccessOrExit(err);
commandHandler.OnMessageReceived(apExchangeContext, aPacketHeader, aPayloadHeader, std::move(aPayload));
apExchangeContext = nullptr;
Expand Down
22 changes: 22 additions & 0 deletions src/app/tests/integration/chip_im_initiator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,28 @@ class MockInteractionModelApp : public chip::app::InteractionModelDelegate
printf("ReportError with err %d", aError);
return CHIP_NO_ERROR;
}
CHIP_ERROR CommandResponseStatus(const chip::app::CommandSender * apCommandSender, const uint16_t aGeneralCode,
const uint32_t aProtocolId, const uint16_t aProtocolCode, const chip::EndpointId aEndpointId,
const chip::ClusterId aClusterId, const chip::CommandId aCommandId,
uint8_t aCommandIndex) override
{
printf("CommandResponseStatus with GeneralCode %d, ProtocolId %d, ProtocolCode %d, EndpointId %d, ClusterId %d, CommandId "
"%d, CommandIndex %d",
aGeneralCode, aProtocolId, aProtocolCode, aEndpointId, aClusterId, aCommandId, aCommandIndex);
return CHIP_NO_ERROR;
}

CHIP_ERROR CommandResponseProtocolError(const chip::app::CommandSender * apCommandSender, uint8_t aCommandIndex) override
{
printf("CommandResponseProtocolError happens with CommandIndex %d", aCommandIndex);
return CHIP_NO_ERROR;
}

CHIP_ERROR CommandResponseTimeout(const chip::app::CommandSender * apCommandSender) override
{
printf("CommandResponseTimeout happens");
return CHIP_NO_ERROR;
}
};

} // namespace
Expand Down

0 comments on commit d925b47

Please sign in to comment.