LCOV - code coverage report
Current view: top level - libs/bsw/cpp2someip/src - TpReceiver.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.3 % 65 60
Test Date: 2026-09-11 12:05:06 Functions: 100.0 % 6 6

            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/TpReceiver.h"
      12              : 
      13              : #include "someip/ITpTransceiver.h"
      14              : #include "someip/NetworkChannel.h"
      15              : #include "someip/logger.h"
      16              : 
      17              : #include <etl/algorithm.h>
      18              : #include <etl/unaligned_type.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           46 : bool TpReceiver::isActive() const { return (_pChannel != nullptr); }
      28              : 
      29            3 : bool TpReceiver::isExpired(uint32_t const time) const
      30              : {
      31            3 :     return ((_timestamp > 0U) && (time >= (_timestamp + ITpTransceiver::TP_RECEIVE_TIMEOUT)));
      32              : }
      33              : 
      34           13 : bool TpReceiver::isMatching(NetworkChannel const& channel, SomeIpMessage const& message) const
      35              : {
      36           13 :     if (!isActive())
      37              :     {
      38            7 :         return false;
      39              :     }
      40              : 
      41            6 :     if (_pChannel->getRemoteEndpoint() != channel.getRemoteEndpoint())
      42              :     {
      43            0 :         return false;
      44              :     }
      45            6 :     if (_pChannel->getLocalPort() != channel.getLocalPort())
      46              :     {
      47            0 :         return false;
      48              :     }
      49              : 
      50            6 :     SomeIpMessage const _message(_buffer);
      51              : 
      52            6 :     if (_message.getMessageId() != message.getMessageId())
      53              :     {
      54            1 :         return false;
      55              :     }
      56            5 :     if (_message.getClientId() != message.getClientId())
      57              :     {
      58            0 :         return false;
      59              :     }
      60            5 :     if (_message.getRawMessageType() != message.getRawMessageType())
      61              :     {
      62            0 :         return false;
      63              :     }
      64            5 :     if (_message.getInterfaceVersion() != message.getInterfaceVersion())
      65              :     {
      66            0 :         return false;
      67              :     }
      68              : 
      69            5 :     return true;
      70              : }
      71              : 
      72           13 : void TpReceiver::start(NetworkChannel& channel, SomeIpMessage const& message, ITpListener& listener)
      73              : {
      74           13 :     _pChannel  = &channel;
      75           13 :     _pListener = &listener;
      76              : 
      77              :     // copy msg-header
      78           13 :     auto header = message.getBufferHeader();
      79           13 :     etl::copy(header.begin(), header.end(), _buffer.begin());
      80           13 : }
      81              : 
      82           13 : void TpReceiver::stop()
      83              : {
      84           13 :     _pChannel  = nullptr;
      85           13 :     _pListener = nullptr;
      86           13 :     _timestamp = 0U;
      87              : 
      88           13 :     etl::fill(_buffer.begin(), _buffer.end(), 0U);
      89              : 
      90           13 :     _totalPayloadLength    = 0U;
      91           13 :     _receivedPayloadLength = 0U;
      92           13 : }
      93              : 
      94           22 : TpReceiver::TpResult TpReceiver::receive(
      95              :     NetworkChannel const& /*channel*/, SomeIpMessage const& message, uint32_t const timestamp)
      96              : {
      97           22 :     INFO_LOG(
      98              :         SOMEIP,
      99              :         "TpReceiver[%p]::receive(): id: 0x%X, type: 0x%X => %d bytes",
     100              :         this,
     101              :         message.getMessageId(),
     102              :         message.getMessageType(),
     103              :         message.getTotalLength());
     104              : 
     105           22 :     auto const payload       = message.getBufferPayload();
     106           22 :     size_t const chunkLength = payload.size() - ITpTransceiver::TP_HEADER_LENGTH;
     107           22 :     auto const chunk         = payload.subspan(ITpTransceiver::TP_HEADER_LENGTH, chunkLength);
     108              : 
     109              :     // read tp-header
     110           22 :     if (payload.size() < ITpTransceiver::TP_HEADER_LENGTH)
     111              :     {
     112            3 :         ERROR_LOG(
     113              :             SOMEIP,
     114              :             "TpReceiver[%p]::receive(): id: 0x%X, type: 0x%X => no tp-header",
     115              :             this,
     116              :             message.getMessageId(),
     117              :             message.getMessageType());
     118              : 
     119            3 :         return TpReceiver::TpResult::TP_ERROR;
     120              :     }
     121           19 :     ITpTransceiver::TpHeader tpHeader{};
     122           19 :     ITpTransceiver::parseTpHeader(::etl::be_uint32_t(&payload[0U]), tpHeader);
     123              : 
     124           19 :     if (!tpHeader.hasMoreSegments)
     125              :     {
     126            8 :         _totalPayloadLength = (tpHeader.payloadOffset + chunkLength);
     127              :     }
     128              : 
     129              :     // copy payload
     130           19 :     size_t const targetLength = static_cast<size_t>(
     131           19 :         chunkLength + static_cast<size_t>(SomeIpMessage::OFFSET_PAYLOAD) + tpHeader.payloadOffset);
     132           19 :     if (_buffer.size() < targetLength)
     133              :     {
     134            1 :         ERROR_LOG(
     135              :             SOMEIP,
     136              :             "TpReceiver[%p]::receive(): id: 0x%X, type: 0x%X => buffer exceeded at %d bytes",
     137              :             this,
     138              :             message.getMessageId(),
     139              :             message.getMessageType(),
     140              :             targetLength);
     141              : 
     142            1 :         return TpReceiver::TpResult::TP_ERROR;
     143              :     }
     144              :     auto destination = _buffer.subspan(
     145           18 :         static_cast<size_t>(SomeIpMessage::OFFSET_PAYLOAD) + tpHeader.payloadOffset);
     146           18 :     etl::copy(chunk.begin(), chunk.end(), destination.begin());
     147           18 :     _receivedPayloadLength += chunkLength;
     148              : 
     149           18 :     bool const lastSegmentReceived = ((_totalPayloadLength != 0U) || (!tpHeader.hasMoreSegments));
     150              : 
     151           18 :     if (lastSegmentReceived && (_totalPayloadLength <= _receivedPayloadLength))
     152              :     {
     153              :         // adjust msg-header
     154            6 :         SomeIpMessage _message(_buffer);
     155            6 :         _message.setRawMessageType(
     156            6 :             _message.getRawMessageType()
     157              :             & static_cast<uint8_t>(~ITpTransceiver::TP_MESSAGE_TYPE_BIT_MASK));
     158            6 :         _message.setPayloadLength(static_cast<uint32_t>(_totalPayloadLength));
     159            6 :         if (_pListener != nullptr)
     160              :         {
     161            6 :             _pListener->receivedTpMessage(*_pChannel, _message);
     162              :         }
     163              : 
     164            6 :         return TpReceiver::TpResult::TP_OK;
     165              :     }
     166              : 
     167           12 :     _timestamp = timestamp;
     168              : 
     169           12 :     return TpReceiver::TpResult::TP_PENDING;
     170              : }
     171              : 
     172              : } // namespace someip
     173              : 
     174              : // NOLINTEND(cppcoreguidelines-pro-type-vararg)
        

Generated by: LCOV version 2.0-1