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.3 % 95 81
Test Date: 2026-07-31 12:54:17 Functions: 90.0 % 10 9

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

Generated by: LCOV version 2.0-1