LCOV - code coverage report
Current view: top level - libs/bsw/cpp2someip/src - RpcChannel.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 65.6 % 90 59
Test Date: 2026-09-11 12:05:06 Functions: 71.4 % 21 15

            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/RpcChannel.h"
      12              : 
      13              : #include "someip/INetwork.h"
      14              : #include "someip/IRpcSender.h"
      15              : #include "someip/NetworkResource.h"
      16              : #include "someip/RpcClosure.h"
      17              : #include "someip/SomeIpConstants.h"
      18              : #include "someip/logger.h"
      19              : 
      20              : #include <udp/DatagramPacket.h>
      21              : #include <util/timeout/ITimeoutManager2.h>
      22              : 
      23              : // Logger API uses printf-style varargs for fixed diagnostic messages in this module.
      24              : // NOLINTBEGIN(cppcoreguidelines-pro-type-vararg)
      25              : 
      26              : namespace someip
      27              : {
      28              : using ::udp::DatagramPacket;
      29              : using ::util::logger::SOMEIP;
      30              : 
      31              : using ::common::ITimeoutManager2;
      32              : 
      33           10 : RpcChannel::RpcChannel(INetwork& network, IRpcSender& sender)
      34           10 : : _network(network)
      35           10 : , _sender(sender)
      36           10 : , _timeoutExpiredFunction(
      37           20 :       ::async::Function::CallType::create<RpcChannel, &RpcChannel::timeoutExpired>(*this))
      38           20 : , _timeoutExpiredTimeout()
      39           10 : {}
      40              : 
      41            2 : bool RpcChannel::isOpen() const
      42              : {
      43            2 :     if (_networkChannel.has_value())
      44              :     {
      45            0 :         return _networkChannel.value().isOpen();
      46              :     }
      47              : 
      48            2 :     return false;
      49              : }
      50              : 
      51            4 : void RpcChannel::openUdp(
      52              :     service_id::type const serviceId,
      53              :     ::ip::IPEndpoint const& remoteEndpoint,
      54              :     port::type const localPort)
      55              : {
      56            4 :     close();
      57              : 
      58            4 :     _serviceId      = serviceId;
      59            4 :     _networkChannel = _network.openUdpChannel(localPort, remoteEndpoint);
      60            4 : }
      61              : 
      62            1 : void RpcChannel::openTcp(
      63              :     service_id::type const serviceId,
      64              :     ::ip::IPEndpoint const& remoteEndpoint,
      65              :     port::type const localPort)
      66              : {
      67            1 :     close();
      68              : 
      69            1 :     _serviceId      = serviceId;
      70            1 :     _networkChannel = _network.openTcpChannel(localPort, remoteEndpoint);
      71            1 : }
      72              : 
      73            1 : void RpcChannel::openTcpWithExternalReassembleBuffer(
      74              :     service_id::type const serviceId,
      75              :     ::ip::IPEndpoint const& remoteEndpoint,
      76              :     port::type const localPort,
      77              :     ::etl::span<uint8_t> const buffer)
      78              : {
      79            1 :     close();
      80              : 
      81            1 :     _serviceId = serviceId;
      82              :     _networkChannel
      83            1 :         = _network.openTcpChannelWithExternalReassembleBuffer(localPort, remoteEndpoint, buffer);
      84            1 : }
      85              : 
      86            9 : void RpcChannel::close()
      87              : {
      88            9 :     _networkChannel.reset();
      89            9 :     _serviceId = 0;
      90            9 : }
      91              : 
      92            4 : service_id::type RpcChannel::getServiceId() const { return _serviceId; }
      93              : 
      94            1 : uint16_t RpcChannel::getClientId() const { return _clientId; }
      95              : 
      96            0 : uint16_t RpcChannel::getSessionId() const { return _sessionId; }
      97              : 
      98            0 : void RpcChannel::setSessionId(uint16_t const sessionId) { _sessionId = sessionId; }
      99              : 
     100            1 : void RpcChannel::setClientId(uint16_t const clientId) { _clientId = clientId; }
     101              : 
     102            7 : ::ip::IPEndpoint const& RpcChannel::getRemoteIp() const
     103              : {
     104            7 :     if (!_networkChannel.has_value())
     105              :     {
     106            7 :         return NetworkResource::INVALID_ADDRESS;
     107              :     }
     108              : 
     109            0 :     return _networkChannel->getRemoteEndpoint();
     110              : }
     111              : 
     112            3 : ::etl::expected<uint16_t, PortError> RpcChannel::getLocalPort() const
     113              : {
     114            3 :     if (!_networkChannel.has_value())
     115              :     {
     116            4 :         return ::etl::unexpected<PortError>(PortError::NOT_INITIALIZED);
     117              :     }
     118              : 
     119            1 :     return _networkChannel->getLocalPort();
     120              : }
     121              : 
     122            2 : uint8_t RpcChannel::getProto() const
     123              : {
     124            2 :     if (!_networkChannel.has_value())
     125              :     {
     126            1 :         return SomeIpConstants::INVALID_PROTO;
     127              :     }
     128              : 
     129            1 :     return _networkChannel->getProto();
     130              : }
     131              : 
     132            2 : ServiceResultCode RpcChannel::callMethod(
     133              :     uint16_t const methodId,
     134              :     ISomeIpSerializable const* const pRequest,
     135              :     uint8_t const interfaceVersion,
     136              :     ISomeIpSerializable* const pResponse,
     137              :     CallDoneClosure& done,
     138              :     uint32_t timeout)
     139              : {
     140            2 :     if (!_networkChannel.has_value())
     141              :     {
     142            1 :         return COULD_NOT_DELIVER;
     143              :     }
     144              : 
     145            1 :     if (_pPendingCallback != nullptr)
     146              :     {
     147            0 :         return BUSY_ERROR;
     148              :     }
     149              : 
     150            1 :     INFO_LOG(SOMEIP, "RpcChannel::callMethod(%d)", methodId);
     151              : 
     152            1 :     _pPendingResponse = pResponse;
     153            1 :     _pPendingCallback = &done;
     154              : 
     155            2 :     ServiceResultCode const rc = _sender.sendRequest(
     156            1 :         pRequest, _serviceId, methodId, interfaceVersion, true, *this, timeout);
     157              : 
     158            1 :     if (rc != RPC_SENT_SUCCESSFULLY)
     159              :     {
     160            0 :         _pPendingCallback = nullptr;
     161              :     }
     162              : 
     163            1 :     return rc;
     164              : }
     165              : 
     166            1 : ServiceResultCode RpcChannel::callFireAndForgetMethod(
     167              :     uint16_t const methodId,
     168              :     ISomeIpSerializable const* const pRequest,
     169              :     uint8_t const interfaceVersion)
     170              : {
     171            1 :     if (!_networkChannel.has_value())
     172              :     {
     173            1 :         return COULD_NOT_DELIVER;
     174              :     }
     175              : 
     176            0 :     INFO_LOG(SOMEIP, "RpcChannel::callFireAndForgetMethod(%d)", methodId);
     177              : 
     178              :     ServiceResultCode const rc
     179            0 :         = _sender.sendRequest(pRequest, _serviceId, methodId, interfaceVersion, false, *this, 0);
     180              : 
     181            0 :     return (rc != RPC_SENT_SUCCESSFULLY) ? rc : RPC_SENT_SUCCESSFULLY_NO_RESPONSE_EXPECTED;
     182              : }
     183              : 
     184            2 : ISomeIpSerializable* RpcChannel::getResponse()
     185              : {
     186            2 :     return (_pPendingCallback != nullptr) ? _pPendingResponse : nullptr;
     187              : }
     188              : 
     189            0 : void RpcChannel::responseReceived(ServiceResultCode result)
     190              : {
     191            0 :     INFO_LOG(SOMEIP, "RpcChannel::responseReceived(%d)", result);
     192              : 
     193            0 :     if (_pPendingCallback == nullptr)
     194              :     {
     195            0 :         ERROR_LOG(SOMEIP, "RpcChannel::responseReceived() no callback");
     196            0 :         return;
     197              :     }
     198              : 
     199            0 :     CallDoneClosure& done = *_pPendingCallback;
     200            0 :     _pPendingCallback     = nullptr;
     201              : 
     202            0 :     done(result);
     203              : }
     204              : 
     205            0 : void RpcChannel::cancelTimeout() { _timeoutExpiredTimeout.cancel(); }
     206              : 
     207            0 : void RpcChannel::setTimeout(::async::ContextType const context, uint32_t timeout)
     208              : {
     209            0 :     async::schedule(
     210              :         context,
     211              :         _timeoutExpiredFunction,
     212            0 :         _timeoutExpiredTimeout,
     213              :         timeout,
     214              :         ::async::TimeUnit::MILLISECONDS);
     215            0 : }
     216              : 
     217              : // private
     218            0 : void RpcChannel::timeoutExpired()
     219              : {
     220            0 :     WARN_LOG(SOMEIP, "RpcChannel::timeoutExpired()");
     221              : 
     222            0 :     if (_pPendingCallback == nullptr)
     223              :     {
     224            0 :         ERROR_LOG(SOMEIP, "RpcChannel::timeoutExpired() no callback");
     225            0 :         return;
     226              :     }
     227              : 
     228            0 :     _sender.requestExpired(*this);
     229              : 
     230            0 :     CallDoneClosure& done = *_pPendingCallback;
     231            0 :     _pPendingCallback     = nullptr;
     232              : 
     233            0 :     done(RPC_TIMEOUT);
     234              : }
     235              : 
     236              : } // namespace someip
     237              : 
     238              : // NOLINTEND(cppcoreguidelines-pro-type-vararg)
        

Generated by: LCOV version 2.0-1