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