17
17
18
18
#pragma once
19
19
20
+ #include < app/CommandHandler.h>
21
+ #include < app/CommandHandlerExchangeInterface.h>
20
22
#include < app/StatusResponse.h>
21
23
#include < messaging/ExchangeHolder.h>
22
24
#include < system/SystemPacketBuffer.h>
23
25
24
26
namespace chip {
25
27
namespace app {
26
28
27
- typedef void (*OnResponseSenderDone)(void * context);
28
- class CommandHandler ;
29
-
29
+ // TODO(#30453): Rename CommandResponseSender to CommandResponder in follow up PR
30
30
/* *
31
- * Class manages the process of sending `InvokeResponseMessage`(s) back to the initial requester.
31
+ * Manages the process of sending InvokeResponseMessage(s) to the requester.
32
+ *
33
+ * Implements the CommandHandlerExchangeInterface. Uses a CommandHandler member to process
34
+ * InvokeCommandRequest. The CommandHandler is provided a reference to this
35
+ * CommandHandlerExchangeInterface implementation to enable sending InvokeResponseMessage(s).
32
36
*/
33
- class CommandResponseSender : public Messaging ::ExchangeDelegate
37
+ class CommandResponseSender : public Messaging ::ExchangeDelegate,
38
+ public CommandHandler::Callback,
39
+ public CommandHandlerExchangeInterface
34
40
{
35
41
public:
36
- CommandResponseSender () : mExchangeCtx (*this ) {}
42
+ class Callback
43
+ {
44
+ public:
45
+ virtual ~Callback () = default ;
46
+ /*
47
+ * Signals registered callback that this object has finished its work and can now be
48
+ * safely destroyed/released.
49
+ */
50
+ virtual void OnDone (CommandResponseSender & apResponderObj) = 0;
51
+ };
52
+
53
+ CommandResponseSender (Callback * apCallback, CommandHandler::Callback * apDispatchCallback) :
54
+ mpCallback (apCallback), mpCommandHandlerCallback(apDispatchCallback), mCommandHandler (this ), mExchangeCtx (*this )
55
+ {}
37
56
38
57
CHIP_ERROR OnMessageReceived (Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader,
39
58
System::PacketBufferHandle && payload) override ;
40
59
41
60
void OnResponseTimeout (Messaging::ExchangeContext * ec) override ;
42
61
62
+ void OnDone (CommandHandler & apCommandObj) override ;
63
+
64
+ void DispatchCommand (CommandHandler & apCommandObj, const ConcreteCommandPath & aCommandPath,
65
+ TLV::TLVReader & apPayload) override ;
66
+
67
+ Protocols::InteractionModel::Status CommandExists (const ConcreteCommandPath & aCommandPath) override ;
68
+
43
69
/* *
44
70
* Gets the inner exchange context object, without ownership.
45
71
*
@@ -51,115 +77,116 @@ class CommandResponseSender : public Messaging::ExchangeDelegate
51
77
* exchange context has been assigned or the context
52
78
* has been released.
53
79
*/
54
- Messaging::ExchangeContext * GetExchangeContext () const { return mExchangeCtx .Get (); }
55
-
56
- /* *
57
- * @brief Flush acks right now, typically done when processing a slow command
58
- */
59
- void FlushAcksRightNow ()
60
- {
61
- VerifyOrReturn (mExchangeCtx );
62
- auto * msgContext = mExchangeCtx ->GetReliableMessageContext ();
63
- VerifyOrReturn (msgContext != nullptr );
64
- msgContext->FlushAcks ();
65
- }
80
+ Messaging::ExchangeContext * GetExchangeContext () const override { return mExchangeCtx .Get (); }
66
81
67
82
/* *
68
83
* Gets subject descriptor of the exchange.
69
84
*
70
85
* WARNING: This method should only be called when the caller is certain the
71
86
* session has not been evicted.
72
87
*/
73
- Access::SubjectDescriptor GetSubjectDescriptor () const
88
+ Access::SubjectDescriptor GetSubjectDescriptor () const override
74
89
{
75
90
VerifyOrDie (mExchangeCtx );
76
91
return mExchangeCtx ->GetSessionHandle ()->GetSubjectDescriptor ();
77
92
}
78
93
79
- bool HasSessionHandle () { return mExchangeCtx && mExchangeCtx ->HasSessionHandle (); }
80
-
81
- FabricIndex GetAccessingFabricIndex () const
94
+ FabricIndex GetAccessingFabricIndex () const override
82
95
{
83
96
VerifyOrDie (mExchangeCtx );
84
97
return mExchangeCtx ->GetSessionHandle ()->GetFabricIndex ();
85
98
}
86
99
87
- void SetExchangeContext (Messaging::ExchangeContext * ec) { mExchangeCtx .Grab (ec); }
88
-
89
- void WillSendMessage () { mExchangeCtx ->WillSendMessage (); }
90
-
91
- bool IsForGroup ()
100
+ Optional<GroupId> GetGroupId () const override
92
101
{
93
102
VerifyOrDie (mExchangeCtx );
94
- return mExchangeCtx ->IsGroupExchangeContext ();
103
+ auto sessionHandle = mExchangeCtx ->GetSessionHandle ();
104
+ if (sessionHandle->GetSessionType () != Transport::Session::SessionType::kGroupIncoming )
105
+ {
106
+ return NullOptional;
107
+ }
108
+ return MakeOptional (sessionHandle->AsIncomingGroupSession ()->GetGroupId ());
95
109
}
96
110
97
- bool HasExchangeContext () { return mExchangeCtx .Get () != nullptr ; }
98
-
99
- GroupId GetGroupId ()
100
- {
101
- VerifyOrDie (mExchangeCtx );
102
- return mExchangeCtx ->GetSessionHandle ()->AsIncomingGroupSession ()->GetGroupId ();
103
- }
104
-
105
- /* *
106
- * @brief Initiates the sending of InvokeResponses previously queued using AddInvokeResponseToSend.
107
- *
108
- * Upon failure, the caller is responsible for closing the exchange appropriately, potentially
109
- * by calling `SendStatusResponse`.
110
- */
111
- CHIP_ERROR StartSendingCommandResponses ();
112
-
113
- void SendStatusResponse (Protocols::InteractionModel::Status aStatus)
111
+ void HandlingSlowCommand () override
114
112
{
115
- StatusResponse::Send (aStatus, mExchangeCtx .Get (), /* aExpectResponse = */ false );
113
+ VerifyOrReturn (mExchangeCtx );
114
+ auto * msgContext = mExchangeCtx ->GetReliableMessageContext ();
115
+ VerifyOrReturn (msgContext != nullptr );
116
+ msgContext->FlushAcks ();
116
117
}
117
118
118
- bool AwaitingStatusResponse () { return mState == State::AwaitingStatusResponse; }
119
-
120
- void AddInvokeResponseToSend (System::PacketBufferHandle && aPacket)
119
+ void AddInvokeResponseToSend (System::PacketBufferHandle && aPacket) override
121
120
{
122
121
VerifyOrDie (mState == State::ReadyForInvokeResponses);
123
122
mChunks .AddToEnd (std::move (aPacket));
124
123
}
125
124
126
- /* *
127
- * @brief Called to indicate that response was dropped
125
+ void ResponseDropped () override { mReportResponseDropped = true ; }
126
+
127
+ /*
128
+ * Main entrypoint for this class to handle an invoke request.
129
+ *
130
+ * isTimedInvoke is true if and only if this is part of a Timed Invoke
131
+ * transaction (i.e. was preceded by a Timed Request). If we reach here,
132
+ * the timer verification has already been done.
128
133
*/
129
- void ResponseDropped () { mReportResponseDropped = true ; }
134
+ void OnInvokeCommandRequest (Messaging::ExchangeContext * ec, System::PacketBufferHandle && payload, bool isTimedInvoke);
130
135
136
+ #if CHIP_WITH_NLFAULTINJECTION
131
137
/* *
132
- * @brief Registers a callback to be invoked when CommandResponseSender has finished sending responses.
138
+ * @brief Sends InvokeResponseMessages with injected faults for certification testing.
139
+ *
140
+ * The Test Harness (TH) uses this to simulate various server response behaviors,
141
+ * ensuring the Device Under Test (DUT) handles responses per specification.
142
+ *
143
+ * This function strictly validates the DUT's InvokeRequestMessage against the test plan.
144
+ * If deviations occur, the TH terminates with a detailed error message.
145
+ *
146
+ * @param ec Exchange context for sending InvokeResponseMessages to the client.
147
+ * @param payload Payload of the incoming InvokeRequestMessage from the client.
148
+ * @param isTimedInvoke Indicates whether the interaction is timed.
149
+ * @param faultType The specific type of fault to inject into the response.
133
150
*/
134
- void RegisterOnResponseSenderDoneCallback (Callback::Callback<OnResponseSenderDone> * aResponseSenderDoneCallback)
135
- {
136
- VerifyOrDie (!mCloseCalled );
137
- mResponseSenderDoneCallback = aResponseSenderDoneCallback;
138
- }
151
+ void TestOnlyInvokeCommandRequestWithFaultsInjected (Messaging::ExchangeContext * ec, System::PacketBufferHandle && payload,
152
+ bool isTimedInvoke, CommandHandler::NlFaultInjectionType faultType);
153
+ #endif // CHIP_WITH_NLFAULTINJECTION
139
154
140
155
private:
141
156
enum class State : uint8_t
142
157
{
143
- ReadyForInvokeResponses, // /< Accepting InvokeResponses to send back to requester.
144
- AwaitingStatusResponse, // /< Awaiting status response from requester, after sending InvokeResponse.
145
- AllInvokeResponsesSent, // /< All InvokeResponses have been sent out.
158
+ ReadyForInvokeResponses, // /< Accepting InvokeResponses to send back to requester.
159
+ AwaitingStatusResponse, // /< Awaiting status response from requester, after sending InvokeResponse.
160
+ AllInvokeResponsesSent, // /< All InvokeResponses have been sent out.
161
+ ErrorSentDelayCloseUntilOnDone // /< We have sent an early error response, but still need to clean up.
146
162
};
147
163
148
164
void MoveToState (const State aTargetState);
149
165
const char * GetStateStr () const ;
150
166
167
+ /* *
168
+ * @brief Initiates the sending of InvokeResponses previously queued using AddInvokeResponseToSend.
169
+ */
170
+ void StartSendingCommandResponses ();
171
+
172
+ void SendStatusResponse (Protocols::InteractionModel::Status aStatus)
173
+ {
174
+ StatusResponse::Send (aStatus, mExchangeCtx .Get (), /* aExpectResponse = */ false );
175
+ }
176
+
151
177
CHIP_ERROR SendCommandResponse ();
152
178
bool HasMoreToSend () { return !mChunks .IsNull () || mReportResponseDropped ; }
153
179
void Close ();
154
180
155
181
// A list of InvokeResponseMessages to be sent out by CommandResponseSender.
156
182
System::PacketBufferHandle mChunks ;
157
183
158
- chip::Callback::Callback<OnResponseSenderDone> * mResponseSenderDoneCallback = nullptr ;
184
+ Callback * mpCallback;
185
+ CommandHandler::Callback * mpCommandHandlerCallback;
186
+ CommandHandler mCommandHandler ;
159
187
Messaging::ExchangeHolder mExchangeCtx ;
160
188
State mState = State::ReadyForInvokeResponses;
161
189
162
- bool mCloseCalled = false ;
163
190
bool mReportResponseDropped = false ;
164
191
};
165
192
0 commit comments