1 // Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6 #include <iomanip>
7 #include <sstream>
8
9 #include <boost/asio/ip/multicast.hpp>
10 #include <vsomeip/internal/logger.hpp>
11
12 #include "../include/endpoint_host.hpp"
13 #include "../include/tp.hpp"
14 #include "../../routing/include/routing_host.hpp"
15 #include "../include/udp_client_endpoint_impl.hpp"
16 #include "../../utility/include/utility.hpp"
17 #include "../../utility/include/byteorder.hpp"
18
19
20 namespace vsomeip_v3 {
21
udp_client_endpoint_impl(const std::shared_ptr<endpoint_host> & _endpoint_host,const std::shared_ptr<routing_host> & _routing_host,const endpoint_type & _local,const endpoint_type & _remote,boost::asio::io_service & _io,const std::shared_ptr<configuration> & _configuration)22 udp_client_endpoint_impl::udp_client_endpoint_impl(
23 const std::shared_ptr<endpoint_host>& _endpoint_host,
24 const std::shared_ptr<routing_host>& _routing_host,
25 const endpoint_type& _local,
26 const endpoint_type& _remote,
27 boost::asio::io_service &_io,
28 const std::shared_ptr<configuration>& _configuration)
29 : udp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local,
30 _remote, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE,
31 _configuration->get_endpoint_queue_limit(
32 _remote.address().to_string(),
33 _remote.port()),
34 _configuration),
35 remote_address_(_remote.address()),
36 remote_port_(_remote.port()),
37 udp_receive_buffer_size_(_configuration->get_udp_receive_buffer_size()),
38 tp_reassembler_(std::make_shared<tp::tp_reassembler>(
39 _configuration->get_max_message_size_unreliable(), _io)) {
40 is_supporting_someip_tp_ = true;
41 }
42
~udp_client_endpoint_impl()43 udp_client_endpoint_impl::~udp_client_endpoint_impl() {
44 std::shared_ptr<endpoint_host> its_host = endpoint_host_.lock();
45 if (its_host) {
46 its_host->release_port(local_.port(), false);
47 }
48 tp_reassembler_->stop();
49 }
50
is_local() const51 bool udp_client_endpoint_impl::is_local() const {
52 return false;
53 }
54
connect()55 void udp_client_endpoint_impl::connect() {
56 std::lock_guard<std::mutex> its_lock(socket_mutex_);
57 boost::system::error_code its_error;
58 socket_->open(remote_.protocol(), its_error);
59 if (!its_error || its_error == boost::asio::error::already_open) {
60 // Enable SO_REUSEADDR to avoid bind problems with services going offline
61 // and coming online again and the user has specified only a small number
62 // of ports in the clients section for one service instance
63 socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error);
64 if (its_error) {
65 VSOMEIP_WARNING << "udp_client_endpoint_impl::connect: couldn't enable "
66 << "SO_REUSEADDR: " << its_error.message()
67 << " local port:" << std::dec << local_.port()
68 << " remote:" << get_address_port_remote();
69 }
70
71 socket_->set_option(boost::asio::socket_base::receive_buffer_size(
72 udp_receive_buffer_size_), its_error);
73 if (its_error) {
74 VSOMEIP_WARNING << "udp_client_endpoint_impl::connect: couldn't set "
75 << "SO_RCVBUF: " << its_error.message()
76 << " to: " << std::dec << udp_receive_buffer_size_
77 << " local port:" << std::dec << local_.port()
78 << " remote:" << get_address_port_remote();
79 }
80
81 boost::asio::socket_base::receive_buffer_size its_option;
82 socket_->get_option(its_option, its_error);
83 #ifdef __linux__
84 // If regular setting of the buffer size did not work, try to force
85 // (requires CAP_NET_ADMIN to be successful)
86 if (its_option.value() < 0
87 || its_option.value() < udp_receive_buffer_size_) {
88 its_error.assign(setsockopt(socket_->native_handle(),
89 SOL_SOCKET, SO_RCVBUFFORCE,
90 &udp_receive_buffer_size_, sizeof(udp_receive_buffer_size_)),
91 boost::system::generic_category());
92 if (!its_error) {
93 VSOMEIP_INFO << "udp_client_endpoint_impl::connect: "
94 << "SO_RCVBUFFORCE successful!";
95 }
96 socket_->get_option(its_option, its_error);
97 }
98 #endif
99 if (its_error) {
100 VSOMEIP_WARNING << "udp_client_endpoint_impl::connect: couldn't get "
101 << "SO_RCVBUF: " << its_error.message()
102 << " local port:" << std::dec << local_.port()
103 << " remote:" << get_address_port_remote();
104 } else {
105 VSOMEIP_INFO << "udp_client_endpoint_impl::connect: SO_RCVBUF is: "
106 << std::dec << its_option.value()
107 << " (" << udp_receive_buffer_size_ << ")"
108 << " local port:" << std::dec << local_.port()
109 << " remote:" << get_address_port_remote();
110 }
111
112 #ifndef _WIN32
113 // If specified, bind to device
114 std::string its_device(configuration_->get_device());
115 if (its_device != "") {
116 if (setsockopt(socket_->native_handle(),
117 SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (socklen_t)its_device.size()) == -1) {
118 VSOMEIP_WARNING << "UDP Client: Could not bind to device \"" << its_device << "\"";
119 }
120 }
121 #endif
122
123 // In case a client endpoint port was configured,
124 // bind to it before connecting
125 if (local_.port() != ILLEGAL_PORT) {
126 boost::system::error_code its_bind_error;
127 socket_->bind(local_, its_bind_error);
128 if(its_bind_error) {
129 VSOMEIP_WARNING << "udp_client_endpoint::connect: "
130 "Error binding socket: " << its_bind_error.message()
131 << " local: " << local_.address().to_string()
132 << ":" << std::dec << local_.port()
133 << " remote:" << get_address_port_remote();
134
135 std::shared_ptr<endpoint_host> its_host = endpoint_host_.lock();
136 if (its_host) {
137 // set new client port depending on service / instance / remote port
138 if (!its_host->on_bind_error(shared_from_this(), remote_port_)) {
139 VSOMEIP_WARNING << "udp_client_endpoint::connect: "
140 "Failed to set new local port for uce: "
141 << " local: " << local_.address().to_string()
142 << ":" << std::dec << local_.port()
143 << " remote:" << get_address_port_remote();
144 } else {
145 local_.port(local_port_);
146 VSOMEIP_INFO << "udp_client_endpoint::connect: "
147 "Using new new local port for uce: "
148 << " local: " << local_.address().to_string()
149 << ":" << std::dec << local_.port()
150 << " remote:" << get_address_port_remote();
151 }
152 }
153
154
155 try {
156 // don't connect on bind error to avoid using a random port
157 strand_.post(std::bind(&client_endpoint_impl::connect_cbk,
158 shared_from_this(), its_bind_error));
159 } catch (const std::exception &e) {
160 VSOMEIP_ERROR << "udp_client_endpoint_impl::connect: "
161 << e.what() << " remote:" << get_address_port_remote();
162 }
163 return;
164 }
165 return;
166 }
167
168 state_ = cei_state_e::CONNECTING;
169 socket_->async_connect(
170 remote_,
171 strand_.wrap(
172 std::bind(
173 &udp_client_endpoint_base_impl::connect_cbk,
174 shared_from_this(),
175 std::placeholders::_1
176 )
177 )
178 );
179 } else {
180 VSOMEIP_WARNING << "udp_client_endpoint::connect: Error opening socket: "
181 << its_error.message() << " remote:" << get_address_port_remote();
182 strand_.post(std::bind(&udp_client_endpoint_base_impl::connect_cbk,
183 shared_from_this(), its_error));
184 }
185 }
186
start()187 void udp_client_endpoint_impl::start() {
188 connect();
189 }
190
restart(bool _force)191 void udp_client_endpoint_impl::restart(bool _force) {
192 if (!_force && state_ == cei_state_e::CONNECTING) {
193 return;
194 }
195 state_ = cei_state_e::CONNECTING;
196 {
197 std::lock_guard<std::mutex> its_lock(mutex_);
198 queue_.clear();
199 }
200 std::string local;
201 {
202 std::lock_guard<std::mutex> its_lock(socket_mutex_);
203 local = get_address_port_local();
204 }
205 shutdown_and_close_socket(false);
206 was_not_connected_ = true;
207 reconnect_counter_ = 0;
208 VSOMEIP_WARNING << "uce::restart: local: " << local
209 << " remote: " << get_address_port_remote();
210 start_connect_timer();
211 }
212
send_queued(message_buffer_ptr_t _buffer)213 void udp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
214 #if 0
215 std::stringstream msg;
216 msg << "ucei<" << remote_.address() << ":"
217 << std::dec << remote_.port() << ">::sq: ";
218 for (std::size_t i = 0; i < _buffer->size(); i++)
219 msg << std::hex << std::setw(2) << std::setfill('0')
220 << (int)(*_buffer)[i] << " ";
221 VSOMEIP_INFO << msg.str();
222 #endif
223 {
224 std::lock_guard<std::mutex> its_lock(socket_mutex_);
225 socket_->async_send(
226 boost::asio::buffer(*_buffer),
227 std::bind(
228 &udp_client_endpoint_base_impl::send_cbk,
229 shared_from_this(),
230 std::placeholders::_1,
231 std::placeholders::_2,
232 _buffer
233 )
234 );
235 }
236 }
237
get_configured_times_from_endpoint(service_t _service,method_t _method,std::chrono::nanoseconds * _debouncing,std::chrono::nanoseconds * _maximum_retention) const238 void udp_client_endpoint_impl::get_configured_times_from_endpoint(
239 service_t _service, method_t _method,
240 std::chrono::nanoseconds *_debouncing,
241 std::chrono::nanoseconds *_maximum_retention) const {
242 configuration_->get_configured_timing_requests(_service,
243 remote_address_.to_string(), remote_port_, _method,
244 _debouncing, _maximum_retention);
245 }
246
receive()247 void udp_client_endpoint_impl::receive() {
248 std::lock_guard<std::mutex> its_lock(socket_mutex_);
249 if (!socket_->is_open()) {
250 return;
251 }
252 message_buffer_ptr_t its_buffer = std::make_shared<message_buffer_t>(VSOMEIP_MAX_UDP_MESSAGE_SIZE);
253 socket_->async_receive_from(
254 boost::asio::buffer(*its_buffer),
255 const_cast<endpoint_type&>(remote_),
256 strand_.wrap(
257 std::bind(
258 &udp_client_endpoint_impl::receive_cbk,
259 std::dynamic_pointer_cast<
260 udp_client_endpoint_impl
261 >(shared_from_this()),
262 std::placeholders::_1,
263 std::placeholders::_2,
264 its_buffer
265 )
266 )
267 );
268 }
269
get_remote_address(boost::asio::ip::address & _address) const270 bool udp_client_endpoint_impl::get_remote_address(
271 boost::asio::ip::address &_address) const {
272 if (remote_address_.is_unspecified()) {
273 return false;
274 }
275 _address = remote_address_;
276 return true;
277 }
278
set_local_port()279 void udp_client_endpoint_impl::set_local_port() {
280 std::lock_guard<std::mutex> its_lock(socket_mutex_);
281 boost::system::error_code its_error;
282 if (socket_->is_open()) {
283 endpoint_type its_endpoint = socket_->local_endpoint(its_error);
284 if (!its_error) {
285 local_port_ = its_endpoint.port();
286 } else {
287 VSOMEIP_WARNING << "udp_client_endpoint_impl::set_local_port() "
288 << " couldn't get local_endpoint: " << its_error.message();
289 }
290 }
291 }
292
get_remote_port() const293 std::uint16_t udp_client_endpoint_impl::get_remote_port() const {
294 return remote_port_;
295 }
296
receive_cbk(boost::system::error_code const & _error,std::size_t _bytes,const message_buffer_ptr_t & _recv_buffer)297 void udp_client_endpoint_impl::receive_cbk(
298 boost::system::error_code const &_error, std::size_t _bytes,
299 const message_buffer_ptr_t& _recv_buffer) {
300 if (_error == boost::asio::error::operation_aborted) {
301 // endpoint was stopped
302 return;
303 }
304 std::shared_ptr<routing_host> its_host = routing_host_.lock();
305 if (!_error && 0 < _bytes && its_host) {
306 #if 0
307 std::stringstream msg;
308 msg << "ucei::rcb(" << _error.message() << "): ";
309 for (std::size_t i = 0; i < _bytes; ++i)
310 msg << std::hex << std::setw(2) << std::setfill('0')
311 << (int) (*_recv_buffer)[i] << " ";
312 VSOMEIP_INFO << msg.str();
313 #endif
314 std::size_t remaining_bytes = _bytes;
315 std::size_t i = 0;
316
317 do {
318 uint64_t read_message_size
319 = utility::get_message_size(&(*_recv_buffer)[i],
320 remaining_bytes);
321 if (read_message_size > MESSAGE_SIZE_UNLIMITED) {
322 VSOMEIP_ERROR << "Message size exceeds allowed maximum!";
323 return;
324 }
325 uint32_t current_message_size = static_cast<uint32_t>(read_message_size);
326 if (current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE &&
327 current_message_size <= remaining_bytes) {
328 if (remaining_bytes - current_message_size > remaining_bytes) {
329 VSOMEIP_ERROR << "buffer underflow in udp client endpoint ~> abort!";
330 return;
331 } else if (current_message_size > VSOMEIP_RETURN_CODE_POS &&
332 ((*_recv_buffer)[i + VSOMEIP_PROTOCOL_VERSION_POS] != VSOMEIP_PROTOCOL_VERSION ||
333 !utility::is_valid_message_type(tp::tp::tp_flag_unset((*_recv_buffer)[i + VSOMEIP_MESSAGE_TYPE_POS])) ||
334 !utility::is_valid_return_code(static_cast<return_code_e>((*_recv_buffer)[i + VSOMEIP_RETURN_CODE_POS]))
335 )) {
336 if ((*_recv_buffer)[i + VSOMEIP_PROTOCOL_VERSION_POS] != VSOMEIP_PROTOCOL_VERSION) {
337 VSOMEIP_ERROR << "uce: Wrong protocol version: 0x"
338 << std::hex << std::setw(2) << std::setfill('0')
339 << std::uint32_t((*_recv_buffer)[i + VSOMEIP_PROTOCOL_VERSION_POS])
340 << " local: " << get_address_port_local()
341 << " remote: " << get_address_port_remote();
342 // ensure to send back a message w/ wrong protocol version
343 its_host->on_message(&(*_recv_buffer)[i],
344 VSOMEIP_SOMEIP_HEADER_SIZE + 8, this,
345 boost::asio::ip::address(),
346 VSOMEIP_ROUTING_CLIENT,
347 std::make_pair(ANY_UID, ANY_GID),
348 remote_address_,
349 remote_port_);
350 } else if (!utility::is_valid_message_type(tp::tp::tp_flag_unset(
351 (*_recv_buffer)[i + VSOMEIP_MESSAGE_TYPE_POS]))) {
352 VSOMEIP_ERROR << "uce: Invalid message type: 0x"
353 << std::hex << std::setw(2) << std::setfill('0')
354 << std::uint32_t((*_recv_buffer)[i + VSOMEIP_MESSAGE_TYPE_POS])
355 << " local: " << get_address_port_local()
356 << " remote: " << get_address_port_remote();
357 } else if (!utility::is_valid_return_code(static_cast<return_code_e>(
358 (*_recv_buffer)[i + VSOMEIP_RETURN_CODE_POS]))) {
359 VSOMEIP_ERROR << "uce: Invalid return code: 0x"
360 << std::hex << std::setw(2) << std::setfill('0')
361 << std::uint32_t((*_recv_buffer)[i + VSOMEIP_RETURN_CODE_POS])
362 << " local: " << get_address_port_local()
363 << " remote: " << get_address_port_remote();
364 }
365 receive();
366 return;
367 } else if (tp::tp::tp_flag_is_set((*_recv_buffer)[i + VSOMEIP_MESSAGE_TYPE_POS])) {
368 const auto res = tp_reassembler_->process_tp_message(
369 &(*_recv_buffer)[i], current_message_size,
370 remote_address_, remote_port_);
371 if (res.first) {
372 its_host->on_message(&res.second[0],
373 static_cast<std::uint32_t>(res.second.size()),
374 this, boost::asio::ip::address(),
375 VSOMEIP_ROUTING_CLIENT,
376 std::make_pair(ANY_UID, ANY_GID),
377 remote_address_,
378 remote_port_);
379 }
380 } else {
381 its_host->on_message(&(*_recv_buffer)[i], current_message_size,
382 this, boost::asio::ip::address(),
383 VSOMEIP_ROUTING_CLIENT,
384 std::make_pair(ANY_UID, ANY_GID),
385 remote_address_,
386 remote_port_);
387 }
388 remaining_bytes -= current_message_size;
389 } else {
390 VSOMEIP_ERROR << "Received a unreliable vSomeIP message with bad "
391 "length field. Message size: " << current_message_size
392 << " Bytes. From: " << remote_.address() << ":"
393 << remote_.port() << ". Dropping message.";
394 remaining_bytes = 0;
395 }
396 i += current_message_size;
397 } while (remaining_bytes > 0);
398 }
399 if (!_error) {
400 receive();
401 } else {
402 if (_error == boost::asio::error::connection_refused) {
403 VSOMEIP_WARNING << "uce::receive_cbk: local: " << get_address_port_local()
404 << " remote: " << get_address_port_remote()
405 << " error: " << _error.message();
406 std::shared_ptr<endpoint_host> its_ep_host = endpoint_host_.lock();
407 its_ep_host->on_disconnect(shared_from_this());
408 restart(false);
409 } else {
410 receive();
411 }
412 }
413 }
414
get_address_port_remote() const415 const std::string udp_client_endpoint_impl::get_address_port_remote() const {
416 boost::system::error_code ec;
417 std::string its_address_port;
418 its_address_port.reserve(21);
419 boost::asio::ip::address its_address;
420 if (get_remote_address(its_address)) {
421 its_address_port += its_address.to_string();
422 }
423 its_address_port += ":";
424 its_address_port += std::to_string(remote_port_);
425 return its_address_port;
426 }
427
get_address_port_local() const428 const std::string udp_client_endpoint_impl::get_address_port_local() const {
429 std::string its_address_port;
430 its_address_port.reserve(21);
431 boost::system::error_code ec;
432 if (socket_->is_open()) {
433 endpoint_type its_local_endpoint = socket_->local_endpoint(ec);
434 if (!ec) {
435 its_address_port += its_local_endpoint.address().to_string(ec);
436 its_address_port += ":";
437 its_address_port.append(std::to_string(its_local_endpoint.port()));
438 }
439 }
440 return its_address_port;
441 }
442
print_status()443 void udp_client_endpoint_impl::print_status() {
444 std::size_t its_data_size(0);
445 std::size_t its_queue_size(0);
446 {
447 std::lock_guard<std::mutex> its_lock(mutex_);
448 its_queue_size = queue_.size();
449 its_data_size = queue_size_;
450 }
451 std::string local;
452 {
453 std::lock_guard<std::mutex> its_lock(socket_mutex_);
454 local = get_address_port_local();
455 }
456
457 VSOMEIP_INFO << "status uce: " << local << " -> "
458 << get_address_port_remote()
459 << " queue: " << std::dec << its_queue_size
460 << " data: " << std::dec << its_data_size;
461 }
462
get_remote_information() const463 std::string udp_client_endpoint_impl::get_remote_information() const {
464 boost::system::error_code ec;
465 return remote_.address().to_string(ec) + ":"
466 + std::to_string(remote_.port());
467 }
468
send_cbk(boost::system::error_code const & _error,std::size_t _bytes,const message_buffer_ptr_t & _sent_msg)469 void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, std::size_t _bytes,
470 const message_buffer_ptr_t &_sent_msg) {
471 (void)_bytes;
472 if (!_error) {
473 std::lock_guard<std::mutex> its_lock(mutex_);
474 if (queue_.size() > 0) {
475 queue_size_ -= queue_.front()->size();
476 queue_.pop_front();
477 auto its_buffer = get_front();
478 if (its_buffer)
479 send_queued(its_buffer);
480 }
481 } else if (_error == boost::asio::error::broken_pipe) {
482 state_ = cei_state_e::CLOSED;
483 bool stopping(false);
484 {
485 std::lock_guard<std::mutex> its_lock(mutex_);
486 stopping = sending_blocked_;
487 if (stopping) {
488 queue_.clear();
489 queue_size_ = 0;
490 } else {
491 service_t its_service(0);
492 method_t its_method(0);
493 client_t its_client(0);
494 session_t its_session(0);
495 if (_sent_msg && _sent_msg->size() > VSOMEIP_SESSION_POS_MAX) {
496 its_service = VSOMEIP_BYTES_TO_WORD(
497 (*_sent_msg)[VSOMEIP_SERVICE_POS_MIN],
498 (*_sent_msg)[VSOMEIP_SERVICE_POS_MAX]);
499 its_method = VSOMEIP_BYTES_TO_WORD(
500 (*_sent_msg)[VSOMEIP_METHOD_POS_MIN],
501 (*_sent_msg)[VSOMEIP_METHOD_POS_MAX]);
502 its_client = VSOMEIP_BYTES_TO_WORD(
503 (*_sent_msg)[VSOMEIP_CLIENT_POS_MIN],
504 (*_sent_msg)[VSOMEIP_CLIENT_POS_MAX]);
505 its_session = VSOMEIP_BYTES_TO_WORD(
506 (*_sent_msg)[VSOMEIP_SESSION_POS_MIN],
507 (*_sent_msg)[VSOMEIP_SESSION_POS_MAX]);
508 }
509 VSOMEIP_WARNING << "uce::send_cbk received error: "
510 << _error.message() << " (" << std::dec
511 << _error.value() << ") " << get_remote_information()
512 << " " << std::dec << queue_.size()
513 << " " << std::dec << queue_size_ << " ("
514 << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): ["
515 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
516 << std::hex << std::setw(4) << std::setfill('0') << its_method << "."
517 << std::hex << std::setw(4) << std::setfill('0') << its_session << "]";
518 }
519 }
520 if (!stopping) {
521 print_status();
522 }
523 was_not_connected_ = true;
524 shutdown_and_close_socket(true);
525 strand_.dispatch(std::bind(&client_endpoint_impl::connect,
526 this->shared_from_this()));
527 } else if (_error == boost::asio::error::not_connected
528 || _error == boost::asio::error::bad_descriptor
529 || _error == boost::asio::error::no_permission) {
530 state_ = cei_state_e::CLOSED;
531 if (_error == boost::asio::error::no_permission) {
532 VSOMEIP_WARNING << "uce::send_cbk received error: " << _error.message()
533 << " (" << std::dec << _error.value() << ") "
534 << get_remote_information();
535 std::lock_guard<std::mutex> its_lock(mutex_);
536 queue_.clear();
537 queue_size_ = 0;
538 }
539 was_not_connected_ = true;
540 shutdown_and_close_socket(true);
541 strand_.dispatch(std::bind(&client_endpoint_impl::connect,
542 this->shared_from_this()));
543 } else if (_error == boost::asio::error::operation_aborted) {
544 VSOMEIP_WARNING << "uce::send_cbk received error: " << _error.message();
545 // endpoint was stopped
546 sending_blocked_ = true;
547 shutdown_and_close_socket(false);
548 } else if (_error == boost::system::errc::destination_address_required) {
549 VSOMEIP_WARNING << "uce::send_cbk received error: " << _error.message()
550 << " (" << std::dec << _error.value() << ") "
551 << get_remote_information();
552 was_not_connected_ = true;
553 } else {
554 if (state_ == cei_state_e::CONNECTING) {
555 VSOMEIP_WARNING << "uce::send_cbk endpoint is already restarting:"
556 << get_remote_information();
557 } else {
558 state_ = cei_state_e::CONNECTING;
559 shutdown_and_close_socket(false);
560 std::shared_ptr<endpoint_host> its_host = endpoint_host_.lock();
561 if (its_host) {
562 its_host->on_disconnect(shared_from_this());
563 }
564 restart(true);
565 }
566 service_t its_service(0);
567 method_t its_method(0);
568 client_t its_client(0);
569 session_t its_session(0);
570 if (_sent_msg && _sent_msg->size() > VSOMEIP_SESSION_POS_MAX) {
571 its_service = VSOMEIP_BYTES_TO_WORD(
572 (*_sent_msg)[VSOMEIP_SERVICE_POS_MIN],
573 (*_sent_msg)[VSOMEIP_SERVICE_POS_MAX]);
574 its_method = VSOMEIP_BYTES_TO_WORD(
575 (*_sent_msg)[VSOMEIP_METHOD_POS_MIN],
576 (*_sent_msg)[VSOMEIP_METHOD_POS_MAX]);
577 its_client = VSOMEIP_BYTES_TO_WORD(
578 (*_sent_msg)[VSOMEIP_CLIENT_POS_MIN],
579 (*_sent_msg)[VSOMEIP_CLIENT_POS_MAX]);
580 its_session = VSOMEIP_BYTES_TO_WORD(
581 (*_sent_msg)[VSOMEIP_SESSION_POS_MIN],
582 (*_sent_msg)[VSOMEIP_SESSION_POS_MAX]);
583 }
584 VSOMEIP_WARNING << "uce::send_cbk received error: " << _error.message()
585 << " (" << std::dec << _error.value() << ") "
586 << get_remote_information() << " "
587 << " " << std::dec << queue_.size()
588 << " " << std::dec << queue_size_ << " ("
589 << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): ["
590 << std::hex << std::setw(4) << std::setfill('0') << its_service << "."
591 << std::hex << std::setw(4) << std::setfill('0') << its_method << "."
592 << std::hex << std::setw(4) << std::setfill('0') << its_session << "]";
593 print_status();
594 }
595 }
596
tp_segmentation_enabled(service_t _service,method_t _method) const597 bool udp_client_endpoint_impl::tp_segmentation_enabled(service_t _service,
598 method_t _method) const {
599 return configuration_->tp_segment_messages_client_to_service(_service,
600 remote_address_.to_string(), remote_port_, _method);
601 }
602
is_reliable() const603 bool udp_client_endpoint_impl::is_reliable() const {
604 return false;
605 }
606
get_max_allowed_reconnects() const607 std::uint32_t udp_client_endpoint_impl::get_max_allowed_reconnects() const {
608 return MAX_RECONNECTS_UNLIMITED;
609 }
610
max_allowed_reconnects_reached()611 void udp_client_endpoint_impl::max_allowed_reconnects_reached() {
612 return;
613 }
614
615 } // namespace vsomeip_v3
616