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/SdReceiver.h"
12 :
13 : #include "someip/ISdMessageParser.h"
14 : #include "someip/NetworkChannel.h"
15 : #include "someip/SomeIpConstants.h"
16 : #include "someip/SomeIpMessage.h"
17 : #include "someip/Statistics.h"
18 : #include "someip/logger.h"
19 :
20 : // Logger API uses printf-style varargs for fixed diagnostic messages in this module.
21 : // NOLINTBEGIN(cppcoreguidelines-pro-type-vararg)
22 :
23 : namespace someip
24 : {
25 : using ::util::logger::SOMEIP;
26 :
27 8 : SdReceiver::SdReceiver(ISdMessageParser& parser) : _parser(parser) {}
28 :
29 7 : void SdReceiver::received(NetworkChannel& channel, uint32_t const length)
30 : {
31 7 : Statistics::incCounter(Statistics::Counter::SD_FRAME_RX);
32 :
33 7 : auto const input = channel.getInputBuffer();
34 :
35 7 : uint32_t const bigLength = length;
36 7 : uint32_t offset = 0;
37 9 : while (offset < bigLength)
38 : {
39 6 : uint32_t const bytesLeft = bigLength - offset;
40 6 : if (bytesLeft < SomeIpMessage::OFFSET_PAYLOAD)
41 : {
42 2 : WARN_LOG(
43 : SOMEIP, "SdReceiver::received(): %d bytes left, but no valid header", bytesLeft);
44 4 : return;
45 : }
46 :
47 4 : Statistics::incCounter(Statistics::Counter::SD_MESSAGE_RX);
48 :
49 4 : SomeIpMessage const message(input.subspan(offset, bytesLeft));
50 :
51 4 : uint32_t const payloadLength = message.getPayloadLength();
52 4 : if (bytesLeft < (payloadLength + SomeIpMessage::OFFSET_PAYLOAD))
53 : {
54 1 : WARN_LOG(
55 : SOMEIP,
56 : "SdReceiver::received(): %d bytes left, but expected is %d",
57 : bytesLeft,
58 : payloadLength + SomeIpMessage::OFFSET_PAYLOAD);
59 1 : Statistics::incCounter(Statistics::Counter::SD_MALFORMED_MESSAGE_RX);
60 1 : return;
61 : }
62 :
63 3 : if (payloadLength > MAX_SD_PAYLOAD_LENGTH)
64 : {
65 1 : WARN_LOG(SOMEIP, "SdReceiver::received(): payload too long (%d bytes)", payloadLength);
66 1 : Statistics::incCounter(Statistics::Counter::SD_MALFORMED_MESSAGE_RX);
67 1 : return;
68 : }
69 :
70 2 : handleMessage(channel, message);
71 :
72 2 : offset += (payloadLength + SomeIpMessage::OFFSET_PAYLOAD);
73 : }
74 : }
75 :
76 : // private
77 2 : void SdReceiver::handleMessage(NetworkChannel& channel, SomeIpMessage const& message)
78 : {
79 2 : if (message.getMessageId() == SD_MESSAGE_ID)
80 : {
81 1 : _parser.handleMessage(message, channel.getRemoteEndpoint(), channel.isMulticast());
82 : }
83 : else
84 : {
85 1 : WARN_LOG(
86 : SOMEIP, "SdReceiver::handleMessage() dropping message 0x%x", message.getMessageId());
87 1 : Statistics::incCounter(Statistics::Counter::SD_MALFORMED_MESSAGE_RX);
88 : }
89 2 : }
90 :
91 : } // namespace someip
92 :
93 : // NOLINTEND(cppcoreguidelines-pro-type-vararg)
|