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