LCOV - code coverage report
Current view: top level - libs/bsw/cpp2someip/src - TpTransceiver.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 72.6 % 73 53
Test Date: 2026-09-11 12:05:06 Functions: 80.0 % 5 4

            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/TpTransceiver.h"
      12              : 
      13              : #include "bsp/timer/SystemTimer.h"
      14              : #include "someip/logger.h"
      15              : 
      16              : #include <util/timeout/ITimeoutManager2.h>
      17              : 
      18              : // Logger API uses printf-style varargs for fixed diagnostic messages in this module.
      19              : // NOLINTBEGIN(cppcoreguidelines-pro-type-vararg)
      20              : 
      21              : namespace someip
      22              : {
      23              : using ::common::ITimeoutManager2;
      24              : using ::util::logger::SOMEIP;
      25              : 
      26           15 : TpTransceiver::TpTransceiver(
      27              :     ::async::ContextType const ethernetContext,
      28              :     ::etl::span<TpSender*>& senders,
      29           15 :     ::etl::span<TpReceiver*>& receivers)
      30           15 : : _ethernetContext(ethernetContext)
      31           15 : , _cyclicFunction(::async::Function::CallType::create<TpTransceiver, &TpTransceiver::cyclic>(*this))
      32              : , _cyclicTimeout()
      33           15 : , _senders(senders)
      34           15 : , _receivers(receivers)
      35           15 : , _busy(false)
      36           15 : {}
      37              : 
      38            2 : void TpTransceiver::stop()
      39              : {
      40            2 :     if (_busy)
      41              :     {
      42            1 :         _cyclicTimeout.cancel();
      43            1 :         _busy = false;
      44              :     }
      45              : 
      46            3 :     for (TpReceiver* const receiver : _receivers)
      47              :     {
      48            1 :         if ((receiver != nullptr) && (receiver->isActive()))
      49              :         {
      50            1 :             receiver->stop();
      51              :         }
      52              :     }
      53            2 : }
      54              : 
      55              : // virtual
      56            3 : bool TpTransceiver::sendTpMessage(NetworkChannel& channel, SomeIpMessage const& message) const
      57              : {
      58            3 :     if (_senders.size() == 0U)
      59              :     {
      60            0 :         ERROR_LOG(SOMEIP, "TpTransceiver::sendTpMessage(): no sender available!");
      61            0 :         return false;
      62              :     }
      63              : 
      64            3 :     TpSender::TpResult const result = _senders.at(0U)->send(channel, message); // sync !
      65              : 
      66            3 :     return (TpSender::TpResult::TP_OK == result);
      67              : }
      68              : 
      69              : // virtual
      70           11 : void TpTransceiver::receiveTpMessage(
      71              :     NetworkChannel& channel, SomeIpMessage const& message, ITpListener& listener)
      72              : {
      73           11 :     TpReceiver* receiver = nullptr;
      74           11 :     TpReceiver* idle     = nullptr;
      75              : 
      76           18 :     for (TpReceiver* const item : _receivers)
      77              :     {
      78           11 :         if (item != nullptr)
      79              :         {
      80           11 :             if (item->isMatching(channel, message))
      81              :             {
      82            4 :                 receiver = item;
      83            4 :                 break;
      84              :             }
      85            7 :             if ((idle == nullptr) && (!item->isActive()))
      86              :             {
      87            6 :                 idle = item;
      88              :             }
      89              :         }
      90              :     }
      91              : 
      92           11 :     if ((receiver == nullptr) && (idle != nullptr))
      93              :     {
      94            6 :         receiver = idle;
      95              :     }
      96              : 
      97           11 :     if (receiver == nullptr)
      98              :     {
      99            1 :         ERROR_LOG(SOMEIP, "TpTransceiver::receiveTpMessage(): no receiver available!");
     100            1 :         return;
     101              :     }
     102              : 
     103           10 :     if (!receiver->isActive())
     104              :     {
     105            6 :         receiver->start(channel, message, listener);
     106              :     }
     107              : 
     108           10 :     uint32_t const time = static_cast<uint32_t>(getSystemTimeMs32Bit());
     109              : 
     110           10 :     TpReceiver::TpResult const result = receiver->receive(channel, message, time); // async !
     111              : 
     112           10 :     if (TpReceiver::TpResult::TP_PENDING == result)
     113              :     {
     114            5 :         if (!_busy)
     115              :         {
     116            5 :             async::schedule(
     117            5 :                 _ethernetContext,
     118              :                 _cyclicFunction,
     119            5 :                 _cyclicTimeout,
     120              :                 TP_UPDATE_CYCLE,
     121              :                 ::async::TimeUnit::MILLISECONDS);
     122              : 
     123            5 :             _busy = true;
     124              :         }
     125              :     }
     126              :     else
     127              :     {
     128            5 :         receiver->stop();
     129              : 
     130            5 :         if (_busy)
     131              :         {
     132            4 :             bool busy = false;
     133              : 
     134            8 :             for (TpReceiver* const item : _receivers)
     135              :             {
     136            4 :                 if ((item != nullptr) && (item->isActive()))
     137              :                 {
     138            0 :                     busy = true;
     139            0 :                     break;
     140              :                 }
     141              :             }
     142              : 
     143            4 :             if (!busy)
     144              :             {
     145            4 :                 _cyclicTimeout.cancel();
     146            4 :                 _busy = false;
     147              :             }
     148              :         }
     149              :     }
     150              : }
     151              : 
     152            0 : void TpTransceiver::cyclic()
     153              : {
     154            0 :     uint32_t const time = static_cast<uint32_t>(getSystemTimeMs32Bit());
     155              : 
     156            0 :     bool busy = false;
     157              : 
     158            0 :     for (TpReceiver* const receiver : _receivers)
     159              :     {
     160            0 :         if (receiver != nullptr)
     161              :         {
     162            0 :             if (receiver->isExpired(time))
     163              :             {
     164            0 :                 WARN_LOG(SOMEIP, "TpTransceiver::expired(): tp-receiver[%p] timeout!", receiver);
     165              : 
     166            0 :                 receiver->stop();
     167              :             }
     168            0 :             else if (receiver->isActive())
     169              :             {
     170            0 :                 busy = true;
     171              :             }
     172              :             else
     173              :             {
     174              :                 // nothing to do
     175              :             }
     176              :         }
     177              :     }
     178              : 
     179            0 :     _busy = busy;
     180              : 
     181            0 :     if (_busy)
     182              :     {
     183            0 :         async::schedule(
     184            0 :             _ethernetContext,
     185              :             _cyclicFunction,
     186            0 :             _cyclicTimeout,
     187              :             TP_UPDATE_CYCLE,
     188              :             ::async::TimeUnit::MILLISECONDS);
     189              :     }
     190            0 : }
     191              : 
     192              : } // namespace someip
     193              : 
     194              : // NOLINTEND(cppcoreguidelines-pro-type-vararg)
        

Generated by: LCOV version 2.0-1