blob: 3971864bb7e06e259817fa16106fba8c848e77ee [file] [log] [blame]
Yufeng Wang4fc19f12020-10-22 16:14:32 -07001/*
2 *
Kevin Schoedel1b6a96b2021-02-10 14:29:33 -05003 * Copyright (c) 2020-2021 Project CHIP Authors
Yufeng Wang4fc19f12020-10-22 16:14:32 -07004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/**
19 * @file
20 * This file implements the ExchangeManager class.
21 *
22 */
23
Song Guo308b2a42020-10-28 14:25:49 +080024#include <cstring>
Yufeng Wang4fc19f12020-10-22 16:14:32 -070025#include <inttypes.h>
26#include <stddef.h>
27
Tennessee Carmel-Veilleux267951c2021-10-13 22:05:45 -040028#include <crypto/RandUtils.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080029#include <lib/core/CHIPCore.h>
30#include <lib/core/CHIPEncoding.h>
31#include <lib/support/CHIPFaultInjection.h>
32#include <lib/support/CodeUtils.h>
Zang MingJie53dd5832021-09-03 03:05:16 +080033#include <lib/support/logging/CHIPLogging.h>
Yufeng Wang4fc19f12020-10-22 16:14:32 -070034#include <messaging/ExchangeContext.h>
35#include <messaging/ExchangeMgr.h>
Yufeng Wangcb23e0c2021-01-07 12:36:21 -080036#include <protocols/Protocols.h>
Yufeng Wang4fc19f12020-10-22 16:14:32 -070037
38using namespace chip::Encoding;
39using namespace chip::Inet;
40using namespace chip::System;
41
42namespace chip {
Yufeng Wang01031e72020-12-01 09:57:42 -080043namespace Messaging {
Yufeng Wang4fc19f12020-10-22 16:14:32 -070044
45/**
46 * Constructor for the ExchangeManager class.
47 * It sets the state to kState_NotInitialized.
48 *
49 * @note
50 * The class must be initialized via ExchangeManager::Init()
51 * prior to use.
52 *
53 */
Zang MingJie6c9f1c52021-11-18 00:58:13 +080054ExchangeManager::ExchangeManager() : mReliableMessageMgr(mContextPool)
Yufeng Wang4fc19f12020-10-22 16:14:32 -070055{
56 mState = State::kState_NotInitialized;
57}
58
Zang MingJieeca9bff2021-09-23 03:19:51 +080059CHIP_ERROR ExchangeManager::Init(SessionManager * sessionManager)
Yufeng Wang4fc19f12020-10-22 16:14:32 -070060{
Yufeng Wanga9497732021-02-17 10:10:50 -080061 CHIP_ERROR err = CHIP_NO_ERROR;
62
63 VerifyOrReturnError(mState == State::kState_NotInitialized, err = CHIP_ERROR_INCORRECT_STATE);
Yufeng Wang4fc19f12020-10-22 16:14:32 -070064
Zang MingJieeca9bff2021-09-23 03:19:51 +080065 mSessionManager = sessionManager;
Yufeng Wang4fc19f12020-10-22 16:14:32 -070066
Tennessee Carmel-Veilleux267951c2021-10-13 22:05:45 -040067 mNextExchangeId = chip::Crypto::GetRandU16();
Zang MingJiea0db4492021-03-10 01:00:35 +080068 mNextKeyId = 0;
Yufeng Wang4fc19f12020-10-22 16:14:32 -070069
Damian Królik36dd75b2021-03-23 15:34:38 +010070 for (auto & handler : UMHandlerPool)
71 {
Boris Zbarsky01ce6aa2021-03-23 14:15:36 -040072 // Mark all handlers as unallocated. This handles both initial
73 // initialization and the case when the consumer shuts us down and
74 // then re-initializes without removing registered handlers.
Boris Zbarskyb8054db2021-03-25 14:46:17 -040075 handler.Reset();
Damian Królik36dd75b2021-03-23 15:34:38 +010076 }
Zang MingJiea0db4492021-03-10 01:00:35 +080077
Zang MingJie6c9f1c52021-11-18 00:58:13 +080078 sessionManager->SetMessageDelegate(this);
Yufeng Wang4fc19f12020-10-22 16:14:32 -070079
Zang MingJie4ec0e4e2021-12-02 15:20:06 +080080 mReliableMessageMgr.Init(sessionManager->SystemLayer());
Yufeng Wangcb23e0c2021-01-07 12:36:21 -080081
Yufeng Wang4fc19f12020-10-22 16:14:32 -070082 mState = State::kState_Initialized;
83
Yufeng Wanga9497732021-02-17 10:10:50 -080084 return err;
Yufeng Wang4fc19f12020-10-22 16:14:32 -070085}
86
Michael Spang63870492022-06-28 08:41:08 -040087void ExchangeManager::Shutdown()
Yufeng Wang4fc19f12020-10-22 16:14:32 -070088{
Michael Spang63870492022-06-28 08:41:08 -040089 VerifyOrReturn(mState != State::kState_NotInitialized);
Vivien Nicolas862f1702022-02-16 15:45:16 +010090
Kevin Schoedel1b6a96b2021-02-10 14:29:33 -050091 mReliableMessageMgr.Shutdown();
92
Zang MingJieeca9bff2021-09-23 03:19:51 +080093 if (mSessionManager != nullptr)
Yufeng Wang4fc19f12020-10-22 16:14:32 -070094 {
Zang MingJie6c9f1c52021-11-18 00:58:13 +080095 mSessionManager->SetMessageDelegate(nullptr);
Zang MingJieeca9bff2021-09-23 03:19:51 +080096 mSessionManager = nullptr;
Yufeng Wang4fc19f12020-10-22 16:14:32 -070097 }
98
Yufeng Wang4fc19f12020-10-22 16:14:32 -070099 mState = State::kState_NotInitialized;
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700100}
101
Jerry Johns55f90492022-08-29 01:14:05 -0400102ExchangeContext * ExchangeManager::NewContext(const SessionHandle & session, ExchangeDelegate * delegate, bool isInitiator)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700103{
Zang MingJie7d125dc2022-06-09 00:11:05 +0800104 if (!session->IsActiveSession())
105 {
106 // Disallow creating exchange on an inactive session
107 ChipLogError(ExchangeManager, "NewContext failed: session inactive");
108 return nullptr;
109 }
Jerry Johns55f90492022-08-29 01:14:05 -0400110 return mContextPool.CreateObject(this, mNextExchangeId++, session, isInitiator, delegate);
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700111}
112
Zang MingJied1512e52022-04-15 12:26:24 +0800113CHIP_ERROR ExchangeManager::RegisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId,
114 UnsolicitedMessageHandler * handler)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700115{
Zang MingJied1512e52022-04-15 12:26:24 +0800116 return RegisterUMH(protocolId, kAnyMessageType, handler);
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700117}
118
Boris Zbarskyf0b7f2b2021-03-22 12:32:13 -0400119CHIP_ERROR ExchangeManager::RegisterUnsolicitedMessageHandlerForType(Protocols::Id protocolId, uint8_t msgType,
Zang MingJied1512e52022-04-15 12:26:24 +0800120 UnsolicitedMessageHandler * handler)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700121{
Zang MingJied1512e52022-04-15 12:26:24 +0800122 return RegisterUMH(protocolId, static_cast<int16_t>(msgType), handler);
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700123}
124
Boris Zbarskyf0b7f2b2021-03-22 12:32:13 -0400125CHIP_ERROR ExchangeManager::UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700126{
127 return UnregisterUMH(protocolId, kAnyMessageType);
128}
129
Boris Zbarskyf0b7f2b2021-03-22 12:32:13 -0400130CHIP_ERROR ExchangeManager::UnregisterUnsolicitedMessageHandlerForType(Protocols::Id protocolId, uint8_t msgType)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700131{
132 return UnregisterUMH(protocolId, static_cast<int16_t>(msgType));
133}
134
Zang MingJied1512e52022-04-15 12:26:24 +0800135CHIP_ERROR ExchangeManager::RegisterUMH(Protocols::Id protocolId, int16_t msgType, UnsolicitedMessageHandler * handler)
Zang MingJie84586522021-01-27 02:05:37 +0800136{
Zang MingJied1512e52022-04-15 12:26:24 +0800137 UnsolicitedMessageHandlerSlot * selected = nullptr;
Zang MingJie84586522021-01-27 02:05:37 +0800138
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400139 for (auto & umh : UMHandlerPool)
Zang MingJie84586522021-01-27 02:05:37 +0800140 {
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400141 if (!umh.IsInUse())
Zang MingJie84586522021-01-27 02:05:37 +0800142 {
143 if (selected == nullptr)
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400144 selected = &umh;
Zang MingJie84586522021-01-27 02:05:37 +0800145 }
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400146 else if (umh.Matches(protocolId, msgType))
Zang MingJie84586522021-01-27 02:05:37 +0800147 {
Zang MingJied1512e52022-04-15 12:26:24 +0800148 umh.Handler = handler;
Zang MingJie84586522021-01-27 02:05:37 +0800149 return CHIP_NO_ERROR;
150 }
151 }
152
153 if (selected == nullptr)
154 return CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS;
155
Zang MingJied1512e52022-04-15 12:26:24 +0800156 selected->Handler = handler;
Zang MingJie84586522021-01-27 02:05:37 +0800157 selected->ProtocolId = protocolId;
158 selected->MessageType = msgType;
159
160 SYSTEM_STATS_INCREMENT(chip::System::Stats::kExchangeMgr_NumUMHandlers);
161
162 return CHIP_NO_ERROR;
163}
164
Boris Zbarskyf0b7f2b2021-03-22 12:32:13 -0400165CHIP_ERROR ExchangeManager::UnregisterUMH(Protocols::Id protocolId, int16_t msgType)
Zang MingJie84586522021-01-27 02:05:37 +0800166{
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400167 for (auto & umh : UMHandlerPool)
Zang MingJie84586522021-01-27 02:05:37 +0800168 {
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400169 if (umh.IsInUse() && umh.Matches(protocolId, msgType))
Zang MingJie84586522021-01-27 02:05:37 +0800170 {
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400171 umh.Reset();
Zang MingJie84586522021-01-27 02:05:37 +0800172 SYSTEM_STATS_DECREMENT(chip::System::Stats::kExchangeMgr_NumUMHandlers);
173 return CHIP_NO_ERROR;
174 }
175 }
176
177 return CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER;
178}
179
180void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
Zang MingJie40842bf2022-04-22 00:28:36 +0800181 const SessionHandle & session, DuplicateMessage isDuplicate,
182 System::PacketBufferHandle && msgBuf)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700183{
Zang MingJied1512e52022-04-15 12:26:24 +0800184 UnsolicitedMessageHandlerSlot * matchingUMH = nullptr;
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700185
Jerry Johns94412892022-09-13 16:33:36 -0400186#if CHIP_PROGRESS_LOGGING
187 auto * protocolName = Protocols::GetProtocolName(payloadHeader.GetProtocolID());
188 auto * msgTypeName = Protocols::GetMessageTypeName(payloadHeader.GetProtocolID(), payloadHeader.GetMessageType());
189
190 //
191 // 32-bit value maximum = 10 chars + text preamble (6) + trailer (1) + null (1) + 2 buffer = 20
192 //
193 char ackBuf[20];
194 ackBuf[0] = '\0';
195 if (payloadHeader.GetAckMessageCounter().HasValue())
196 {
197 snprintf(ackBuf, sizeof(ackBuf), " (Ack:" ChipLogFormatMessageCounter ")", payloadHeader.GetAckMessageCounter().Value());
198 }
199
200 CompressedFabricId compressedFabricId = 0;
201 if (session->IsSecureSession() && mSessionManager->GetFabricTable() != nullptr)
202 {
203 auto fabricInfo = mSessionManager->GetFabricTable()->FindFabricWithIndex(session->AsSecureSession()->GetFabricIndex());
204 if (fabricInfo)
205 {
206 compressedFabricId = fabricInfo->GetCompressedFabricId();
207 }
208 }
209
210 //
211 // Legend that can be used to decode this log line can be found in README.md
212 //
Boris Zbarskyf7c51272021-09-22 10:22:31 -0400213 ChipLogProgress(ExchangeManager,
Boris Zbarskyc77dbde2023-02-08 11:00:38 -0500214 ">>> [E:" ChipLogFormatExchangeId " S:%u M:" ChipLogFormatMessageCounter
215 "%s] (%s) Msg RX from %u:" ChipLogFormatX64 " [%04X] --- Type %04x:%02x (%s:%s)",
216 ChipLogValueExchangeIdFromReceivedHeader(payloadHeader), session->SessionIdForLogging(),
217 packetHeader.GetMessageCounter(), ackBuf, Transport::GetSessionTypeString(session), session->GetFabricIndex(),
Jerry Johns94412892022-09-13 16:33:36 -0400218 ChipLogValueX64(session->GetPeer().GetNodeId()), static_cast<uint16_t>(compressedFabricId),
219 payloadHeader.GetProtocolID().GetProtocolId(), payloadHeader.GetMessageType(), protocolName, msgTypeName);
220#endif
shana-apple3907f382021-05-05 08:50:42 +0200221
Pankaj Garg48ed12b2021-06-28 10:07:30 -0700222 MessageFlags msgFlags;
223 if (isDuplicate == DuplicateMessage::Yes)
224 {
225 msgFlags.Set(MessageFlagValues::kDuplicateMessage);
226 }
227
jepenven-silabsfb1a62e2021-11-05 13:51:12 -0400228 // Skip retrieval of exchange for group message since no exchange is stored
229 // for group msg (optimization)
230 if (!packetHeader.IsGroupSession())
Zang MingJie1b5d2a72021-05-15 04:13:32 +0800231 {
jepenven-silabsfb1a62e2021-11-05 13:51:12 -0400232 // Search for an existing exchange that the message applies to. If a match is found...
233 bool found = false;
234 mContextPool.ForEachActiveObject([&](auto * ec) {
235 if (ec->MatchExchange(session, packetHeader, payloadHeader))
236 {
Boris Zbarsky1ad526b2021-12-02 19:31:01 -0500237 ChipLogDetail(ExchangeManager, "Found matching exchange: " ChipLogFormatExchange ", Delegate: %p",
Boris Zbarskyffee2a92021-12-01 14:34:57 -0500238 ChipLogValueExchange(ec), ec->GetDelegate());
239
jepenven-silabsfb1a62e2021-11-05 13:51:12 -0400240 // Matched ExchangeContext; send to message handler.
Zang MingJie40842bf2022-04-22 00:28:36 +0800241 ec->HandleMessage(packetHeader.GetMessageCounter(), payloadHeader, msgFlags, std::move(msgBuf));
jepenven-silabsfb1a62e2021-11-05 13:51:12 -0400242 found = true;
Zang MingJiee2e4c172021-12-03 01:15:02 +0800243 return Loop::Break;
jepenven-silabsfb1a62e2021-11-05 13:51:12 -0400244 }
Zang MingJiee2e4c172021-12-03 01:15:02 +0800245 return Loop::Continue;
jepenven-silabsfb1a62e2021-11-05 13:51:12 -0400246 });
247
248 if (found)
249 {
250 return;
251 }
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700252 }
Jean-Francois Penvenae485d12021-12-07 10:41:05 -0500253 else
254 {
Jerry Johns94412892022-09-13 16:33:36 -0400255 ChipLogProgress(ExchangeManager, "Received Groupcast Message with GroupId 0x%04X (%d)",
256 packetHeader.GetDestinationGroupId().Value(), packetHeader.GetDestinationGroupId().Value());
Jean-Francois Penvenae485d12021-12-07 10:41:05 -0500257 }
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700258
Boris Zbarsky03de7002022-06-22 19:19:30 -0400259 // Do not handle messages that don't match an existing exchange on an
260 // inactive session, since we should not be creating new exchanges there.
261 if (!session->IsActiveSession())
262 {
263 ChipLogProgress(ExchangeManager, "Dropping message on inactive session that does not match an existing exchange");
264 return;
265 }
266
Pankaj Garg48ed12b2021-06-28 10:07:30 -0700267 // If it's not a duplicate message, search for an unsolicited message handler if it is marked as being sent by an initiator.
268 // Since we didn't find an existing exchange that matches the message, it must be an unsolicited message. However all
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700269 // unsolicited messages must be marked as being from an initiator.
Jerry Johnsc6724a02022-06-21 06:47:02 -0700270 if (!msgFlags.Has(MessageFlagValues::kDuplicateMessage) && payloadHeader.IsInitiator())
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700271 {
272 // Search for an unsolicited message handler that can handle the message. Prefer handlers that can explicitly
273 // handle the message type over handlers that handle all messages for a profile.
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700274 matchingUMH = nullptr;
275
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400276 for (auto & umh : UMHandlerPool)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700277 {
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400278 if (umh.IsInUse() && payloadHeader.HasProtocol(umh.ProtocolId))
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700279 {
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400280 if (umh.MessageType == payloadHeader.GetMessageType())
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700281 {
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400282 matchingUMH = &umh;
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700283 break;
284 }
285
Boris Zbarskyd87cdb72021-05-20 10:41:42 -0400286 if (umh.MessageType == kAnyMessageType)
287 matchingUMH = &umh;
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700288 }
289 }
290 }
Yufeng Wangcb23e0c2021-01-07 12:36:21 -0800291 // Discard the message if it isn't marked as being sent by an initiator and the message does not need to send
292 // an ack to the peer.
Yufeng Wang3d79e0e2021-02-09 12:04:30 -0800293 else if (!payloadHeader.NeedsAck())
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700294 {
Boris Zbarskyef5bda72023-09-15 13:07:38 -0400295 // We can easily get standalone acks here: any time we fail to get a
296 // timely ack for the last message in an exchange and retransmit it,
297 // then get acks for both the message and the retransmit, the second ack
298 // will end up in this block. That's not really an error condition, so
299 // there is no need to log an error in that case.
300 if (!payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::StandaloneAck))
301 {
302 // Using same error message for all errors to reduce code size.
303 ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %" CHIP_ERROR_FORMAT,
304 CHIP_ERROR_UNSOLICITED_MSG_NO_ORIGINATOR.Format());
305 }
Zang MingJie32c13932021-07-20 22:18:50 +0800306 return;
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700307 }
308
Zang MingJied2a2f072022-06-10 22:09:05 +0800309 // If we found a handler, create an exchange to handle the message.
310 if (matchingUMH != nullptr)
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700311 {
Zang MingJied1512e52022-04-15 12:26:24 +0800312 ExchangeDelegate * delegate = nullptr;
313
314 // Fetch delegate from the handler
Zang MingJied2a2f072022-06-10 22:09:05 +0800315 CHIP_ERROR err = matchingUMH->Handler->OnUnsolicitedMessageReceived(payloadHeader, delegate);
316 if (err != CHIP_NO_ERROR)
Zang MingJied1512e52022-04-15 12:26:24 +0800317 {
Zang MingJied2a2f072022-06-10 22:09:05 +0800318 // Using same error message for all errors to reduce code size.
Damian Królik5e9d4132022-06-27 09:02:15 +0200319 ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %" CHIP_ERROR_FORMAT, err.Format());
Zang MingJied2a2f072022-06-10 22:09:05 +0800320 SendStandaloneAckIfNeeded(packetHeader, payloadHeader, session, msgFlags, std::move(msgBuf));
321 return;
Zang MingJied1512e52022-04-15 12:26:24 +0800322 }
323
Zang MingJied2a2f072022-06-10 22:09:05 +0800324 ExchangeContext * ec = mContextPool.CreateObject(this, payloadHeader.GetExchangeID(), session, false, delegate);
Yufeng Wangcb23e0c2021-01-07 12:36:21 -0800325
Zang MingJie32c13932021-07-20 22:18:50 +0800326 if (ec == nullptr)
327 {
Zang MingJied2a2f072022-06-10 22:09:05 +0800328 if (delegate != nullptr)
Zang MingJied1512e52022-04-15 12:26:24 +0800329 {
330 matchingUMH->Handler->OnExchangeCreationFailed(delegate);
331 }
332
Zang MingJie32c13932021-07-20 22:18:50 +0800333 // Using same error message for all errors to reduce code size.
Damian Królik5e9d4132022-06-27 09:02:15 +0200334 ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %" CHIP_ERROR_FORMAT, CHIP_ERROR_NO_MEMORY.Format());
Zang MingJied2a2f072022-06-10 22:09:05 +0800335 // No resource for creating new exchange, SendStandaloneAckIfNeeded probably also fails, so do not try it here
Zang MingJie32c13932021-07-20 22:18:50 +0800336 return;
337 }
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700338
Boris Zbarsky1ad526b2021-12-02 19:31:01 -0500339 ChipLogDetail(ExchangeManager, "Handling via exchange: " ChipLogFormatExchange ", Delegate: %p", ChipLogValueExchange(ec),
Boris Zbarskydbbe48d2021-09-21 16:06:03 -0400340 ec->GetDelegate());
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700341
Zang MingJied2a2f072022-06-10 22:09:05 +0800342 if (ec->IsEncryptionRequired() != packetHeader.IsEncrypted())
Zang MingJie2b2622f2021-09-10 20:59:20 +0800343 {
Damian Królik5e9d4132022-06-27 09:02:15 +0200344 ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %" CHIP_ERROR_FORMAT,
345 CHIP_ERROR_INVALID_MESSAGE_TYPE.Format());
Zang MingJie2b2622f2021-09-10 20:59:20 +0800346 ec->Close();
Zang MingJied2a2f072022-06-10 22:09:05 +0800347 SendStandaloneAckIfNeeded(packetHeader, payloadHeader, session, msgFlags, std::move(msgBuf));
348 return;
Zang MingJie2b2622f2021-09-10 20:59:20 +0800349 }
350
Zang MingJied2a2f072022-06-10 22:09:05 +0800351 err = ec->HandleMessage(packetHeader.GetMessageCounter(), payloadHeader, msgFlags, std::move(msgBuf));
Trevor Holbrook8c419b62021-07-30 07:43:45 -0700352 if (err != CHIP_NO_ERROR)
353 {
354 // Using same error message for all errors to reduce code size.
Damian Królik5e9d4132022-06-27 09:02:15 +0200355 ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %" CHIP_ERROR_FORMAT, err.Format());
Trevor Holbrook8c419b62021-07-30 07:43:45 -0700356 }
Zang MingJied2a2f072022-06-10 22:09:05 +0800357 return;
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700358 }
Zang MingJied2a2f072022-06-10 22:09:05 +0800359
360 SendStandaloneAckIfNeeded(packetHeader, payloadHeader, session, msgFlags, std::move(msgBuf));
Zang MingJied2a2f072022-06-10 22:09:05 +0800361}
362
363void ExchangeManager::SendStandaloneAckIfNeeded(const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
364 const SessionHandle & session, MessageFlags msgFlags,
365 System::PacketBufferHandle && msgBuf)
366{
Pradip Ded82ce572023-11-24 12:22:18 -0800367
368 // If using the MRP protocol and we need to send a StandaloneAck, create an EphemeralExchange to send
369 // the StandaloneAck.
370 if (!session->AllowsMRP() || !payloadHeader.NeedsAck())
Zang MingJied2a2f072022-06-10 22:09:05 +0800371 return;
372
373 // If rcvd msg is from initiator then this exchange is created as not Initiator.
374 // If rcvd msg is not from initiator then this exchange is created as Initiator.
375 // Create a EphemeralExchange to generate a StandaloneAck
376 ExchangeContext * ec = mContextPool.CreateObject(this, payloadHeader.GetExchangeID(), session, !payloadHeader.IsInitiator(),
377 nullptr, true /* IsEphemeralExchange */);
378
379 if (ec == nullptr)
380 {
381 // Using same error message for all errors to reduce code size.
Damian Królik5e9d4132022-06-27 09:02:15 +0200382 ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %" CHIP_ERROR_FORMAT, CHIP_ERROR_NO_MEMORY.Format());
Zang MingJied2a2f072022-06-10 22:09:05 +0800383 return;
384 }
385
386 ChipLogDetail(ExchangeManager, "Generating StandaloneAck via exchange: " ChipLogFormatExchange, ChipLogValueExchange(ec));
387
388 // No need to verify packet encryption type, the EphemeralExchange can handle both secure and insecure messages.
389
390 CHIP_ERROR err = ec->HandleMessage(packetHeader.GetMessageCounter(), payloadHeader, msgFlags, std::move(msgBuf));
391 if (err != CHIP_NO_ERROR)
392 {
393 // Using same error message for all errors to reduce code size.
Damian Królik5e9d4132022-06-27 09:02:15 +0200394 ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %" CHIP_ERROR_FORMAT, err.Format());
Zang MingJied2a2f072022-06-10 22:09:05 +0800395 }
396
397 // The exchange should be closed inside HandleMessage function. So don't bother close it here.
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700398}
399
Pankaj Garg107a3802021-05-25 09:48:45 -0700400void ExchangeManager::CloseAllContextsForDelegate(const ExchangeDelegate * delegate)
Boris Zbarsky0fe16aa2021-05-05 17:02:54 -0400401{
Zang MingJie1b5d2a72021-05-15 04:13:32 +0800402 mContextPool.ForEachActiveObject([&](auto * ec) {
403 if (ec->GetDelegate() == delegate)
Boris Zbarsky0fe16aa2021-05-05 17:02:54 -0400404 {
Zang MingJie1b5d2a72021-05-15 04:13:32 +0800405 // Make sure to null out the delegate before closing the context, so
406 // we don't notify the delegate that the context is closing. We
407 // have to do this, because the delegate might be partially
408 // destroyed by this point.
409 ec->SetDelegate(nullptr);
410 ec->Close();
Boris Zbarsky0fe16aa2021-05-05 17:02:54 -0400411 }
Zang MingJiee2e4c172021-12-03 01:15:02 +0800412 return Loop::Continue;
Zang MingJie1b5d2a72021-05-15 04:13:32 +0800413 });
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700414}
415
Yufeng Wang01031e72020-12-01 09:57:42 -0800416} // namespace Messaging
Yufeng Wang4fc19f12020-10-22 16:14:32 -0700417} // namespace chip