Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : #include "transport/TransportMessage.h"
4 :
5 : #include "transport/TransportLogger.h"
6 :
7 : #include <etl/error_handler.h>
8 :
9 : #include <cstring>
10 :
11 : namespace transport
12 : {
13 : using ::util::logger::Logger;
14 : using ::util::logger::TRANSPORT;
15 :
16 919 : TransportMessage::TransportMessage()
17 919 : : _buffer()
18 919 : , _sourceAddress(INVALID_ADDRESS)
19 919 : , _targetAddress(INVALID_ADDRESS)
20 919 : , _payloadLength(0U)
21 919 : , _validBytes(0U)
22 919 : {}
23 :
24 27 : TransportMessage::TransportMessage(uint8_t* const buffer, uint32_t const bufferLength)
25 27 : : _buffer(::etl::span<uint8_t>(buffer, bufferLength))
26 27 : , _sourceAddress(INVALID_ADDRESS)
27 27 : , _targetAddress(INVALID_ADDRESS)
28 27 : , _payloadLength(0U)
29 27 : , _validBytes(0U)
30 27 : {}
31 :
32 : // NOLINTBEGIN(cppcoreguidelines-pro-type-vararg): Logger API is variadic by design.
33 492 : void TransportMessage::init(uint8_t* const buffer, uint32_t const bufferLength)
34 : {
35 492 : if ((buffer == nullptr) && (bufferLength > 0U))
36 : {
37 2 : Logger::critical(
38 : TRANSPORT,
39 : "TransportMessage::init(): buffer is NULL but bufferLength is %d!",
40 : bufferLength);
41 2 : ETL_ASSERT_FAIL(ETL_ERROR_GENERIC("buffer is null but buffer length is not zero"));
42 : }
43 490 : _buffer = ::etl::span<uint8_t>(buffer, bufferLength);
44 490 : _validBytes = 0U;
45 490 : if (_buffer.size() != 0U)
46 : {
47 485 : setPayloadLength(0U);
48 : }
49 490 : }
50 :
51 17 : void TransportMessage::setServiceId(uint8_t const theServiceId)
52 : {
53 17 : if (_buffer.size() == 0U)
54 : {
55 1 : Logger::critical(TRANSPORT, "TransportMessage::setServiceId(): fpBuffer is NULL!");
56 1 : ETL_ASSERT_FAIL(ETL_ERROR_GENERIC("buffer size is zero"));
57 : }
58 16 : _buffer[SERVICE_ID_INDEX] = theServiceId;
59 : // to be consistent with append, valid bytes must be increased here!
60 16 : if (0U == _validBytes)
61 : {
62 4 : (void)increaseValidBytes(1U);
63 : }
64 16 : }
65 :
66 767 : void TransportMessage::setPayloadLength(uint16_t const length)
67 : {
68 767 : if (length > getMaxPayloadLength())
69 : {
70 2 : Logger::critical(
71 : TRANSPORT,
72 : "TransportMessage::setPayloadLength(): length is too large (%d),"
73 : " maxLength is:%d!",
74 : length,
75 2 : getMaxPayloadLength());
76 2 : ETL_ASSERT_FAIL(ETL_ERROR_GENERIC("length is too large"));
77 : }
78 765 : _payloadLength = length;
79 765 : }
80 :
81 : // NOLINTEND(cppcoreguidelines-pro-type-vararg)
82 :
83 : TransportMessage::ErrorCode
84 1880 : TransportMessage::append(uint8_t const* const data, uint16_t const length)
85 : {
86 1880 : if ((_validBytes + length) > getMaxPayloadLength())
87 : {
88 2 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED;
89 : }
90 :
91 1878 : ::etl::span<uint8_t const> source(data, length);
92 1878 : (void)::etl::copy(source, _buffer.subspan(_validBytes));
93 1878 : (void)increaseValidBytes(length);
94 1878 : return ErrorCode::TP_MSG_OK;
95 : }
96 :
97 356 : TransportMessage::ErrorCode TransportMessage::append(uint8_t const data)
98 : {
99 356 : if ((_validBytes + 1U) > getMaxPayloadLength())
100 : {
101 1 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED;
102 : }
103 355 : _buffer[static_cast<size_t>(_validBytes)] = data;
104 355 : (void)increaseValidBytes(1U);
105 355 : return ErrorCode::TP_MSG_OK;
106 : }
107 :
108 2333 : TransportMessage::ErrorCode TransportMessage::increaseValidBytes(uint16_t const n)
109 : {
110 2333 : if ((_validBytes + n) > getMaxPayloadLength())
111 : {
112 : // this is an overflow, we only add as much as possible
113 1 : _validBytes = getMaxPayloadLength();
114 1 : return ErrorCode::TP_MSG_LENGTH_EXCEEDED;
115 : }
116 :
117 2332 : _validBytes += n;
118 2332 : return ErrorCode::TP_MSG_OK;
119 : }
120 :
121 20 : bool TransportMessage::operator==(TransportMessage const& rhs) const
122 : {
123 20 : if (getPayloadLength() != rhs.getPayloadLength())
124 : {
125 1 : return false;
126 : }
127 : // compare only valid bytes because a larger message may be used to receive
128 : // a small amount of data
129 19 : if (_validBytes != rhs._validBytes)
130 : {
131 1 : return false;
132 : }
133 18 : if ((getTargetId() != rhs.getTargetId()) || (getSourceId() != rhs.getSourceId()))
134 : {
135 2 : return false;
136 : }
137 :
138 16 : return 0 == ::memcmp(rhs._buffer.data(), _buffer.data(), _validBytes);
139 : }
140 :
141 : } // namespace transport
|