summaryrefslogtreecommitdiff
path: root/implementation/endpoints/src/udp_client_endpoint_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'implementation/endpoints/src/udp_client_endpoint_impl.cpp')
-rw-r--r--implementation/endpoints/src/udp_client_endpoint_impl.cpp96
1 files changed, 62 insertions, 34 deletions
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
index 3b9a212..5d675f6 100644
--- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
@@ -1,10 +1,11 @@
-// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <iomanip>
#include <sstream>
+#include <thread>
#include <boost/asio/ip/multicast.hpp>
#include <vsomeip/internal/logger.hpp>
@@ -16,7 +17,6 @@
#include "../../utility/include/utility.hpp"
#include "../../utility/include/byteorder.hpp"
-
namespace vsomeip_v3 {
udp_client_endpoint_impl::udp_client_endpoint_impl(
@@ -24,7 +24,7 @@ udp_client_endpoint_impl::udp_client_endpoint_impl(
const std::shared_ptr<routing_host>& _routing_host,
const endpoint_type& _local,
const endpoint_type& _remote,
- boost::asio::io_service &_io,
+ boost::asio::io_context &_io,
const std::shared_ptr<configuration>& _configuration)
: udp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local,
_remote, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE,
@@ -53,6 +53,7 @@ bool udp_client_endpoint_impl::is_local() const {
}
void udp_client_endpoint_impl::connect() {
+ start_connecting_timer();
std::lock_guard<std::mutex> its_lock(socket_mutex_);
boost::system::error_code its_error;
socket_->open(remote_.protocol(), its_error);
@@ -63,11 +64,9 @@ void udp_client_endpoint_impl::connect() {
socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error);
if (its_error) {
VSOMEIP_WARNING << "udp_client_endpoint_impl::connect: couldn't enable "
- << "SO_REUSEADDR: " << its_error.message()
- << " local port:" << std::dec << local_.port()
- << " remote:" << get_address_port_remote();
+ << "SO_REUSEADDR: " << its_error.message() << " remote:"
+ << get_address_port_remote();
}
-
socket_->set_option(boost::asio::socket_base::receive_buffer_size(
udp_receive_buffer_size_), its_error);
if (its_error) {
@@ -109,12 +108,17 @@ void udp_client_endpoint_impl::connect() {
<< " remote:" << get_address_port_remote();
}
-#ifndef _WIN32
+ if (local_.port() == ILLEGAL_PORT) {
+ // Let the OS assign the port
+ local_.port(0);
+ }
+
+#if defined(__linux__) || defined(ANDROID)
// If specified, bind to device
std::string its_device(configuration_->get_device());
if (its_device != "") {
if (setsockopt(socket_->native_handle(),
- SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (socklen_t)its_device.size()) == -1) {
+ SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), socklen_t(its_device.size())) == -1) {
VSOMEIP_WARNING << "UDP Client: Could not bind to device \"" << its_device << "\"";
}
}
@@ -135,7 +139,7 @@ void udp_client_endpoint_impl::connect() {
std::shared_ptr<endpoint_host> its_host = endpoint_host_.lock();
if (its_host) {
// set new client port depending on service / instance / remote port
- if (!its_host->on_bind_error(shared_from_this(), remote_port_)) {
+ if (!its_host->on_bind_error(shared_from_this(), remote_address_, remote_port_)) {
VSOMEIP_WARNING << "udp_client_endpoint::connect: "
"Failed to set new local port for uce: "
<< " local: " << local_.address().to_string()
@@ -162,7 +166,6 @@ void udp_client_endpoint_impl::connect() {
}
return;
}
- return;
}
state_ = cei_state_e::CONNECTING;
@@ -210,26 +213,44 @@ void udp_client_endpoint_impl::restart(bool _force) {
start_connect_timer();
}
-void udp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
+void udp_client_endpoint_impl::send_queued(std::pair<message_buffer_ptr_t, uint32_t> &_entry) {
+ static std::chrono::steady_clock::time_point its_last_sent;
#if 0
std::stringstream msg;
msg << "ucei<" << remote_.address() << ":"
<< std::dec << remote_.port() << ">::sq: ";
for (std::size_t i = 0; i < _buffer->size(); i++)
msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
+ << (int)(*_entry.first)[i] << " ";
VSOMEIP_INFO << msg.str();
#endif
{
std::lock_guard<std::mutex> its_lock(socket_mutex_);
+
+ // Check whether we need to wait (SOME/IP-TP separation time)
+ if (_entry.second > 0) {
+ if (its_last_sent != std::chrono::steady_clock::time_point()) {
+ const auto its_elapsed
+ = std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now() - its_last_sent).count();
+ if (_entry.second > its_elapsed)
+ std::this_thread::sleep_for(
+ std::chrono::microseconds(_entry.second - its_elapsed));
+ }
+ its_last_sent = std::chrono::steady_clock::now();
+ } else {
+ its_last_sent = std::chrono::steady_clock::time_point();
+ }
+
+ // Send
socket_->async_send(
- boost::asio::buffer(*_buffer),
+ boost::asio::buffer(*_entry.first),
std::bind(
&udp_client_endpoint_base_impl::send_cbk,
shared_from_this(),
std::placeholders::_1,
std::placeholders::_2,
- _buffer
+ _entry.first
)
);
}
@@ -342,9 +363,9 @@ void udp_client_endpoint_impl::receive_cbk(
// ensure to send back a message w/ wrong protocol version
its_host->on_message(&(*_recv_buffer)[i],
VSOMEIP_SOMEIP_HEADER_SIZE + 8, this,
- boost::asio::ip::address(),
+ false,
VSOMEIP_ROUTING_CLIENT,
- std::make_pair(ANY_UID, ANY_GID),
+ nullptr,
remote_address_,
remote_port_);
} else if (!utility::is_valid_message_type(tp::tp::tp_flag_unset(
@@ -371,17 +392,19 @@ void udp_client_endpoint_impl::receive_cbk(
if (res.first) {
its_host->on_message(&res.second[0],
static_cast<std::uint32_t>(res.second.size()),
- this, boost::asio::ip::address(),
+ this,
+ false,
VSOMEIP_ROUTING_CLIENT,
- std::make_pair(ANY_UID, ANY_GID),
+ nullptr,
remote_address_,
remote_port_);
}
} else {
its_host->on_message(&(*_recv_buffer)[i], current_message_size,
- this, boost::asio::ip::address(),
+ this,
+ false,
VSOMEIP_ROUTING_CLIENT,
- std::make_pair(ANY_UID, ANY_GID),
+ nullptr,
remote_address_,
remote_port_);
}
@@ -412,8 +435,7 @@ void udp_client_endpoint_impl::receive_cbk(
}
}
-const std::string udp_client_endpoint_impl::get_address_port_remote() const {
- boost::system::error_code ec;
+std::string udp_client_endpoint_impl::get_address_port_remote() const {
std::string its_address_port;
its_address_port.reserve(21);
boost::asio::ip::address its_address;
@@ -425,7 +447,7 @@ const std::string udp_client_endpoint_impl::get_address_port_remote() const {
return its_address_port;
}
-const std::string udp_client_endpoint_impl::get_address_port_local() const {
+std::string udp_client_endpoint_impl::get_address_port_local() const {
std::string its_address_port;
its_address_port.reserve(21);
boost::system::error_code ec;
@@ -466,17 +488,21 @@ std::string udp_client_endpoint_impl::get_remote_information() const {
+ std::to_string(remote_.port());
}
-void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, std::size_t _bytes,
- const message_buffer_ptr_t &_sent_msg) {
+void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error,
+ std::size_t _bytes, const message_buffer_ptr_t &_sent_msg) {
(void)_bytes;
if (!_error) {
std::lock_guard<std::mutex> its_lock(mutex_);
if (queue_.size() > 0) {
- queue_size_ -= queue_.front()->size();
+ queue_size_ -= queue_.front().first->size();
queue_.pop_front();
- auto its_buffer = get_front();
- if (its_buffer)
- send_queued(its_buffer);
+
+ update_last_departure();
+
+ auto its_entry = get_front();
+ if (its_entry.first) {
+ send_queued(its_entry);
+ }
}
} else if (_error == boost::asio::error::broken_pipe) {
state_ = cei_state_e::CLOSED;
@@ -594,10 +620,12 @@ void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error,
}
}
-bool udp_client_endpoint_impl::tp_segmentation_enabled(service_t _service,
- method_t _method) const {
- return configuration_->tp_segment_messages_client_to_service(_service,
- remote_address_.to_string(), remote_port_, _method);
+bool udp_client_endpoint_impl::tp_segmentation_enabled(
+ service_t _service, method_t _method) const {
+
+ return configuration_->is_tp_client(_service,
+ remote_address_.to_string(), remote_port_,
+ _method);
}
bool udp_client_endpoint_impl::is_reliable() const {