Line data Source code
1 : /********************************************************************************
2 : * Copyright (c) 2026 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 "someip/SomeIpMessage.h"
12 :
13 : #include "someip/SomeIpConstants.h"
14 :
15 : #include <etl/algorithm.h>
16 : #include <etl/array.h>
17 : #include <etl/unaligned_type.h>
18 : #include <util/meta/Bitmask.h>
19 :
20 : namespace someip
21 : {
22 : using configuration::NUMBER_OF_BITS_CLIENT_ID;
23 : using ::util::meta::Bitmask;
24 :
25 : namespace
26 : {
27 : ::etl::array<uint8_t const, SomeIpConstants::HEADER_LENGTH> const clientToServerCookieBuffer{
28 : {0xFFU,
29 : 0xFFU,
30 : 0x00U,
31 : 0x00U,
32 : 0x00U,
33 : 0x00U,
34 : 0x00U,
35 : 0x08U,
36 : 0xDEU,
37 : 0xADU,
38 : 0xBEU,
39 : 0xEFU,
40 : 0x01U,
41 : 0x01U,
42 : 0x01U,
43 : 0x00U}};
44 : ::etl::array<uint8_t const, SomeIpConstants::HEADER_LENGTH> const serverToClientCookieBuffer{
45 : {0xFFU,
46 : 0xFFU,
47 : 0x80U,
48 : 0x00U,
49 : 0x00U,
50 : 0x00U,
51 : 0x00U,
52 : 0x08U,
53 : 0xDEU,
54 : 0xADU,
55 : 0xBEU,
56 : 0xEFU,
57 : 0x01U,
58 : 0x01U,
59 : 0x02U,
60 : 0x00U}};
61 : } // namespace
62 :
63 167 : uint32_t readLength(::etl::span<uint8_t const> const& messageBuffer)
64 : {
65 167 : return ::etl::be_uint32_t(&messageBuffer[SomeIpMessage::OFFSET_LENGTH]);
66 : }
67 :
68 60 : uint32_t readTotalLength(::etl::span<uint8_t const> const& messageBuffer)
69 : {
70 60 : return readLength(messageBuffer)
71 60 : + (SomeIpMessage::OFFSET_PAYLOAD - SomeIpMessage::OFFSET_REQUEST_ID);
72 : }
73 :
74 21 : ::etl::span<uint8_t const> SomeIpMessage::getBufferHeader() const
75 : {
76 21 : return _buffer.first(SomeIpMessage::OFFSET_PAYLOAD);
77 : }
78 :
79 62 : ::etl::span<uint8_t const> SomeIpMessage::getBufferPayload() const
80 : {
81 62 : return _buffer.subspan(OFFSET_PAYLOAD, getPayloadLength());
82 : }
83 :
84 26 : uint8_t const* SomeIpMessage::getPayload() const
85 : {
86 26 : if (_buffer.size() <= OFFSET_PAYLOAD)
87 : {
88 1 : return nullptr;
89 : }
90 25 : return &_buffer[OFFSET_PAYLOAD];
91 : }
92 :
93 42 : uint8_t* SomeIpMessage::getPayload()
94 : {
95 42 : if (_buffer.size() <= OFFSET_PAYLOAD)
96 : {
97 1 : return nullptr;
98 : }
99 41 : return &_buffer[OFFSET_PAYLOAD];
100 : }
101 :
102 79 : uint32_t SomeIpMessage::getMessageId() const
103 : {
104 79 : return ::etl::be_uint32_t(&_buffer[OFFSET_MESSAGE_ID]);
105 : }
106 :
107 47 : void SomeIpMessage::setMessageId(uint32_t const messageId)
108 : {
109 47 : ::etl::be_uint32_ext_t{&_buffer[OFFSET_MESSAGE_ID]} = messageId;
110 47 : }
111 :
112 50 : service_id::type SomeIpMessage::getServiceId() const
113 : {
114 50 : return ::etl::be_uint16_t(&_buffer[OFFSET_SERVICE_ID]);
115 : }
116 :
117 55 : void SomeIpMessage::setServiceId(service_id::type const serviceId)
118 : {
119 55 : ::etl::be_uint16_ext_t{&_buffer[OFFSET_SERVICE_ID]} = serviceId;
120 55 : }
121 :
122 49 : uint16_t SomeIpMessage::getMethodId() const
123 : {
124 49 : return ::etl::be_uint16_t(&_buffer[OFFSET_METHOD_ID]);
125 : }
126 :
127 56 : void SomeIpMessage::setMethodId(uint16_t const methodId)
128 : {
129 56 : ::etl::be_uint16_ext_t{&_buffer[OFFSET_METHOD_ID]} = methodId;
130 56 : }
131 :
132 141 : void SomeIpMessage::setLength(uint32_t const length)
133 : {
134 141 : ::etl::be_uint32_ext_t{&_buffer[OFFSET_LENGTH]} = length;
135 141 : }
136 :
137 181 : uint32_t SomeIpMessage::getRequestId() const
138 : {
139 181 : return ::etl::be_uint32_t(&_buffer[OFFSET_REQUEST_ID]);
140 : }
141 :
142 112 : void SomeIpMessage::setRequestId(uint32_t const requestId)
143 : {
144 112 : ::etl::be_uint32_ext_t{&_buffer[OFFSET_REQUEST_ID]} = requestId;
145 112 : }
146 :
147 93 : uint16_t SomeIpMessage::getClientId() const
148 : {
149 : return static_cast<uint16_t>(
150 93 : getRequestId() >> (32U - static_cast<uint32_t>(NUMBER_OF_BITS_CLIENT_ID)));
151 : }
152 :
153 17 : void SomeIpMessage::setClientId(uint16_t const clientId)
154 : {
155 17 : uint32_t tmp = clientId;
156 17 : tmp <<= (32U - static_cast<uint32_t>(NUMBER_OF_BITS_CLIENT_ID));
157 17 : tmp |= static_cast<uint32_t>(getSessionId());
158 17 : setRequestId(tmp);
159 17 : }
160 :
161 60 : uint16_t SomeIpMessage::getSessionId() const
162 : {
163 : return static_cast<uint16_t>(
164 60 : getRequestId()
165 60 : & Bitmask<uint32_t, 32U - static_cast<uint32_t>(NUMBER_OF_BITS_CLIENT_ID)>::value);
166 : }
167 :
168 38 : void SomeIpMessage::setSessionId(uint16_t const sessionId)
169 : {
170 38 : uint32_t tmp = getClientId();
171 38 : tmp <<= (32U - static_cast<uint32_t>(NUMBER_OF_BITS_CLIENT_ID));
172 38 : tmp |= static_cast<uint32_t>(sessionId);
173 38 : setRequestId(tmp);
174 38 : }
175 :
176 48 : uint8_t SomeIpMessage::getProtocolVersion() const { return _buffer[OFFSET_PROTOCOL_VERSION]; }
177 :
178 69 : void SomeIpMessage::setProtocolVersion(uint8_t const protocolVersion)
179 : {
180 69 : _buffer[OFFSET_PROTOCOL_VERSION] = protocolVersion;
181 69 : }
182 :
183 66 : uint8_t SomeIpMessage::getInterfaceVersion() const { return _buffer[OFFSET_INTERFACE_VERSION]; }
184 :
185 64 : void SomeIpMessage::setInterfaceVersion(uint8_t const interfaceVersion)
186 : {
187 64 : _buffer[OFFSET_INTERFACE_VERSION] = interfaceVersion;
188 64 : }
189 :
190 101 : SomeIpMessage::MessageType SomeIpMessage::getMessageType() const
191 : {
192 101 : return static_cast<MessageType>(_buffer[OFFSET_MESSAGE_TYPE]);
193 : }
194 :
195 62 : void SomeIpMessage::setMessageType(MessageType const messageType)
196 : {
197 62 : _buffer[OFFSET_MESSAGE_TYPE] = static_cast<uint8_t>(messageType);
198 62 : }
199 :
200 34 : uint8_t SomeIpMessage::getRawMessageType() const { return _buffer[OFFSET_MESSAGE_TYPE]; }
201 :
202 42 : void SomeIpMessage::setRawMessageType(uint8_t const messageType)
203 : {
204 42 : _buffer[OFFSET_MESSAGE_TYPE] = messageType;
205 42 : }
206 :
207 36 : SomeIpMessage::ReturnCode SomeIpMessage::getReturnCode() const
208 : {
209 36 : return static_cast<SomeIpMessage::ReturnCode>(_buffer[OFFSET_RETURN_CODE]);
210 : }
211 :
212 67 : void SomeIpMessage::setReturnCode(SomeIpMessage::ReturnCode const returnCode)
213 : {
214 67 : _buffer[OFFSET_RETURN_CODE] = static_cast<uint8_t>(returnCode);
215 67 : }
216 :
217 103 : uint32_t SomeIpMessage::getPayloadLength() const
218 : {
219 103 : uint32_t const lengthCorrection = OFFSET_PAYLOAD - OFFSET_REQUEST_ID;
220 103 : uint32_t const length = getLength();
221 103 : if (length >= lengthCorrection)
222 : {
223 101 : return length - lengthCorrection;
224 : }
225 :
226 2 : return 0U;
227 : }
228 :
229 122 : void SomeIpMessage::setPayloadLength(uint32_t const payloadLength)
230 : {
231 122 : setLength(payloadLength + (OFFSET_PAYLOAD - OFFSET_REQUEST_ID));
232 122 : }
233 :
234 29 : uint32_t SomeIpMessage::getMaximumPayloadLength() const
235 : {
236 29 : return static_cast<uint32_t>(_buffer.size()) - OFFSET_PAYLOAD;
237 : }
238 :
239 23 : uint8_t SomeIpMessage::getFlags() const { return getPayload()[OFFSET_SD_FLAGS]; }
240 :
241 4 : void SomeIpMessage::makeClientToServerMagicCookieMessage(SomeIpMessage& message)
242 : {
243 4 : etl::copy(
244 : clientToServerCookieBuffer.begin(),
245 : clientToServerCookieBuffer.end(),
246 : message._buffer.begin());
247 4 : }
248 :
249 1 : void SomeIpMessage::makeServerToClientMagicCookieMessage(SomeIpMessage& message)
250 : {
251 1 : etl::copy(
252 : serverToClientCookieBuffer.begin(),
253 : serverToClientCookieBuffer.end(),
254 : message._buffer.begin());
255 1 : }
256 :
257 : } // namespace someip
|