Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : #include "transport/TransportMessage.h" 4 : 5 : #include "transport/IDataProgressListener.h" 6 : #include "transport/TransportLogger.h" 7 : 8 : #include <util/estd/assert.h> 9 : 10 : #include <cstring> 11 : 12 : namespace transport 13 : { 14 : using ::util::logger::_CRITICAL; 15 : using ::util::logger::Logger; 16 : using ::util::logger::TRANSPORT; 17 : 18 950 : TransportMessage::TransportMessage() 19 950 : : fpDataProgressListener(nullptr) 20 950 : , fBuffer() 21 950 : , fSourceId(INVALID_ADDRESS) 22 950 : , fTargetId(INVALID_ADDRESS) 23 950 : , fPayloadLength(0U) 24 950 : , fValidBytes(0U) 25 950 : {} 26 : 27 24 : TransportMessage::TransportMessage(uint8_t* const buffer, uint32_t const bufferLength) 28 24 : : fpDataProgressListener(nullptr) 29 24 : , fBuffer(::etl::span<uint8_t>(buffer, bufferLength)) 30 24 : , fSourceId(INVALID_ADDRESS) 31 24 : , fTargetId(INVALID_ADDRESS) 32 24 : , fPayloadLength(0U) 33 24 : , fValidBytes(0U) 34 24 : {} 35 : 36 759 : void TransportMessage::init(uint8_t* const buffer, uint32_t const bufferLength) 37 : { 38 759 : if ((buffer == nullptr) && (bufferLength > 0U)) 39 : { 40 2 : Logger::critical( 41 : TRANSPORT, 42 : "TransportMessage::init(): buffer is NULL but bufferLength is %d!", 43 : bufferLength); 44 2 : estd_assert(false); 45 : } 46 757 : fpDataProgressListener = nullptr; 47 757 : fBuffer = ::etl::span<uint8_t>(buffer, bufferLength); 48 757 : fValidBytes = 0U; 49 757 : if (fBuffer.size() != 0U) 50 : { 51 752 : setPayloadLength(0U); 52 : } 53 757 : } 54 : 55 17 : void TransportMessage::setServiceId(uint8_t const theServiceId) 56 : { 57 17 : if (fBuffer.size() == 0U) 58 : { 59 1 : Logger::critical(TRANSPORT, "TransportMessage::setServiceId(): fpBuffer is NULL!"); 60 1 : estd_assert(false); 61 : } 62 16 : fBuffer[SERVICE_ID_INDEX] = theServiceId; 63 : // to be consistent with append, valid bytes must be increased here! 64 16 : if (0U == fValidBytes) 65 : { 66 4 : (void)increaseValidBytes(1U); 67 : } 68 16 : } 69 : 70 1045 : void TransportMessage::setPayloadLength(uint16_t const length) 71 : { 72 1045 : if (length > getMaxPayloadLength()) 73 : { 74 2 : Logger::critical( 75 : TRANSPORT, 76 : "TransportMessage::setPayloadLength(): length is too large (%d)," 77 : " maxLength is:%d!", 78 : length, 79 2 : getMaxPayloadLength()); 80 2 : estd_assert(false); 81 : } 82 1043 : fPayloadLength = length; 83 1043 : } 84 : 85 : TransportMessage::ErrorCode 86 1884 : TransportMessage::append(uint8_t const* const data, uint16_t const length) 87 : { 88 1884 : if ((fValidBytes + length) > getMaxPayloadLength()) 89 : { 90 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED; 91 : } 92 : 93 1882 : ::etl::span<uint8_t const> source(data, length); 94 1882 : (void)::etl::copy(source, fBuffer.subspan(fValidBytes)); 95 1882 : (void)increaseValidBytes(length); 96 : return ErrorCode::TP_MSG_OK; 97 : } 98 : 99 411 : TransportMessage::ErrorCode TransportMessage::append(uint8_t const data) 100 : { 101 411 : if ((fValidBytes + 1U) > getMaxPayloadLength()) 102 : { 103 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED; 104 : } 105 410 : fBuffer[static_cast<size_t>(fValidBytes)] = data; 106 410 : (void)increaseValidBytes(1U); 107 410 : return ErrorCode::TP_MSG_OK; 108 : } 109 : 110 2376 : TransportMessage::ErrorCode TransportMessage::increaseValidBytes(uint16_t const n) 111 : { 112 2376 : if ((fValidBytes + n) > getMaxPayloadLength()) 113 : { 114 : // this is an overflow, we only add as much as possible 115 1 : uint32_t const numberOfNewValidBytes 116 1 : = static_cast<uint32_t>(getMaxPayloadLength()) - static_cast<uint32_t>(fValidBytes); 117 1 : fValidBytes = getMaxPayloadLength(); 118 1 : notifyDataProgressListener(numberOfNewValidBytes); 119 1 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED; 120 : } 121 : 122 2375 : fValidBytes += n; 123 2375 : notifyDataProgressListener(static_cast<uint32_t>(n)); 124 2375 : return ErrorCode::TP_MSG_OK; 125 : } 126 : 127 20 : bool TransportMessage::operator==(TransportMessage const& rhs) const 128 : { 129 20 : if (getPayloadLength() != rhs.getPayloadLength()) 130 : { 131 : return false; 132 : } 133 : // compare only valid bytes because a larger message may be used to receive 134 : // a small amount of data 135 19 : if (fValidBytes != rhs.fValidBytes) 136 : { 137 : return false; 138 : } 139 18 : if ((getTargetId() != rhs.getTargetId()) || (getSourceId() != rhs.getSourceId())) 140 : { 141 : return false; 142 : } 143 : 144 16 : return 0 == ::memcmp(rhs.fBuffer.data(), fBuffer.data(), fValidBytes); 145 : } 146 : 147 1 : void TransportMessage::setDataProgressListener(IDataProgressListener& listener) 148 : { 149 1 : fpDataProgressListener = &listener; 150 1 : } 151 : 152 3 : bool TransportMessage::isDataProgressListener(IDataProgressListener const& listener) const 153 : { 154 3 : return fpDataProgressListener == &listener; 155 : } 156 : 157 1 : void TransportMessage::removeDataProgressListener() { fpDataProgressListener = nullptr; } 158 : 159 2376 : void TransportMessage::notifyDataProgressListener(uint32_t const numberOfNewValidBytes) 160 : { 161 2376 : if (fpDataProgressListener != nullptr) 162 : { 163 1 : fpDataProgressListener->dataProgressed(*this, numberOfNewValidBytes); 164 : } 165 2376 : } 166 : 167 : } // namespace transport