Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : *
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 provides implementation of ExchangeMessageDispatch class.
21 : */
22 :
23 : #include <errno.h>
24 : #include <inttypes.h>
25 : #include <memory>
26 :
27 : #include <lib/support/CodeUtils.h>
28 : #include <messaging/ExchangeMessageDispatch.h>
29 : #include <messaging/ReliableMessageContext.h>
30 : #include <messaging/ReliableMessageMgr.h>
31 : #include <protocols/secure_channel/Constants.h>
32 :
33 : namespace chip {
34 : namespace Messaging {
35 :
36 9777 : CHIP_ERROR ExchangeMessageDispatch::SendMessage(SessionManager * sessionManager, const SessionHandle & session, uint16_t exchangeId,
37 : bool isInitiator, ReliableMessageContext * reliableMessageContext,
38 : bool isReliableTransmission, Protocols::Id protocol, uint8_t type,
39 : System::PacketBufferHandle && message)
40 : {
41 9777 : VerifyOrReturnError(MessagePermitted(protocol, type), CHIP_ERROR_INVALID_ARGUMENT);
42 :
43 9777 : PayloadHeader payloadHeader;
44 9777 : payloadHeader.SetExchangeID(exchangeId).SetMessageType(protocol, type).SetInitiator(isInitiator);
45 :
46 9777 : if (session->AllowsMRP())
47 : {
48 : // If there is a pending acknowledgment piggyback it on this message.
49 9729 : if (reliableMessageContext->HasPiggybackAckPending())
50 : {
51 8035 : payloadHeader.SetAckMessageCounter(reliableMessageContext->TakePendingPeerAckMessageCounter());
52 : }
53 :
54 29185 : if (IsReliableTransmissionAllowed() && reliableMessageContext->AutoRequestAck() &&
55 29185 : reliableMessageContext->GetReliableMessageMgr() != nullptr && isReliableTransmission)
56 : {
57 8076 : auto * reliableMessageMgr = reliableMessageContext->GetReliableMessageMgr();
58 :
59 8076 : payloadHeader.SetNeedsAck(true);
60 :
61 8076 : ReliableMessageMgr::RetransTableEntry * entry = nullptr;
62 :
63 : // Add to Table for subsequent sending
64 8076 : ReturnErrorOnFailure(reliableMessageMgr->AddToRetransTable(reliableMessageContext, &entry));
65 4 : auto deleter = [reliableMessageMgr](ReliableMessageMgr::RetransTableEntry * e) {
66 4 : reliableMessageMgr->ClearRetransTable(*e);
67 8080 : };
68 8076 : std::unique_ptr<ReliableMessageMgr::RetransTableEntry, decltype(deleter)> entryOwner(entry, deleter);
69 :
70 8076 : ReturnErrorOnFailure(
71 : sessionManager->PrepareMessage(session, payloadHeader, std::move(message), entryOwner->retainedBuf));
72 8076 : CHIP_ERROR err = sessionManager->SendPreparedMessage(session, entryOwner->retainedBuf);
73 8076 : err = ReliableMessageMgr::MapSendError(err, exchangeId, isInitiator);
74 8076 : ReturnErrorOnFailure(err);
75 8072 : reliableMessageMgr->StartRetransmision(entryOwner.release());
76 8076 : }
77 : else
78 : {
79 1653 : ReturnErrorOnFailure(PrepareAndSendNonMRPMessage(sessionManager, session, payloadHeader, std::move(message)));
80 : }
81 : }
82 : else
83 : {
84 48 : ReturnErrorOnFailure(PrepareAndSendNonMRPMessage(sessionManager, session, payloadHeader, std::move(message)));
85 : }
86 :
87 9772 : return CHIP_NO_ERROR;
88 9777 : }
89 :
90 1701 : CHIP_ERROR ExchangeMessageDispatch::PrepareAndSendNonMRPMessage(SessionManager * sessionManager, const SessionHandle & session,
91 : PayloadHeader & payloadHeader,
92 : System::PacketBufferHandle && message)
93 : {
94 1701 : payloadHeader.SetNeedsAck(false);
95 1701 : EncryptedPacketBufferHandle preparedMessage;
96 1701 : ReturnErrorOnFailure(sessionManager->PrepareMessage(session, payloadHeader, std::move(message), preparedMessage));
97 1701 : ReturnErrorOnFailure(sessionManager->SendPreparedMessage(session, preparedMessage));
98 :
99 1700 : return CHIP_NO_ERROR;
100 1701 : }
101 :
102 : } // namespace Messaging
103 : } // namespace chip
|