Skip to content

Commit 3625917

Browse files
yufengwangcabzbarsky-apple
authored andcommitted
Refactor exchange usage in IM to improve cirque stability (#6730)
* Refactor exhange usage in IM to improve cirque stability * Update src/app/ReadClient.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Update src/app/CommandSender.cpp Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> * Rename ClearExistingExchangeContext to AbortExistingExchangeContext Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
1 parent 50ca6ca commit 3625917

8 files changed

+44
-34
lines changed

scripts/tests/cirque_tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ OT_SIMULATION_CACHE="$CIRQUE_CACHE_PATH/ot-simulation.tgz"
3636
CIRQUE_TESTS=(
3737
"EchoTest"
3838
"MobileDeviceTest"
39-
"InteractionModel"
39+
"InteractionModelTest"
4040
)
4141

4242
BOLD_GREEN_TEXT="\033[1;32m"

src/app/Command.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ CHIP_ERROR Command::Init(Messaging::ExchangeManager * apExchangeMgr, Interaction
3737
// Error if already initialized.
3838
VerifyOrExit(apExchangeMgr != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
3939
VerifyOrExit(mpExchangeMgr == nullptr, err = CHIP_ERROR_INCORRECT_STATE);
40-
VerifyOrExit(mpExchangeCtx == nullptr, err = CHIP_ERROR_INCORRECT_STATE);
4140

4241
mpExchangeMgr = apExchangeMgr;
4342
mpDelegate = apDelegate;
@@ -53,7 +52,7 @@ CHIP_ERROR Command::Reset()
5352
{
5453
CHIP_ERROR err = CHIP_NO_ERROR;
5554
CommandList::Builder commandListBuilder;
56-
ClearExistingExchangeContext();
55+
AbortExistingExchangeContext();
5756

5857
if (mCommandMessageBuf.IsNull())
5958
{
@@ -133,7 +132,7 @@ void Command::Shutdown()
133132
mCommandMessageWriter.Reset();
134133
mCommandMessageBuf = nullptr;
135134

136-
ClearExistingExchangeContext();
135+
AbortExistingExchangeContext();
137136

138137
mpExchangeMgr = nullptr;
139138
mpDelegate = nullptr;
@@ -213,7 +212,7 @@ CHIP_ERROR Command::ConstructCommandPath(const CommandPathParams & aCommandPathP
213212
return commandPath.GetError();
214213
}
215214

216-
CHIP_ERROR Command::ClearExistingExchangeContext()
215+
CHIP_ERROR Command::AbortExistingExchangeContext()
217216
{
218217
// Discard any existing exchange context. Effectively we can only have one Echo exchange with
219218
// a single node at any one time.

src/app/Command.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class Command
119119
virtual CHIP_ERROR ProcessCommandDataElement(CommandDataElement::Parser & aCommandElement) = 0;
120120

121121
protected:
122-
CHIP_ERROR ClearExistingExchangeContext();
122+
CHIP_ERROR AbortExistingExchangeContext();
123123
void MoveToState(const CommandState aTargetState);
124124
CHIP_ERROR ProcessCommandMessage(System::PacketBufferHandle && payload, CommandRoleId aCommandRoleId);
125125
CHIP_ERROR ConstructCommandPath(const CommandPathParams & aCommandPathParams, CommandDataElement::Builder aCommandDataElement);

src/app/CommandSender.cpp

+14-16
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ CHIP_ERROR CommandSender::SendCommandRequest(NodeId aNodeId, Transport::AdminId
4141
err = FinalizeCommandsMessage();
4242
SuccessOrExit(err);
4343

44-
ClearExistingExchangeContext();
44+
// Discard any existing exchange context. Effectively we can only have one exchange per CommandSender
45+
// at any one time.
46+
AbortExistingExchangeContext();
4547

4648
// Create a new exchange context.
4749
// TODO: temprary create a SecureSessionHandle from node id, will be fix in PR 3602
@@ -59,7 +61,7 @@ CHIP_ERROR CommandSender::SendCommandRequest(NodeId aNodeId, Transport::AdminId
5961
exit:
6062
if (err != CHIP_NO_ERROR)
6163
{
62-
ClearExistingExchangeContext();
64+
AbortExistingExchangeContext();
6365
}
6466
ChipLogFunctError(err);
6567

@@ -70,27 +72,23 @@ void CommandSender::OnMessageReceived(Messaging::ExchangeContext * apExchangeCon
7072
const PayloadHeader & aPayloadHeader, System::PacketBufferHandle aPayload)
7173
{
7274
CHIP_ERROR err = CHIP_NO_ERROR;
73-
// Assert that the exchange context matches the client's current context.
74-
// This should never fail because even if SendCommandRequest is called
75-
// back-to-back, the second call will call Close() on the first exchange,
76-
// which clears the OnMessageReceived callback.
7775

78-
VerifyOrDie(apExchangeContext == mpExchangeCtx);
79-
80-
// Verify that the message is an Invoke Command Response.
81-
// If not, close the exchange and free the payload.
82-
if (!aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::InvokeCommandResponse))
83-
{
84-
apExchangeContext->Close();
85-
mpExchangeCtx = nullptr;
86-
goto exit;
87-
}
76+
VerifyOrExit(apExchangeContext == mpExchangeCtx, err = CHIP_ERROR_INCORRECT_STATE);
77+
VerifyOrExit(aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::InvokeCommandResponse),
78+
err = CHIP_ERROR_INVALID_MESSAGE_TYPE);
8879

8980
err = ProcessCommandMessage(std::move(aPayload), CommandRoleId::SenderId);
9081
SuccessOrExit(err);
9182

9283
exit:
84+
ChipLogFunctError(err);
85+
86+
// Close the exchange cleanly so that the ExchangeManager will send an ack for the message we just received.
87+
// This needs to be done before the Reset() call, because Reset() aborts mpExchangeCtx if its not null.
88+
mpExchangeCtx->Close();
89+
mpExchangeCtx = nullptr;
9390
Reset();
91+
9492
if (mpDelegate != nullptr)
9593
{
9694
if (err != CHIP_NO_ERROR)

src/app/ReadClient.cpp

+21-8
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,21 @@ CHIP_ERROR ReadClient::Init(Messaging::ExchangeManager * apExchangeMgr, Interact
3434
// Error if already initialized.
3535
VerifyOrExit(apExchangeMgr != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
3636
VerifyOrExit(mpExchangeMgr == nullptr, err = CHIP_ERROR_INCORRECT_STATE);
37-
VerifyOrExit(mpExchangeCtx == nullptr, err = CHIP_ERROR_INCORRECT_STATE);
3837

3938
mpExchangeMgr = apExchangeMgr;
40-
mpExchangeCtx = nullptr;
4139
mpDelegate = apDelegate;
4240
mState = ClientState::Initialized;
4341

42+
AbortExistingExchangeContext();
43+
4444
exit:
4545
ChipLogFunctError(err);
4646
return err;
4747
}
4848

4949
void ReadClient::Shutdown()
5050
{
51-
ClearExistingExchangeContext();
51+
AbortExistingExchangeContext();
5252
mpExchangeMgr = nullptr;
5353
mpDelegate = nullptr;
5454
MoveToState(ClientState::Uninitialized);
@@ -88,7 +88,10 @@ CHIP_ERROR ReadClient::SendReadRequest(NodeId aNodeId, Transport::AdminId aAdmin
8888
InteractionModelEngine::GetInstance()->GetReadClientArrayIndex(this), GetStateStr());
8989
VerifyOrExit(ClientState::Initialized == mState, err = CHIP_ERROR_INCORRECT_STATE);
9090
VerifyOrExit(mpDelegate != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
91-
VerifyOrExit(mpExchangeCtx == nullptr, err = CHIP_ERROR_INCORRECT_STATE);
91+
92+
// Discard any existing exchange context. Effectively we can only have one exchange per ReadClient
93+
// at any one time.
94+
AbortExistingExchangeContext();
9295

9396
{
9497
System::PacketBufferTLVWriter writer;
@@ -175,23 +178,33 @@ CHIP_ERROR ReadClient::SendReadRequest(NodeId aNodeId, Transport::AdminId aAdmin
175178

176179
exit:
177180
ChipLogFunctError(err);
181+
182+
if (err != CHIP_NO_ERROR)
183+
{
184+
AbortExistingExchangeContext();
185+
}
186+
178187
return err;
179188
}
180189

181190
void ReadClient::OnMessageReceived(Messaging::ExchangeContext * apExchangeContext, const PacketHeader & aPacketHeader,
182191
const PayloadHeader & aPayloadHeader, System::PacketBufferHandle aPayload)
183192
{
184193
CHIP_ERROR err = CHIP_NO_ERROR;
194+
195+
VerifyOrExit(apExchangeContext == mpExchangeCtx, err = CHIP_ERROR_INCORRECT_STATE);
185196
VerifyOrExit(aPayloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::ReportData),
186197
err = CHIP_ERROR_INVALID_MESSAGE_TYPE);
187-
VerifyOrExit(apExchangeContext == mpExchangeCtx, err = CHIP_ERROR_INCORRECT_STATE);
188198
err = ProcessReportData(std::move(aPayload));
189199

190200
exit:
191201
ChipLogFunctError(err);
192202

193-
ClearExistingExchangeContext();
203+
// Close the exchange cleanly so that the ExchangeManager will send an ack for the message we just received.
204+
mpExchangeCtx->Close();
205+
mpExchangeCtx = nullptr;
194206
MoveToState(ClientState::Initialized);
207+
195208
if (mpDelegate != nullptr)
196209
{
197210
if (err != CHIP_NO_ERROR)
@@ -207,7 +220,7 @@ void ReadClient::OnMessageReceived(Messaging::ExchangeContext * apExchangeContex
207220
return;
208221
}
209222

210-
CHIP_ERROR ReadClient::ClearExistingExchangeContext()
223+
CHIP_ERROR ReadClient::AbortExistingExchangeContext()
211224
{
212225
if (mpExchangeCtx != nullptr)
213226
{
@@ -302,7 +315,7 @@ void ReadClient::OnResponseTimeout(Messaging::ExchangeContext * apExchangeContex
302315
{
303316
ChipLogProgress(DataManagement, "Time out! failed to receive report data from Exchange: %d",
304317
apExchangeContext->GetExchangeId());
305-
ClearExistingExchangeContext();
318+
AbortExistingExchangeContext();
306319
MoveToState(ClientState::Initialized);
307320
if (nullptr != mpDelegate)
308321
{

src/app/ReadClient.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class ReadClient : public Messaging::ExchangeDelegate
115115

116116
void MoveToState(const ClientState aTargetState);
117117
CHIP_ERROR ProcessReportData(System::PacketBufferHandle aPayload);
118-
CHIP_ERROR ClearExistingExchangeContext();
118+
CHIP_ERROR AbortExistingExchangeContext();
119119
const char * GetStateStr() const;
120120

121121
Messaging::ExchangeManager * mpExchangeMgr = nullptr;

src/app/ReadHandler.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ void ReadHandler::Shutdown()
5252
{
5353
InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpAttributeClusterInfoList);
5454
InteractionModelEngine::GetInstance()->ReleaseClusterInfoList(mpEventClusterInfoList);
55-
ClearExistingExchangeContext();
55+
AbortExistingExchangeContext();
5656
MoveToState(HandlerState::Uninitialized);
5757
mpDelegate = nullptr;
5858
mpAttributeClusterInfoList = nullptr;
5959
mpEventClusterInfoList = nullptr;
6060
mCurrentPriority = PriorityLevel::Invalid;
6161
}
6262

63-
CHIP_ERROR ReadHandler::ClearExistingExchangeContext()
63+
CHIP_ERROR ReadHandler::AbortExistingExchangeContext()
6464
{
6565
if (mpExchangeCtx != nullptr)
6666
{

src/app/ReadHandler.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class ReadHandler
128128
void MoveToState(const HandlerState aTargetState);
129129

130130
const char * GetStateStr() const;
131-
CHIP_ERROR ClearExistingExchangeContext();
131+
CHIP_ERROR AbortExistingExchangeContext();
132132

133133
Messaging::ExchangeContext * mpExchangeCtx = nullptr;
134134
InteractionModelDelegate * mpDelegate = nullptr;

0 commit comments

Comments
 (0)