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 : #ifndef __STDC_FORMAT_MACROS 24 : #define __STDC_FORMAT_MACROS 25 : #endif 26 : 27 : #ifndef __STDC_LIMIT_MACROS 28 : #define __STDC_LIMIT_MACROS 29 : #endif 30 : 31 : #include <errno.h> 32 : #include <inttypes.h> 33 : #include <memory> 34 : 35 : #include <lib/support/CodeUtils.h> 36 : #include <messaging/ExchangeMessageDispatch.h> 37 : #include <messaging/ReliableMessageContext.h> 38 : #include <messaging/ReliableMessageMgr.h> 39 : #include <protocols/secure_channel/Constants.h> 40 : 41 : namespace chip { 42 : namespace Messaging { 43 : 44 9539 : CHIP_ERROR ExchangeMessageDispatch::SendMessage(SessionManager * sessionManager, const SessionHandle & session, uint16_t exchangeId, 45 : bool isInitiator, ReliableMessageContext * reliableMessageContext, 46 : bool isReliableTransmission, Protocols::Id protocol, uint8_t type, 47 : System::PacketBufferHandle && message) 48 : { 49 9539 : ReturnErrorCodeIf(!MessagePermitted(protocol, type), CHIP_ERROR_INVALID_ARGUMENT); 50 : 51 9539 : PayloadHeader payloadHeader; 52 9539 : payloadHeader.SetExchangeID(exchangeId).SetMessageType(protocol, type).SetInitiator(isInitiator); 53 : 54 9539 : if (session->AllowsMRP()) 55 : { 56 : // If there is a pending acknowledgment piggyback it on this message. 57 9491 : if (reliableMessageContext->HasPiggybackAckPending()) 58 : { 59 7877 : payloadHeader.SetAckMessageCounter(reliableMessageContext->TakePendingPeerAckMessageCounter()); 60 : } 61 : 62 28471 : if (IsReliableTransmissionAllowed() && reliableMessageContext->AutoRequestAck() && 63 28471 : reliableMessageContext->GetReliableMessageMgr() != nullptr && isReliableTransmission) 64 : { 65 7919 : auto * reliableMessageMgr = reliableMessageContext->GetReliableMessageMgr(); 66 : 67 7919 : payloadHeader.SetNeedsAck(true); 68 : 69 7919 : ReliableMessageMgr::RetransTableEntry * entry = nullptr; 70 : 71 : // Add to Table for subsequent sending 72 7919 : ReturnErrorOnFailure(reliableMessageMgr->AddToRetransTable(reliableMessageContext, &entry)); 73 4 : auto deleter = [reliableMessageMgr](ReliableMessageMgr::RetransTableEntry * e) { 74 4 : reliableMessageMgr->ClearRetransTable(*e); 75 7923 : }; 76 7919 : std::unique_ptr<ReliableMessageMgr::RetransTableEntry, decltype(deleter)> entryOwner(entry, deleter); 77 : 78 7919 : ReturnErrorOnFailure( 79 : sessionManager->PrepareMessage(session, payloadHeader, std::move(message), entryOwner->retainedBuf)); 80 7919 : CHIP_ERROR err = sessionManager->SendPreparedMessage(session, entryOwner->retainedBuf); 81 7919 : err = ReliableMessageMgr::MapSendError(err, exchangeId, isInitiator); 82 7919 : ReturnErrorOnFailure(err); 83 7915 : reliableMessageMgr->StartRetransmision(entryOwner.release()); 84 7919 : } 85 : else 86 : { 87 1572 : ReturnErrorOnFailure(PrepareAndSendNonMRPMessage(sessionManager, session, payloadHeader, std::move(message))); 88 : } 89 : } 90 : else 91 : { 92 48 : ReturnErrorOnFailure(PrepareAndSendNonMRPMessage(sessionManager, session, payloadHeader, std::move(message))); 93 : } 94 : 95 9534 : return CHIP_NO_ERROR; 96 9539 : } 97 : 98 1620 : CHIP_ERROR ExchangeMessageDispatch::PrepareAndSendNonMRPMessage(SessionManager * sessionManager, const SessionHandle & session, 99 : PayloadHeader & payloadHeader, 100 : System::PacketBufferHandle && message) 101 : { 102 1620 : payloadHeader.SetNeedsAck(false); 103 1620 : EncryptedPacketBufferHandle preparedMessage; 104 1620 : ReturnErrorOnFailure(sessionManager->PrepareMessage(session, payloadHeader, std::move(message), preparedMessage)); 105 1620 : ReturnErrorOnFailure(sessionManager->SendPreparedMessage(session, preparedMessage)); 106 : 107 1619 : return CHIP_NO_ERROR; 108 1620 : } 109 : 110 : } // namespace Messaging 111 : } // namespace chip