LCOV - code coverage report
Current view: top level - libs/bsw/transportRouterSimple/src/transport/routing - TransportRouterSimple.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.6 % 97 83
Test Date: 2026-06-18 08:29:03 Functions: 90.9 % 11 10

            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              : // NOLINTBEGIN(cppcoreguidelines-pro-type-vararg): Logger/StringWriter API is variadic by design.
      12              : 
      13              : #include "transport/routing/TransportRouterSimple.h"
      14              : 
      15              : #include "busid/BusId.h"
      16              : #include "transport/ITransportMessageProcessedListener.h"
      17              : 
      18              : #include <async/Async.h>
      19              : #include <transport/TpRouterLogger.h>
      20              : 
      21              : namespace transport
      22              : {
      23              : using ::util::logger::Logger;
      24              : using ::util::logger::TPROUTER;
      25              : 
      26              : namespace
      27              : {
      28            7 : bool is1ByteDiagAddressBus(uint8_t const busId)
      29              : {
      30            7 :     return (busId != ::busid::ETH_0) && (busId != ::busid::ETH_1);
      31              : }
      32              : } // namespace
      33              : 
      34           48 : TransportRouterSimple::TransportRouterSimple() : _transportLayers()
      35              : {
      36           16 :     for (uint8_t i = 0U; i < NUM_BUFFERS; i++)
      37              :     {
      38           12 :         _locked[i] = false;
      39           12 :         _message[i].init(_buffer[i], BUFFER_SIZE);
      40              :     }
      41           36 :     for (uint8_t i = 0U; i < NUM_FUNCTIONAL_BUFFERS; i++)
      42              :     {
      43           32 :         _functionalLocked[i] = false;
      44           32 :         _functionalMessage[i].init(_functionalBuffer[i], FUNCTIONAL_BUFFER_SIZE);
      45              :     }
      46            4 :     _busIdToReply = ::busid::SELFDIAG;
      47            4 : }
      48              : 
      49            4 : void TransportRouterSimple::init() { _transportLayers.clear(); }
      50              : 
      51            4 : void TransportRouterSimple::shutdown() { _transportLayers.clear(); }
      52              : 
      53            2 : ITransportMessageProvidingListener::ErrorCode TransportRouterSimple::getTransportMessage(
      54              :     uint8_t const srcBusId,
      55              :     uint16_t const sourceAddress,
      56              :     uint16_t const targetId,
      57              :     uint16_t const size,
      58              :     ::etl::span<uint8_t const> const& /* peek */,
      59              :     TransportMessage*& pTransportMessage)
      60              : {
      61            2 :     Logger::debug(
      62              :         TPROUTER,
      63              :         "TransportRouterSimple::getTransportMessage : sourceAddress 0x%x, targetId 0x%x",
      64              :         sourceAddress,
      65              :         targetId);
      66            2 :     pTransportMessage = nullptr;
      67              : 
      68            2 :     ::async::LockType const lockGuard;
      69              :     uint16_t const targetId2Byte
      70            2 :         = is1ByteDiagAddressBus(srcBusId)
      71            2 :               ? TransportConfiguration::convert1ByteAddressTo2Byte(targetId)
      72            2 :               : targetId;
      73              : 
      74            2 :     if (TransportConfiguration::isFunctionalAddress(targetId2Byte))
      75              :     {
      76            1 :         if (size <= TransportConfiguration::MAX_FUNCTIONAL_MESSAGE_PAYLOAD_SIZE)
      77              :         {
      78            1 :             for (uint8_t i = 0U; i < NUM_FUNCTIONAL_BUFFERS; i++)
      79              :             {
      80            1 :                 if (!_functionalLocked[i])
      81              :                 {
      82            1 :                     _functionalMessage[i].init(_functionalBuffer[i], FUNCTIONAL_BUFFER_SIZE);
      83            1 :                     pTransportMessage    = &_functionalMessage[i];
      84            1 :                     _functionalLocked[i] = true;
      85            1 :                     return ErrorCode::TPMSG_OK;
      86              :                 }
      87              :             }
      88              :         }
      89              :     }
      90              : 
      91            1 :     if (size > BUFFER_SIZE)
      92              :     {
      93            1 :         return ITransportMessageProvider::ErrorCode::TPMSG_SIZE_TOO_LARGE;
      94              :     }
      95              : 
      96            0 :     for (uint8_t i = 0U; i < NUM_BUFFERS; i++)
      97              :     {
      98            0 :         if (!_locked[i])
      99              :         {
     100            0 :             _message[i].init(_buffer[i], BUFFER_SIZE);
     101            0 :             pTransportMessage = &_message[i];
     102            0 :             _locked[i]        = true;
     103            0 :             return ErrorCode::TPMSG_OK;
     104              :         }
     105              :     }
     106              : 
     107            0 :     return ErrorCode::TPMSG_NO_MSG_AVAILABLE;
     108            2 : }
     109              : 
     110            1 : void TransportRouterSimple::releaseTransportMessage(TransportMessage& transportMessage)
     111              : {
     112            1 :     ::async::LockType const lockGuard;
     113            4 :     for (uint8_t i = 0U; i < NUM_BUFFERS; i++)
     114              :     {
     115            3 :         if (&transportMessage == &_message[i])
     116              :         {
     117            0 :             _locked[i] = false;
     118            0 :             return;
     119              :         }
     120              :     }
     121            1 :     for (uint8_t i = 0U; i < NUM_FUNCTIONAL_BUFFERS; i++)
     122              :     {
     123            1 :         if (&transportMessage == &_functionalMessage[i])
     124              :         {
     125            1 :             _functionalLocked[i] = false;
     126            1 :             return;
     127              :         }
     128              :     }
     129            1 : }
     130              : 
     131            3 : ITransportMessageProvidingListener::ReceiveResult TransportRouterSimple::messageReceived(
     132              :     uint8_t const sourceBusId,
     133              :     TransportMessage& transportMessage,
     134              :     ITransportMessageProcessedListener* const pNotificationListener)
     135              : {
     136            3 :     AbstractTransportLayer::ErrorCode result(AbstractTransportLayer::ErrorCode::TP_OK);
     137              : 
     138            3 :     if (is1ByteDiagAddressBus(sourceBusId))
     139              :     {
     140            2 :         transportMessage.setSourceAddress(
     141            2 :             TransportConfiguration::convert1ByteAddressTo2Byte(transportMessage.getSourceId()));
     142            2 :         transportMessage.setTargetAddress(
     143            2 :             TransportConfiguration::convert1ByteAddressTo2Byte(transportMessage.getTargetId()));
     144              :     }
     145              : 
     146            3 :     if ((sourceBusId == ::busid::CAN_0)
     147              : #ifdef PLATFORM_SUPPORT_ETHERNET
     148            3 :         || (sourceBusId == ::busid::ETH_0)
     149              : #endif
     150              :     )
     151              :     {
     152            1 :         _busIdToReply = sourceBusId;
     153            1 :         forwardMessageToTransportLayer(
     154              :             transportMessage, ::busid::SELFDIAG, pNotificationListener, result);
     155              :     }
     156            2 :     else if (sourceBusId == ::busid::SELFDIAG && _busIdToReply != ::busid::SELFDIAG)
     157              :     {
     158            1 :         forwardMessageToTransportLayer(
     159            1 :             transportMessage, _busIdToReply, pNotificationListener, result);
     160              :     }
     161              :     else
     162              :     {
     163            1 :         result = AbstractTransportLayer::ErrorCode::TP_SEND_FAIL;
     164              :     }
     165              : 
     166            3 :     if (result != AbstractTransportLayer::ErrorCode::TP_OK)
     167              :     {
     168            1 :         return ReceiveResult::RECEIVED_ERROR;
     169              :     }
     170            2 :     return ReceiveResult::RECEIVED_NO_ERROR;
     171              : }
     172              : 
     173            0 : void TransportRouterSimple::dump() {}
     174              : 
     175            8 : void TransportRouterSimple::addTransportLayer(AbstractTransportLayer& transportLayer)
     176              : {
     177            8 :     TransportLayerList::iterator itr         = _transportLayers.begin();
     178            8 :     TransportLayerList::iterator const e_itr = _transportLayers.end();
     179           12 :     for (; itr != e_itr; ++itr)
     180              :     {
     181            4 :         if (itr->getBusId() == transportLayer.getBusId())
     182              :         {
     183            0 :             Logger::error(
     184              :                 TPROUTER,
     185              :                 "TpLayer for bus %s must not be registered multiple times",
     186            0 :                 ::common::busid::BusIdTraits::getName(itr->getBusId()));
     187            0 :             return;
     188              :         }
     189              :     }
     190            8 :     transportLayer.fProvidingListenerHelper.fpMessageListener = this;
     191            8 :     transportLayer.fProvidingListenerHelper.fpMessageProvider = this;
     192            8 :     _transportLayers.push_back(transportLayer);
     193              : }
     194              : 
     195            8 : void TransportRouterSimple::removeTransportLayer(AbstractTransportLayer& transportLayer)
     196              : {
     197            8 :     if (!_transportLayers.contains_node(transportLayer))
     198              :     {
     199            0 :         return;
     200              :     }
     201            8 :     transportLayer.fProvidingListenerHelper.fpMessageListener = nullptr;
     202            8 :     transportLayer.fProvidingListenerHelper.fpMessageProvider = nullptr;
     203            8 :     _transportLayers.erase(transportLayer);
     204              : }
     205              : 
     206            2 : void TransportRouterSimple::forwardMessageToTransportLayer(
     207              :     TransportMessage& transportMessage,
     208              :     uint8_t const destBusId,
     209              :     ITransportMessageProcessedListener* const pNotificationListener,
     210              :     AbstractTransportLayer::ErrorCode& result)
     211              : {
     212            2 :     if (is1ByteDiagAddressBus(destBusId))
     213              :     {
     214            1 :         transportMessage.setSourceAddress(
     215            1 :             TransportConfiguration::convert2ByteAddressTo1Byte(transportMessage.getSourceId()));
     216            1 :         transportMessage.setTargetAddress(
     217            1 :             TransportConfiguration::convert2ByteAddressTo1Byte(transportMessage.getTargetId()));
     218              :     }
     219              : 
     220            3 :     for (TransportLayerList::iterator itr = _transportLayers.begin(); itr != _transportLayers.end();
     221            1 :          ++itr)
     222              :     {
     223            3 :         if (itr->getBusId() == destBusId)
     224              :         {
     225            2 :             result = itr->send(transportMessage, pNotificationListener);
     226            2 :             break;
     227              :         }
     228              :     }
     229            2 : }
     230              : 
     231              : } // namespace transport
     232              : 
     233              : // NOLINTEND(cppcoreguidelines-pro-type-vararg)
        

Generated by: LCOV version 2.0-1