@@ -39,9 +39,9 @@ CHIP_ERROR CommandResponseSender::OnMessageReceived(Messaging::ExchangeContext *
39
39
VerifyOrExit (err == CHIP_NO_ERROR, failureStatusToSend.SetValue (Status::InvalidAction));
40
40
41
41
err = SendCommandResponse ();
42
- // If SendCommandResponse() fails, we must still close the exchange. Since sending an
43
- // InvokeResponseMessage seems problematic, we'll send a StatusResponse with 'Failure'
44
- // instead .
42
+ // If SendCommandResponse() fails, we must close the exchange. We signal the failure to the
43
+ // requester with a StatusResponse ('Failure'). Since we're in the middle of processing an
44
+ // incoming message, we close the exchange by indicating that we don't expect a further response .
45
45
VerifyOrExit (err == CHIP_NO_ERROR, failureStatusToSend.SetValue (Status::Failure));
46
46
47
47
bool moreToSend = !mChunks .IsNull ();
@@ -76,8 +76,6 @@ void CommandResponseSender::OnResponseTimeout(Messaging::ExchangeContext * apExc
76
76
{
77
77
ChipLogDetail (DataManagement, " CommandResponseSender: Timed out waiting for response from requester mState=[%10.10s]" ,
78
78
GetStateStr ());
79
- // We don't need to consider remaining async CommandHandlers here. We become the exchange
80
- // delegate only after CommandHandler::OnDone is called.
81
79
Close ();
82
80
}
83
81
@@ -99,9 +97,9 @@ void CommandResponseSender::StartSendingCommandResponses()
99
97
// {
100
98
// SendStatusResponse(Status::Failure);
101
99
// }
102
- // Close();
103
- // return;
104
100
// ```
101
+ Close ();
102
+ return ;
105
103
}
106
104
107
105
if (HasMoreToSend ())
@@ -115,6 +113,31 @@ void CommandResponseSender::StartSendingCommandResponses()
115
113
}
116
114
}
117
115
116
+ void CommandResponseSender::OnDone (CommandHandler & apCommandObj)
117
+ {
118
+ if (mState == State::ErrorSentDelayCloseUntilOnDone)
119
+ {
120
+ // We have already sent a message to the client indicating that we are not expecting
121
+ // a response.
122
+ Close ();
123
+ return ;
124
+ }
125
+ StartSendingCommandResponses ();
126
+ }
127
+
128
+ void CommandResponseSender::DispatchCommand (CommandHandler & apCommandObj, const ConcreteCommandPath & aCommandPath,
129
+ TLV::TLVReader & apPayload)
130
+ {
131
+ VerifyOrReturn (mpCommandHandlerCallback);
132
+ mpCommandHandlerCallback->DispatchCommand (apCommandObj, aCommandPath, apPayload);
133
+ }
134
+
135
+ Status CommandResponseSender::CommandExists (const ConcreteCommandPath & aCommandPath)
136
+ {
137
+ VerifyOrReturnValue (mpCommandHandlerCallback, Protocols::InteractionModel::Status::UnsupportedCommand);
138
+ return mpCommandHandlerCallback->CommandExists (aCommandPath);
139
+ }
140
+
118
141
CHIP_ERROR CommandResponseSender::SendCommandResponse ()
119
142
{
120
143
VerifyOrReturnError (HasMoreToSend (), CHIP_ERROR_INCORRECT_STATE);
@@ -153,6 +176,9 @@ const char * CommandResponseSender::GetStateStr() const
153
176
154
177
case State::AllInvokeResponsesSent:
155
178
return " AllInvokeResponsesSent" ;
179
+
180
+ case State::ErrorSentDelayCloseUntilOnDone:
181
+ return " ErrorSentDelayCloseUntilOnDone" ;
156
182
}
157
183
#endif // CHIP_DETAIL_LOGGING
158
184
return " N/A" ;
@@ -185,8 +211,8 @@ void CommandResponseSender::OnInvokeCommandRequest(Messaging::ExchangeContext *
185
211
mExchangeCtx .Grab (ec);
186
212
mExchangeCtx ->WillSendMessage ();
187
213
188
- // Grabbing Handle to prevent OnDone from being called before OnInvokeCommandRequest returns.
189
- // This allows us to send a StatusResponse error instead of the queued up InvokeResponseMessages.
214
+ // Grabbing Handle to prevent mCommandHandler from calling OnDone before OnInvokeCommandRequest returns.
215
+ // This allows us to send a StatusResponse error instead of any potentially queued up InvokeResponseMessages.
190
216
CommandHandler::Handle workHandle (&mCommandHandler );
191
217
Status status = mCommandHandler .OnInvokeCommandRequest (*this , std::move (payload), isTimedInvoke);
192
218
if (status != Status::Success)
@@ -196,7 +222,7 @@ void CommandResponseSender::OnInvokeCommandRequest(Messaging::ExchangeContext *
196
222
// The API contract of OnInvokeCommandRequest requires the CommandResponder instance to outlive
197
223
// the CommandHandler. Therefore, we cannot safely call Close() here, even though we have
198
224
// finished sending data. Closing must be deferred until the CommandHandler::OnDone callback.
199
- mDelayCallingCloseUntilOnDone = true ;
225
+ MoveToState (State::ErrorSentDelayCloseUntilOnDone) ;
200
226
}
201
227
}
202
228
0 commit comments