summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürgen Gehring <Juergen.Gehring@bmw.de>2016-12-12 03:57:25 -0800
committerJürgen Gehring <Juergen.Gehring@bmw.de>2016-12-12 03:57:25 -0800
commitce34f857850ebf7bff1e4dc6c79574ff75abca56 (patch)
treed74c50b547412cc5dd847508b7d405ccd1520aaf
parent30b6688d9f77d40352cc3cec99052e0946a8affc (diff)
downloadvSomeIP-ce34f857850ebf7bff1e4dc6c79574ff75abca56.tar.gz
vSomeIP 2.5.12.5.1
-rw-r--r--.gitignore2
-rw-r--r--CHANGES18
-rw-r--r--CMakeLists.txt2
-rw-r--r--daemon/vsomeipd.cpp2
-rw-r--r--documentation/vsomeipUserGuide69
-rw-r--r--examples/hello_world/hello_world_client.cpp21
-rw-r--r--examples/hello_world/hello_world_service.cpp18
-rw-r--r--examples/notify-sample.cpp20
-rw-r--r--examples/request-sample.cpp19
-rw-r--r--examples/response-sample.cpp20
-rw-r--r--examples/subscribe-sample.cpp23
-rw-r--r--implementation/configuration/include/configuration.hpp6
-rw-r--r--implementation/configuration/include/configuration_impl.hpp54
-rw-r--r--implementation/configuration/include/internal.hpp.in11
-rw-r--r--implementation/configuration/src/configuration_impl.cpp95
-rw-r--r--implementation/endpoints/include/buffer.hpp2
-rw-r--r--implementation/endpoints/include/client_endpoint.hpp24
-rw-r--r--implementation/endpoints/include/client_endpoint_impl.hpp17
-rw-r--r--implementation/endpoints/include/endpoint.hpp2
-rw-r--r--implementation/endpoints/include/endpoint_host.hpp8
-rw-r--r--implementation/endpoints/include/endpoint_impl.hpp6
-rw-r--r--implementation/endpoints/include/local_client_endpoint_impl.hpp11
-rw-r--r--implementation/endpoints/include/local_server_endpoint_impl.hpp20
-rw-r--r--implementation/endpoints/include/netlink_connector.hpp220
-rw-r--r--implementation/endpoints/include/tcp_client_endpoint_impl.hpp12
-rw-r--r--implementation/endpoints/include/tcp_server_endpoint_impl.hpp23
-rw-r--r--implementation/endpoints/include/udp_client_endpoint_impl.hpp2
-rw-r--r--implementation/endpoints/include/udp_server_endpoint_impl.hpp5
-rw-r--r--implementation/endpoints/src/client_endpoint_impl.cpp38
-rw-r--r--implementation/endpoints/src/endpoint_impl.cpp25
-rw-r--r--implementation/endpoints/src/local_client_endpoint_impl.cpp53
-rw-r--r--implementation/endpoints/src/local_server_endpoint_impl.cpp135
-rw-r--r--implementation/endpoints/src/netlink_connector.cpp262
-rw-r--r--implementation/endpoints/src/server_endpoint_impl.cpp11
-rw-r--r--implementation/endpoints/src/tcp_client_endpoint_impl.cpp137
-rw-r--r--implementation/endpoints/src/tcp_server_endpoint_impl.cpp168
-rw-r--r--implementation/endpoints/src/udp_client_endpoint_impl.cpp72
-rw-r--r--implementation/endpoints/src/udp_server_endpoint_impl.cpp32
-rw-r--r--implementation/helper/boost/asio/detail/socket_ops_ext.hpp2
-rw-r--r--implementation/logging/src/dlt_sink_backend.cpp4
-rw-r--r--implementation/message/include/deserializer.hpp9
-rw-r--r--implementation/message/include/serializer.hpp14
-rw-r--r--implementation/message/src/deserializer.cpp33
-rw-r--r--implementation/message/src/message_header_impl.cpp7
-rw-r--r--implementation/message/src/payload_impl.cpp2
-rw-r--r--implementation/message/src/serializer.cpp117
-rw-r--r--implementation/routing/include/event.hpp1
-rw-r--r--implementation/routing/include/routing_manager_base.hpp24
-rw-r--r--implementation/routing/include/routing_manager_host.hpp2
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp37
-rw-r--r--implementation/routing/include/routing_manager_proxy.hpp8
-rw-r--r--implementation/routing/include/routing_manager_stub.hpp10
-rw-r--r--implementation/routing/include/routing_manager_stub_host.hpp3
-rw-r--r--implementation/routing/src/event.cpp15
-rw-r--r--implementation/routing/src/eventgroupinfo.cpp4
-rw-r--r--implementation/routing/src/routing_manager_base.cpp135
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp465
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp62
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp117
-rw-r--r--implementation/runtime/include/application_impl.hpp3
-rw-r--r--implementation/runtime/include/runtime_impl.hpp6
-rw-r--r--implementation/runtime/src/application_impl.cpp37
-rw-r--r--implementation/runtime/src/runtime_impl.cpp21
-rwxr-xr-ximplementation/service_discovery/include/deserializer.hpp5
-rw-r--r--implementation/service_discovery/include/service_discovery.hpp2
-rw-r--r--implementation/service_discovery/include/service_discovery_impl.hpp10
-rw-r--r--implementation/service_discovery/src/deserializer.cpp9
-rw-r--r--implementation/service_discovery/src/service_discovery_impl.cpp269
-rw-r--r--implementation/tracing/include/trace_header.hpp4
-rw-r--r--implementation/tracing/src/trace_header.cpp65
-rw-r--r--implementation/utility/include/utility.hpp4
-rw-r--r--implementation/utility/src/utility.cpp115
-rw-r--r--interface/vsomeip/defines.hpp6
-rw-r--r--interface/vsomeip/runtime.hpp2
-rw-r--r--test/CMakeLists.txt108
-rw-r--r--test/application_tests/application_test.cpp24
-rw-r--r--test/application_tests/application_test_client.cpp13
-rw-r--r--test/application_tests/application_test_daemon.cpp10
-rw-r--r--test/application_tests/application_test_service.cpp10
-rw-r--r--test/big_payload_tests/big_payload_test_client.cpp173
-rw-r--r--test/big_payload_tests/big_payload_test_client.hpp12
-rwxr-xr-xtest/big_payload_tests/big_payload_test_external_starter.sh29
-rw-r--r--test/big_payload_tests/big_payload_test_globals.hpp17
-rw-r--r--test/big_payload_tests/big_payload_test_local_limited.json42
-rw-r--r--test/big_payload_tests/big_payload_test_local_random.json44
-rwxr-xr-xtest/big_payload_tests/big_payload_test_local_starter.sh22
-rw-r--r--test/big_payload_tests/big_payload_test_service.cpp124
-rw-r--r--test/big_payload_tests/big_payload_test_service.hpp11
-rwxr-xr-xtest/big_payload_tests/big_payload_test_service_external_start.sh17
-rw-r--r--test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in31
-rw-r--r--test/big_payload_tests/conf/big_payload_test_tcp_service.json.in20
-rw-r--r--test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in60
-rwxr-xr-xtest/client_id_tests/client_id_test_master_starter.sh18
-rw-r--r--test/client_id_tests/client_id_test_service.cpp4
-rw-r--r--test/client_id_tests/client_id_test_utility.cpp447
-rw-r--r--test/client_id_tests/client_id_test_utility.json38
-rw-r--r--test/cpu_load_tests/cpu_load_test_client.cpp4
-rwxr-xr-xtest/cpu_load_tests/cpu_load_test_master_starter.sh20
-rw-r--r--test/cpu_load_tests/cpu_load_test_service.cpp14
-rwxr-xr-xtest/cpu_load_tests/cpu_load_test_slave_starter.sh2
-rw-r--r--test/header_factory_tests/header_factory_test_client.cpp14
-rw-r--r--test/header_factory_tests/header_factory_test_client.hpp2
-rw-r--r--test/header_factory_tests/header_factory_test_service.cpp14
-rw-r--r--test/header_factory_tests/header_factory_test_service.hpp2
-rw-r--r--test/initial_event_tests/initial_event_test_availability_checker.cpp4
-rw-r--r--test/initial_event_tests/initial_event_test_client.cpp4
-rwxr-xr-xtest/initial_event_tests/initial_event_test_master_starter.sh6
-rw-r--r--test/initial_event_tests/initial_event_test_service.cpp4
-rw-r--r--test/initial_event_tests/initial_event_test_stop_service.cpp4
-rw-r--r--test/magic_cookies_tests/magic_cookies_test_client.cpp50
-rw-r--r--test/magic_cookies_tests/magic_cookies_test_service.cpp30
-rwxr-xr-xtest/magic_cookies_tests/magic_cookies_test_starter.sh26
-rwxr-xr-xtest/offer_tests/conf/offer_test_external_master_starter.sh.in38
-rw-r--r--test/offer_tests/offer_test_client.cpp4
-rw-r--r--test/offer_tests/offer_test_service.cpp4
-rw-r--r--test/offer_tests/offer_test_service_external.cpp4
-rwxr-xr-xtest/payload_tests/external_local_payload_test_client_external_starter.sh28
-rwxr-xr-xtest/payload_tests/external_local_payload_test_client_local_and_external_starter.sh27
-rwxr-xr-xtest/payload_tests/local_payload_test_huge_payload_starter.sh43
-rw-r--r--test/payload_tests/payload_test_client.cpp57
-rw-r--r--test/payload_tests/payload_test_client.hpp2
-rw-r--r--test/payload_tests/payload_test_service.cpp27
-rw-r--r--test/payload_tests/payload_test_service.hpp2
-rw-r--r--test/readme.txt7
-rw-r--r--test/routing_tests/external_local_routing_test_service.cpp14
-rw-r--r--test/routing_tests/external_local_routing_test_service.hpp2
-rwxr-xr-xtest/routing_tests/external_local_routing_test_starter.sh8
-rw-r--r--test/routing_tests/local_routing_test_client.cpp14
-rw-r--r--test/routing_tests/local_routing_test_client.hpp2
-rw-r--r--test/routing_tests/local_routing_test_service.cpp14
-rw-r--r--test/routing_tests/local_routing_test_service.hpp2
-rwxr-xr-xtest/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh8
-rw-r--r--test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp23
-rwxr-xr-xtest/subscribe_notify_tests/subscribe_notify_test_master_starter.sh8
-rw-r--r--test/subscribe_notify_tests/subscribe_notify_test_service.cpp14
-rw-r--r--tools/vsomeip_ctrl.cpp7
136 files changed, 3950 insertions, 1177 deletions
diff --git a/.gitignore b/.gitignore
index 313f04c..1a92f25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,8 @@
/test/application_tests/application_test_no_dispatch_threads_daemon.json
/test/big_payload_tests/big_payload_test_tcp_client.json
/test/big_payload_tests/big_payload_test_tcp_service.json
+/test/big_payload_tests/big_payload_test_tcp_client_random.json
+/test/big_payload_tests/big_payload_test_tcp_service_random.json
/test/magic_cookies_tests/magic_cookies_test_client.json
/test/magic_cookies_tests/magic_cookies_test_service.json
/test/payload_tests/external_local_payload_test_client_external.json
diff --git a/CHANGES b/CHANGES
index 3f50503..307f64c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -242,3 +242,21 @@ v2.5.0
sending out the offers of the same service instance with a too high frequency.
The default debounce time is set to 500ms. It can be changed via the new json
file parameter service-discovery/offer_debounce_time.
+
+v2.5.1
+- Removed payload size limit. By default messages with an arbitrary length can
+ now be sent locally and via TCP. The payload-sizes configuration file array is
+ now used to limit the payload size for the specified endpoints instead of
+ increasing it. There are two new configuration file parameters:
+ - max-payload-size-local: limit maximum allowed payload size for node internal
+ communication.
+ - buffer-shrink-threshold: variable to control buffer memory deallocation
+ after big messages have been processed. For more information see the
+ vsomeipUserGuide.
+- Fixed cleanup of endpoints for subscriptions using an exclusive proxy
+ (selective) which unnecessarily increased the number of open file descriptors.
+- Fixed assignment of predefined application IDs via autoconfiguration.
+- Decouple start of routing manager from network availability.
+- Made number of internal threads per application configurable.
+- Postpone notify_one events sent from subscription handler to ensure correct
+ message order on receiver side.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1b0fd39..efdd3b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ project (vsomeip)
set (VSOMEIP_MAJOR_VERSION 2)
set (VSOMEIP_MINOR_VERSION 5)
-set (VSOMEIP_PATCH_VERSION 0)
+set (VSOMEIP_PATCH_VERSION 1)
set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION})
set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentatin/doxygen.in
set (CMAKE_VERBOSE_MAKEFILE off)
diff --git a/daemon/vsomeipd.cpp b/daemon/vsomeipd.cpp
index 397abe9..d79b300 100644
--- a/daemon/vsomeipd.cpp
+++ b/daemon/vsomeipd.cpp
@@ -29,7 +29,7 @@ void vsomeipd_stop(int _signal) {
if (_signal == SIGINT || _signal == SIGTERM)
its_application->stop();
if (_signal == SIGABRT) {
- VSOMEIP_DEBUG << "Suspending service discovery";
+ VSOMEIP_INFO << "Suspending service discovery";
its_application->set_routing_state(vsomeip::routing_state_e::RS_SUSPENDED);
its_application->stop();
}
diff --git a/documentation/vsomeipUserGuide b/documentation/vsomeipUserGuide
index 491a136..059992a 100644
--- a/documentation/vsomeipUserGuide
+++ b/documentation/vsomeipUserGuide
@@ -385,6 +385,11 @@ The maximum time that an application callback may consume before the callback is
considered to be blocked (and an additional thread is used to execute pending
callbacks if max_dispatchers is configured greater than 0).
+
+** 'threads' (optional)
++
+The number of internal threads to process messages and events within an application.
+Valid values are 1-255. Default is 2.
++
* `services` (array)
+
Contains the services of the service provider.
@@ -518,40 +523,62 @@ service instance.
* `payload-sizes` (array)
+
-Array to specify the maximum allowed payload sizes per IP and port. If not
-specified, or a smaller value than the default values is specified, the default
-values are used. The settings in this array only affect communication over TCP
-and local communication over UNIX domain sockets.
+Array to limit the maximum allowed payload sizes per IP and port. If not
+specified otherwise the allowed payload sizes are unlimited. The settings in
+this array only affect communication over TCP. To limit the local payload size
+`max-payload-size-local` can be used.
** `unicast`
+
-On client side: the IP of the remote service to which the oversized messages
-should be sent.
-On service side: the IP of the offered service which should receive the
-oversized messages and is allowed to respond with oversized messages.
-If client and service only communicate locally, any IP can be entered here as
-for local communication only the maximum specified payload size is relevant.
+On client side: the IP of the remote service for which the payload size should
+be limited.
++
+On service side: the IP of the offered service for which the payload size for
+receiving and sending should be limited.
** `ports` (array)
+
-Array which holds pairs of port and payload-size statements.
+Array which holds pairs of port and payload size statements.
*** `port`
+
-On client side: the port of the remote service to which the oversized messages
-should be sent.
-On service side: the port of the offered service which should receive the
-oversized messages and is allowed to respond with oversized messages.
-If client and service only communicate locally, any port number can be entered.
+On client side: the port of the remote service for which the payload size should
+be limited.
++
+On service side: the port of the offered service for which the payload size for
+receiving and sending should be limited.
*** `max-payload-size`
+
-On client side: the maximum payload size in bytes of a message sent to the
+On client side: the payload size limit in bytes of a message sent to the
remote service hosted on beforehand specified IP and port.
-On service side: the maximum payload size in bytes of messages received by the
-service offered on previously specified IP and port. If multiple services are
-hosted on the same port all of them are allowed to receive oversized messages
-and send oversized responses.
++
+On service side: the payload size limit in bytes of messages received and sent
+by the service offered on previously specified IP and port.
++
+If multiple services are hosted on the same port all they share the limit
+specified.
+
+* `max-payload-size-local`
++
+The maximum allowed payload size for node internal communication in bytes. By
+default the payload size for node internal communication is unlimited. It can be
+limited via this setting.
+
+* `buffer-shrink-threshold`
++
+The number of processed messages which are half the size or smaller than the
+allocated buffer used to process them before the memory for the buffer is
+released and starts to grow dynamically again. This setting can be useful in
+scenarios where only a small number of the overall messages are a lot bigger
+then the rest and the memory allocated to process them should be released in a
+timely manner. If not specified via this setting the buffer sizes by default
+aren't reseted and are as big as the biggest processed message.
++
+Example: `buffer-shrink-threshold` is set to 50. A message with 500 bytes has to
+be processed and the buffers grow accordingly. After this message 50 consecutive
+messages smaller than 250 bytes have to be processed before the buffer size is
+reduced and starts to grow dynamically again.
* `internal_services` (optional array)
+
diff --git a/examples/hello_world/hello_world_client.cpp b/examples/hello_world/hello_world_client.cpp
index 8d5b33c..0854cc7 100644
--- a/examples/hello_world/hello_world_client.cpp
+++ b/examples/hello_world/hello_world_client.cpp
@@ -24,9 +24,12 @@ public:
{
}
- void init(){
+ bool init(){
// init the application
- app_->init();
+ if (!app_->init()) {
+ std::cerr << "Couldn't initialize application" << std::endl;
+ return false;
+ }
// register a state handler to get called back after registration at the
// runtime was successful
@@ -45,6 +48,7 @@ public:
std::bind(&hello_world_client::on_availability_cbk, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
+ return true;
}
void start()
@@ -118,6 +122,10 @@ public:
// unregister the message handler
app_->unregister_message_handler(vsomeip::ANY_SERVICE,
service_instance_id, vsomeip::ANY_METHOD);
+ // alternatively unregister all registered handlers at once
+ app_->clear_all_handler();
+ // release the service
+ app_->release_service(service_id, service_instance_id);
// shutdown the application
app_->stop();
}
@@ -144,7 +152,10 @@ int main(int argc, char **argv)
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
#endif
- hw_cl.init();
- hw_cl.start();
- return 0;
+ if (hw_cl.init()) {
+ hw_cl.start();
+ return 0;
+ } else {
+ return 1;
+ }
}
diff --git a/examples/hello_world/hello_world_service.cpp b/examples/hello_world/hello_world_service.cpp
index 7e6b615..0692b86 100644
--- a/examples/hello_world/hello_world_service.cpp
+++ b/examples/hello_world/hello_world_service.cpp
@@ -10,6 +10,7 @@
#include <thread>
#include <condition_variable>
#include <mutex>
+#include <iostream>
static vsomeip::service_t service_id = 0x1111;
static vsomeip::instance_t service_instance_id = 0x2222;
@@ -34,10 +35,13 @@ public:
stop_thread_.join();
}
- void init()
+ bool init()
{
// init the application
- app_->init();
+ if (!app_->init()) {
+ std::cerr << "Couldn't initialize application" << std::endl;
+ return false;
+ }
// register a message handler callback for messages sent to our service
app_->register_message_handler(service_id, service_instance_id,
@@ -50,6 +54,7 @@ public:
app_->register_state_handler(
std::bind(&hello_world_service::on_state_cbk, this,
std::placeholders::_1));
+ return true;
}
void start()
@@ -141,7 +146,10 @@ int main(int argc, char **argv)
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
#endif
- hw_srv.init();
- hw_srv.start();
- return 0;
+ if (hw_srv.init()) {
+ hw_srv.start();
+ return 0;
+ } else {
+ return 1;
+ }
}
diff --git a/examples/notify-sample.cpp b/examples/notify-sample.cpp
index 172bf7d..bead4ba 100644
--- a/examples/notify-sample.cpp
+++ b/examples/notify-sample.cpp
@@ -30,10 +30,13 @@ public:
notify_thread_(std::bind(&service_sample::notify, this)) {
}
- void init() {
+ bool init() {
std::lock_guard<std::mutex> its_lock(mutex_);
- app_->init();
+ if (!app_->init()) {
+ std::cerr << "Couldn't initialize application" << std::endl;
+ return false;
+ }
app_->register_state_handler(
std::bind(&service_sample::on_state, this,
std::placeholders::_1));
@@ -64,6 +67,7 @@ public:
blocked_ = true;
condition_.notify_one();
+ return true;
}
void start() {
@@ -79,6 +83,8 @@ public:
blocked_ = true;
condition_.notify_one();
notify_condition_.notify_one();
+ app_->clear_all_handler();
+ stop_offer();
offer_thread_.join();
notify_thread_.join();
app_->stop();
@@ -245,8 +251,10 @@ int main(int argc, char **argv) {
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
#endif
- its_sample.init();
- its_sample.start();
-
- return 0;
+ if (its_sample.init()) {
+ its_sample.start();
+ return 0;
+ } else {
+ return 1;
+ }
}
diff --git a/examples/request-sample.cpp b/examples/request-sample.cpp
index 93b8f0e..910c69e 100644
--- a/examples/request-sample.cpp
+++ b/examples/request-sample.cpp
@@ -30,8 +30,11 @@ public:
sender_(std::bind(&client_sample::run, this)) {
}
- void init() {
- app_->init();
+ bool init() {
+ if (!app_->init()) {
+ std::cerr << "Couldn't initialize application" << std::endl;
+ return false;
+ }
std::cout << "Client settings [protocol="
<< (use_tcp_ ? "TCP" : "UDP")
@@ -73,6 +76,7 @@ public:
std::bind(&client_sample::on_availability,
this,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
+ return true;
}
void start() {
@@ -86,6 +90,8 @@ public:
void stop() {
running_ = false;
blocked_ = true;
+ app_->clear_all_handler();
+ app_->release_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
condition_.notify_one();
sender_.join();
app_->stop();
@@ -222,7 +228,10 @@ int main(int argc, char **argv) {
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
#endif
- its_sample.init();
- its_sample.start();
- return 0;
+ if (its_sample.init()) {
+ its_sample.start();
+ return 0;
+ } else {
+ return 1;
+ }
}
diff --git a/examples/response-sample.cpp b/examples/response-sample.cpp
index 883d821..0d947c3 100644
--- a/examples/response-sample.cpp
+++ b/examples/response-sample.cpp
@@ -27,10 +27,13 @@ public:
offer_thread_(std::bind(&service_sample::run, this)) {
}
- void init() {
+ bool init() {
std::lock_guard<std::mutex> its_lock(mutex_);
- app_->init();
+ if (!app_->init()) {
+ std::cerr << "Couldn't initialize application" << std::endl;
+ return false;
+ }
app_->register_state_handler(
std::bind(&service_sample::on_state, this,
std::placeholders::_1));
@@ -41,6 +44,7 @@ public:
std::cout << "Static routing " << (use_static_routing_ ? "ON" : "OFF")
<< std::endl;
+ return true;
}
void start() {
@@ -54,6 +58,8 @@ public:
void stop() {
running_ = false;
blocked_ = true;
+ app_->clear_all_handler();
+ stop_offer();
condition_.notify_one();
offer_thread_.join();
app_->stop();
@@ -172,8 +178,10 @@ int main(int argc, char **argv) {
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
#endif
- its_sample.init();
- its_sample.start();
-
- return 0;
+ if (its_sample.init()) {
+ its_sample.start();
+ return 0;
+ } else {
+ return 1;
+ }
}
diff --git a/examples/subscribe-sample.cpp b/examples/subscribe-sample.cpp
index 38b80c8..ab82df9 100644
--- a/examples/subscribe-sample.cpp
+++ b/examples/subscribe-sample.cpp
@@ -23,9 +23,11 @@ public:
_use_tcp) {
}
- void init() {
- app_->init();
-
+ bool init() {
+ if (!app_->init()) {
+ std::cerr << "Couldn't initialize application" << std::endl;
+ return false;
+ }
std::cout << "Client settings [protocol="
<< (use_tcp_ ? "TCP" : "UDP")
<< "]"
@@ -53,6 +55,7 @@ public:
SAMPLE_EVENT_ID,
its_groups,
true);
+ return true;
}
void start() {
@@ -64,6 +67,10 @@ public:
* Handle signal to shutdown
*/
void stop() {
+ app_->clear_all_handler();
+ app_->unsubscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
+ app_->release_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID);
+ app_->release_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
app_->stop();
}
#endif
@@ -142,7 +149,6 @@ public:
private:
std::shared_ptr< vsomeip::application > app_;
bool use_tcp_;
- bool be_quiet_;
};
#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
@@ -176,7 +182,10 @@ int main(int argc, char **argv) {
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
#endif
- its_sample.init();
- its_sample.start();
- return 0;
+ if (its_sample.init()) {
+ its_sample.start();
+ return 0;
+ } else {
+ return 1;
+ }
}
diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp
index 4a99ec3..75e7e55 100644
--- a/implementation/configuration/include/configuration.hpp
+++ b/implementation/configuration/include/configuration.hpp
@@ -57,8 +57,8 @@ public:
virtual bool is_someip(service_t _service, instance_t _instance) const = 0;
virtual bool get_client_port(
- service_t _service, instance_t _instance, bool _reliable,
- std::map<bool, std::set<uint16_t> > &_used, uint16_t &_port) const = 0;
+ service_t _service, instance_t _instance, bool _reliable,
+ std::map<bool, std::set<uint16_t> > &_used, uint16_t &_port) const = 0;
virtual std::set<std::pair<service_t, instance_t> > get_remote_services() const = 0;
@@ -73,10 +73,12 @@ public:
virtual std::size_t get_max_dispatchers(const std::string &_name) const = 0;
virtual std::size_t get_max_dispatch_time(const std::string &_name) const = 0;
+ virtual std::size_t get_io_thread_count(const std::string &_name) const = 0;
virtual std::uint32_t get_max_message_size_local() const = 0;
virtual std::uint32_t get_message_size_reliable(const std::string& _address,
std::uint16_t _port) const = 0;
+ virtual std::uint32_t get_buffer_shrink_threshold() const = 0;
virtual bool supports_selective_broadcasts(boost::asio::ip::address _address) const = 0;
diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp
index 0dfc382..584a69a 100644
--- a/implementation/configuration/include/configuration_impl.hpp
+++ b/implementation/configuration/include/configuration_impl.hpp
@@ -70,7 +70,7 @@ public:
VSOMEIP_EXPORT bool is_someip(service_t _service, instance_t _instance) const;
VSOMEIP_EXPORT bool get_client_port(service_t _service, instance_t _instance, bool _reliable,
- std::map<bool, std::set<uint16_t> > &_used, uint16_t &_port) const;
+ std::map<bool, std::set<uint16_t> > &_used, uint16_t &_port) const;
VSOMEIP_EXPORT const std::string & get_routing_host() const;
@@ -79,6 +79,7 @@ public:
VSOMEIP_EXPORT std::size_t get_max_dispatchers(const std::string &_name) const;
VSOMEIP_EXPORT std::size_t get_max_dispatch_time(const std::string &_name) const;
+ VSOMEIP_EXPORT std::size_t get_io_thread_count(const std::string &_name) const;
VSOMEIP_EXPORT std::set<std::pair<service_t, instance_t> > get_remote_services() const;
@@ -91,6 +92,7 @@ public:
VSOMEIP_EXPORT std::uint32_t get_max_message_size_local() const;
VSOMEIP_EXPORT std::uint32_t get_message_size_reliable(const std::string& _address,
std::uint16_t _port) const;
+ VSOMEIP_EXPORT std::uint32_t get_buffer_shrink_threshold() const;
VSOMEIP_EXPORT bool supports_selective_broadcasts(boost::asio::ip::address _address) const;
@@ -225,7 +227,7 @@ protected:
std::string logfile_;
boost::log::trivial::severity_level loglevel_;
- std::map<std::string, std::tuple<client_t, std::size_t, std::size_t>> applications_;
+ std::map<std::string, std::tuple<client_t, std::size_t, std::size_t, size_t>> applications_;
std::set<client_t> client_identifiers_;
std::map<service_t,
@@ -233,8 +235,8 @@ protected:
std::shared_ptr<service> > > services_;
std::map<service_t,
- std::map<instance_t,
- std::shared_ptr<client> > > clients_;
+ std::map<instance_t,
+ std::shared_ptr<client> > > clients_;
std::string routing_host_;
@@ -256,6 +258,8 @@ protected:
std::map<std::string, std::map<std::uint16_t, std::uint32_t>> message_sizes_;
std::uint32_t max_configured_message_size_;
+ std::uint32_t max_local_message_size_;
+ std::uint32_t buffer_shrink_threshold_;
std::shared_ptr<trace> trace_;
@@ -271,27 +275,27 @@ protected:
enum element_type_e {
ET_UNICAST,
ET_DIAGNOSIS,
- ET_LOGGING_CONSOLE,
- ET_LOGGING_FILE,
- ET_LOGGING_DLT,
- ET_LOGGING_LEVEL,
- ET_ROUTING,
- ET_SERVICE_DISCOVERY_ENABLE,
- ET_SERVICE_DISCOVERY_PROTOCOL,
- ET_SERVICE_DISCOVERY_MULTICAST,
- ET_SERVICE_DISCOVERY_PORT,
- ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN,
- ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX,
- ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY,
- ET_SERVICE_DISCOVERY_REPETITION_MAX,
- ET_SERVICE_DISCOVERY_TTL,
- ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY,
- ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY,
- ET_WATCHDOG_ENABLE,
- ET_WATCHDOG_TIMEOUT,
- ET_WATCHDOG_ALLOWED_MISSING_PONGS,
- ET_TRACING_ENABLE,
- ET_TRACING_SD_ENABLE,
+ ET_LOGGING_CONSOLE,
+ ET_LOGGING_FILE,
+ ET_LOGGING_DLT,
+ ET_LOGGING_LEVEL,
+ ET_ROUTING,
+ ET_SERVICE_DISCOVERY_ENABLE,
+ ET_SERVICE_DISCOVERY_PROTOCOL,
+ ET_SERVICE_DISCOVERY_MULTICAST,
+ ET_SERVICE_DISCOVERY_PORT,
+ ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN,
+ ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX,
+ ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY,
+ ET_SERVICE_DISCOVERY_REPETITION_MAX,
+ ET_SERVICE_DISCOVERY_TTL,
+ ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY,
+ ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY,
+ ET_WATCHDOG_ENABLE,
+ ET_WATCHDOG_TIMEOUT,
+ ET_WATCHDOG_ALLOWED_MISSING_PONGS,
+ ET_TRACING_ENABLE,
+ ET_TRACING_SD_ENABLE,
ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME,
ET_MAX = 24
};
diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in
index 766a3f6..ca5a76c 100644
--- a/implementation/configuration/include/internal.hpp.in
+++ b/implementation/configuration/include/internal.hpp.in
@@ -7,6 +7,7 @@
#define VSOMEIP_INTERNAL_HPP
#include <cstdint>
+#include <limits>
#define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME"
#define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION"
@@ -48,6 +49,8 @@
#define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000
#define VSOMEIP_DEFAULT_MAX_MISSING_PONGS 3
+#define VSOMEIP_IO_THREAD_COUNT 2
+
#define VSOMEIP_MAX_DISPATCHERS 10
#define VSOMEIP_MAX_DISPATCH_TIME 100
@@ -127,6 +130,14 @@ struct configuration_data_t {
unsigned short routing_manager_host_;
};
+#ifndef WIN32
+constexpr std::uint32_t MESSAGE_SIZE_UNLIMITED = std::numeric_limits<std::uint32_t>::max();
+#elif _MSC_VER >= 1900
+constexpr std::uint32_t MESSAGE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)();
+#else
+const std::uint32_t MESSAGE_SIZE_UNLIMITED = (std::numeric_limits<std::uint32_t>::max)();
+#endif
+
} // namespace vsomeip
#endif // VSOMEIP_INTERNAL_HPP
diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp
index c4fefb9..3c8d90b 100644
--- a/implementation/configuration/src/configuration_impl.cpp
+++ b/implementation/configuration/src/configuration_impl.cpp
@@ -8,6 +8,7 @@
#include <functional>
#include <set>
#include <sstream>
+#include <limits>
#define WIN32_LEAN_AND_MEAN
@@ -58,6 +59,8 @@ configuration_impl::configuration_impl()
sd_request_response_delay_(VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY),
sd_offer_debounce_time_(VSOMEIP_SD_DEFAULT_OFFER_DEBOUNCE_TIME),
max_configured_message_size_(0),
+ max_local_message_size_(0),
+ buffer_shrink_threshold_(0),
trace_(std::make_shared<trace>()),
watchdog_(std::make_shared<watchdog>()),
log_version_(true),
@@ -76,7 +79,9 @@ configuration_impl::configuration_impl(const configuration_impl &_other)
is_loaded_(_other.is_loaded_),
is_logging_loaded_(_other.is_logging_loaded_),
mandatory_(_other.mandatory_),
- max_configured_message_size_(0),
+ max_configured_message_size_(_other.max_configured_message_size_),
+ max_local_message_size_(_other.max_local_message_size_),
+ buffer_shrink_threshold_(_other.buffer_shrink_threshold_),
permissions_shm_(VSOMEIP_DEFAULT_SHM_PERMISSION),
umask_(VSOMEIP_DEFAULT_UMASK_LOCAL_ENDPOINTS) {
@@ -209,7 +214,7 @@ bool configuration_impl::load(const std::string &_name) {
set_magic_cookies_unicast_address();
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
- VSOMEIP_DEBUG << "Parsed vsomeip configuration in "
+ VSOMEIP_INFO << "Parsed vsomeip configuration in "
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count()
<< "ms";
@@ -435,6 +440,7 @@ void configuration_impl::load_application_data(
client_t its_id(0);
std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS);
std::size_t its_max_dispatch_time(VSOMEIP_MAX_DISPATCH_TIME);
+ std::size_t its_io_thread_count(VSOMEIP_IO_THREAD_COUNT);
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
std::string its_key(i->first);
std::string its_value(i->second.data());
@@ -454,13 +460,24 @@ void configuration_impl::load_application_data(
} else if (its_key == "max_dispatch_time") {
its_converter << std::dec << its_value;
its_converter >> its_max_dispatch_time;
+ } else if (its_key == "threads") {
+ its_converter << std::dec << its_value;
+ its_converter >> its_io_thread_count;
+ if (its_io_thread_count == 0) {
+ VSOMEIP_WARNING << "Min. number of threads per application is 1";
+ its_io_thread_count = 1;
+ } else if (its_io_thread_count > 255) {
+ VSOMEIP_WARNING << "Max. number of threads per application is 255";
+ its_io_thread_count = 255;
+ }
}
}
- if (its_name != "" && its_id != 0) {
+ if (its_name != "") {
if (applications_.find(its_name) == applications_.end()) {
if (!is_configured_client_id(its_id)) {
applications_[its_name]
- = std::make_tuple(its_id, its_max_dispatchers, its_max_dispatch_time);
+ = std::make_tuple(its_id, its_max_dispatchers,
+ its_max_dispatch_time, its_io_thread_count);
client_identifiers_.insert(its_id);
} else {
VSOMEIP_WARNING << "Multiple configurations for application "
@@ -1258,7 +1275,32 @@ void configuration_impl::load_watchdog(const element &_element) {
void configuration_impl::load_payload_sizes(const element &_element) {
const std::string payload_sizes("payload-sizes");
+ const std::string max_local_payload_size("max-payload-size-local");
+ const std::string buffer_shrink_threshold("buffer-shrink-threshold");
try {
+ if (_element.tree_.get_child_optional(max_local_payload_size)) {
+ auto mpsl = _element.tree_.get_child(max_local_payload_size);
+ std::string s(mpsl.data());
+ try {
+ // add 16 Byte for the SOME/IP header
+ max_local_message_size_ = static_cast<std::uint32_t>(std::stoul(
+ s.c_str(), NULL, 10) + 16);
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR<< __func__ << ": " << max_local_payload_size
+ << " " << e.what();
+ }
+ }
+ if (_element.tree_.get_child_optional(buffer_shrink_threshold)) {
+ auto bst = _element.tree_.get_child(buffer_shrink_threshold);
+ std::string s(bst.data());
+ try {
+ buffer_shrink_threshold_ = static_cast<std::uint32_t>(
+ std::stoul(s.c_str(), NULL, 10));
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR<< __func__ << ": " << buffer_shrink_threshold
+ << " " << e.what();
+ }
+ }
if (_element.tree_.get_child_optional(payload_sizes)) {
const std::string unicast("unicast");
const std::string ports("ports");
@@ -1298,13 +1340,23 @@ void configuration_impl::load_payload_sizes(const element &_element) {
if (its_port == ILLEGAL_PORT || its_message_size == 0) {
continue;
}
- if(max_configured_message_size_ < its_message_size) {
+ if (max_configured_message_size_ < its_message_size) {
max_configured_message_size_ = its_message_size;
}
message_sizes_[its_unicast][its_port] = its_message_size;
}
}
+ if (max_local_message_size_ != 0
+ && max_configured_message_size_ != 0
+ && max_configured_message_size_ > max_local_message_size_) {
+ VSOMEIP_WARNING << max_local_payload_size
+ << " is configured smaller than the biggest payloadsize"
+ << " for external communication. "
+ << max_local_payload_size << " will be increased to "
+ << max_configured_message_size_ - 16 << " to ensure "
+ << "local message distribution.";
+ }
}
} catch (...) {
}
@@ -1741,6 +1793,17 @@ bool configuration_impl::is_configured_client_id(client_t _id) const {
return (client_identifiers_.find(_id) != client_identifiers_.end());
}
+std::size_t configuration_impl::get_io_thread_count(const std::string &_name) const {
+ std::size_t its_io_thread_count = VSOMEIP_IO_THREAD_COUNT;
+
+ auto found_application = applications_.find(_name);
+ if (found_application != applications_.end()) {
+ its_io_thread_count = std::get<3>(found_application->second);
+ }
+
+ return its_io_thread_count;
+}
+
std::size_t configuration_impl::get_max_dispatchers(
const std::string &_name) const {
std::size_t its_max_dispatchers = VSOMEIP_MAX_DISPATCHERS;
@@ -1906,14 +1969,22 @@ std::shared_ptr<eventgroup> configuration_impl::find_eventgroup(
}
std::uint32_t configuration_impl::get_max_message_size_local() const {
- uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size) {
+ if (max_local_message_size_ == 0
+ && (VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0
+ || VSOMEIP_MAX_TCP_MESSAGE_SIZE == 0)) {
+ // no limit specified in configuration file and
+ // defines are set to unlimited
+ return MESSAGE_SIZE_UNLIMITED;
+ }
+
+ uint32_t its_max_message_size = max_local_message_size_;
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE >= its_max_message_size) {
its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
}
if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size) {
its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
}
- if(its_max_message_size < max_configured_message_size_) {
+ if (its_max_message_size < max_configured_message_size_) {
its_max_message_size = max_configured_message_size_;
}
@@ -1933,7 +2004,13 @@ std::uint32_t configuration_impl::get_message_size_reliable(
return its_port->second;
}
}
- return VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+ return (VSOMEIP_MAX_TCP_MESSAGE_SIZE == 0) ?
+ MESSAGE_SIZE_UNLIMITED :
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+}
+
+std::uint32_t configuration_impl::get_buffer_shrink_threshold() const {
+ return buffer_shrink_threshold_;
}
bool configuration_impl::supports_selective_broadcasts(boost::asio::ip::address _address) const {
diff --git a/implementation/endpoints/include/buffer.hpp b/implementation/endpoints/include/buffer.hpp
index 1dac89a..e9bb811 100644
--- a/implementation/endpoints/include/buffer.hpp
+++ b/implementation/endpoints/include/buffer.hpp
@@ -14,8 +14,6 @@
namespace vsomeip {
-typedef std::vector<byte_t> receive_buffer_t;
-
typedef std::vector<byte_t> message_buffer_t;
typedef std::shared_ptr<message_buffer_t> message_buffer_ptr_t;
diff --git a/implementation/endpoints/include/client_endpoint.hpp b/implementation/endpoints/include/client_endpoint.hpp
new file mode 100644
index 0000000..cbf9063
--- /dev/null
+++ b/implementation/endpoints/include/client_endpoint.hpp
@@ -0,0 +1,24 @@
+// Copyright (C) 2014-2016 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/.
+
+#ifndef VSOMEIP_CLIENT_ENDPOINT_HPP_
+#define VSOMEIP_CLIENT_ENDPOINT_HPP_
+
+#include "endpoint.hpp"
+
+namespace vsomeip {
+
+class client_endpoint : public virtual endpoint {
+public:
+ virtual ~client_endpoint() {}
+
+ virtual bool get_remote_address(boost::asio::ip::address &_address) const = 0;
+ virtual unsigned short get_remote_port() const = 0;
+};
+
+} // namespace vsomeip
+
+
+#endif /* VSOMEIP_CLIENT_ENDPOINT_HPP_ */
diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp
index 9a889f3..32f0c20 100644
--- a/implementation/endpoints/include/client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/client_endpoint_impl.hpp
@@ -19,6 +19,7 @@
#include "buffer.hpp"
#include "endpoint_impl.hpp"
+#include "client_endpoint.hpp"
namespace vsomeip {
@@ -26,15 +27,15 @@ class endpoint;
class endpoint_host;
template<typename Protocol>
-class client_endpoint_impl: public endpoint_impl<Protocol>,
+class client_endpoint_impl: public endpoint_impl<Protocol>, public client_endpoint,
public std::enable_shared_from_this<client_endpoint_impl<Protocol> > {
public:
- typedef typename Protocol::endpoint endpoint_type;
+ typedef typename Protocol::endpoint endpoint_type;
typedef typename Protocol::socket socket_type;
client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
- endpoint_type _local, endpoint_type _remote,
- boost::asio::io_service &_io,
+ endpoint_type _local, endpoint_type _remote,
+ boost::asio::io_service &_io,
std::uint32_t _max_message_size);
virtual ~client_endpoint_impl();
@@ -50,6 +51,9 @@ public:
bool is_connected() const;
+ virtual bool get_remote_address(boost::asio::ip::address &_address) const;
+ virtual unsigned short get_remote_port() const;
+
public:
void connect_cbk(boost::system::error_code const &_error);
void wait_connect_cbk(boost::system::error_code const &_error);
@@ -59,8 +63,6 @@ public:
public:
virtual void connect() = 0;
virtual void receive() = 0;
- typedef std::function<void()> endpoint_error_handler_t;
- void register_error_callback(endpoint_error_handler_t _callback);
protected:
virtual void send_queued() = 0;
@@ -82,9 +84,6 @@ protected:
bool was_not_connected_;
- std::mutex error_handler_mutex_;
- endpoint_error_handler_t error_handler_;
-
std::mutex stop_mutex_;
};
diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp
index c063f2a..c09ab92 100644
--- a/implementation/endpoints/include/endpoint.hpp
+++ b/implementation/endpoints/include/endpoint.hpp
@@ -37,9 +37,7 @@ public:
const std::string &_address, uint16_t _port) = 0;
virtual void remove_default_target(service_t _service) = 0;
- virtual bool get_remote_address(boost::asio::ip::address &_address) const = 0;
virtual unsigned short get_local_port() const = 0;
- virtual unsigned short get_remote_port() const = 0;
virtual bool is_reliable() const = 0;
virtual bool is_local() const = 0;
diff --git a/implementation/endpoints/include/endpoint_host.hpp b/implementation/endpoints/include/endpoint_host.hpp
index 8834158..25218d4 100644
--- a/implementation/endpoints/include/endpoint_host.hpp
+++ b/implementation/endpoints/include/endpoint_host.hpp
@@ -28,9 +28,13 @@ public:
virtual void on_message(const byte_t *_data, length_t _length,
endpoint *_receiver, const boost::asio::ip::address &_destination
= boost::asio::ip::address(),
- client_t _bound_client = VSOMEIP_ROUTING_CLIENT) = 0;
+ client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
+ const boost::asio::ip::address &_remote_address = boost::asio::ip::address(),
+ std::uint16_t _remote_port = 0) = 0;
virtual void on_error(const byte_t *_data, length_t _length,
- endpoint *_receiver) = 0;
+ endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) = 0;
virtual void release_port(uint16_t _port, bool _reliable) = 0;
virtual client_t get_client() const = 0;
#ifndef WIN32
diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp
index b000011..341325b 100644
--- a/implementation/endpoints/include/endpoint_impl.hpp
+++ b/implementation/endpoints/include/endpoint_impl.hpp
@@ -20,7 +20,7 @@ namespace vsomeip {
class endpoint_host;
template<typename Protocol>
-class endpoint_impl: public endpoint {
+class endpoint_impl: public virtual endpoint {
public:
typedef typename Protocol::endpoint endpoint_type;
@@ -40,12 +40,9 @@ public:
void add_default_target(service_t, const std::string &, uint16_t);
void remove_default_target(service_t);
- bool get_remote_address(boost::asio::ip::address &_address) const;
-
// Dummy implementations as we only need these for server endpoints
// TODO: redesign
unsigned short get_local_port() const;
- unsigned short get_remote_port() const;
bool is_reliable() const;
void increment_use_count();
@@ -59,7 +56,6 @@ public:
virtual void restart() = 0;
protected:
- virtual bool is_magic_cookie() const;
uint32_t find_magic_cookie(byte_t *_buffer, size_t _size);
protected:
diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_client_endpoint_impl.hpp
index 79a0420..8f9b224 100644
--- a/implementation/endpoints/include/local_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/local_client_endpoint_impl.hpp
@@ -31,6 +31,8 @@ typedef client_endpoint_impl<
class local_client_endpoint_impl: public local_client_endpoint_base_impl {
public:
+ typedef std::function<void()> error_handler_t;
+
local_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
endpoint_type _remote,
boost::asio::io_service &_io,
@@ -42,6 +44,11 @@ public:
bool is_local() const;
+ bool get_remote_address(boost::asio::ip::address &_address) const;
+ unsigned short get_remote_port() const;
+
+ void register_error_handler(error_handler_t _error_handler);
+
private:
void send_queued();
@@ -52,7 +59,9 @@ private:
void receive_cbk(boost::system::error_code const &_error,
std::size_t _bytes);
- receive_buffer_t recv_buffer_;
+ message_buffer_t recv_buffer_;
+
+ error_handler_t error_handler_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/local_server_endpoint_impl.hpp b/implementation/endpoints/include/local_server_endpoint_impl.hpp
index 66c1fc2..a66a410 100644
--- a/implementation/endpoints/include/local_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/local_server_endpoint_impl.hpp
@@ -41,13 +41,15 @@ public:
local_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
endpoint_type _local,
boost::asio::io_service &_io,
- std::uint32_t _max_message_size);
+ std::uint32_t _max_message_size,
+ std::uint32_t _buffer_shrink_threshold);
local_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
endpoint_type _local,
boost::asio::io_service &_io,
std::uint32_t _max_message_size,
- int native_socket);
+ int native_socket,
+ std::uint32_t _buffer_shrink_threshold);
virtual ~local_server_endpoint_impl();
@@ -74,7 +76,7 @@ private:
typedef boost::shared_ptr<connection> ptr;
static ptr create(std::weak_ptr<local_server_endpoint_impl> _server,
- std::uint32_t _max_message_size);
+ std::uint32_t _buffer_shrink_threshold);
socket_type & get_socket();
void start();
@@ -86,23 +88,28 @@ private:
private:
connection(std::weak_ptr<local_server_endpoint_impl> _server,
- std::uint32_t _max_message_size);
+ std::uint32_t _recv_buffer_size_initial,
+ std::uint32_t _buffer_shrink_threshold);
void send_magic_cookie();
local_server_endpoint_impl::socket_type socket_;
std::weak_ptr<local_server_endpoint_impl> server_;
- uint32_t max_message_size_;
+ const uint32_t recv_buffer_size_initial_;
- receive_buffer_t recv_buffer_;
+ message_buffer_t recv_buffer_;
size_t recv_buffer_size_;
+ std::uint32_t missing_capacity_;
+ std::uint32_t shrink_count_;
+ const std::uint32_t buffer_shrink_threshold_;
client_t bound_client_;
private:
void receive_cbk(boost::system::error_code const &_error,
std::size_t _bytes);
+ void calculate_shrink_count();
};
#ifdef WIN32
@@ -114,6 +121,7 @@ private:
std::mutex connections_mutex_;
std::map<endpoint_type, connection::ptr> connections_;
connection::ptr current_;
+ const std::uint32_t buffer_shrink_threshold_;
private:
void remove_connection(connection *_connection);
diff --git a/implementation/endpoints/include/netlink_connector.hpp b/implementation/endpoints/include/netlink_connector.hpp
new file mode 100644
index 0000000..c47e0f4
--- /dev/null
+++ b/implementation/endpoints/include/netlink_connector.hpp
@@ -0,0 +1,220 @@
+// Copyright (C) 2014-2016 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/.
+
+#ifndef NETLINK_CONNECTOR_HPP_
+#define NETLINK_CONNECTOR_HPP_
+
+#ifndef WIN32
+
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <map>
+
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/basic_raw_socket.hpp>
+
+#include "../../endpoints/include/buffer.hpp"
+
+namespace vsomeip {
+
+template <typename Protocol>
+class nl_endpoint {
+public:
+ /// The protocol type associated with the endpoint.
+ typedef Protocol protocol_type;
+ typedef boost::asio::detail::socket_addr_type data_type;
+
+ /// Default constructor.
+ nl_endpoint()
+ {
+ sockaddr.nl_family = PF_NETLINK;
+ sockaddr.nl_groups = 0;
+ sockaddr.nl_pid = getpid();
+ }
+
+ /// Construct an endpoint using the specified path name.
+ nl_endpoint(int group, int pid=getpid())
+ {
+ sockaddr.nl_family = PF_NETLINK;
+ sockaddr.nl_groups = group;
+ sockaddr.nl_pid = pid;
+ }
+
+ /// Copy constructor.
+ nl_endpoint(const nl_endpoint& other)
+ {
+ sockaddr = other.sockaddr;
+ }
+
+ /// Assign from another endpoint.
+ nl_endpoint& operator=(const nl_endpoint& other)
+ {
+ sockaddr = other.sockaddr;
+ return *this;
+ }
+
+ /// The protocol associated with the endpoint.
+ protocol_type protocol() const
+ {
+ return protocol_type();
+ }
+
+ /// Get the underlying endpoint in the native type.
+ data_type* data()
+ {
+ return &sockaddr;
+ }
+
+ /// Get the underlying endpoint in the native type.
+ const data_type* data() const
+ {
+ return (struct sockaddr*)&sockaddr;
+ }
+
+ /// Get the underlying size of the endpoint in the native type.
+ std::size_t size() const
+ {
+ return sizeof(sockaddr);
+ }
+
+ /// Set the underlying size of the endpoint in the native type.
+ void resize(std::size_t size)
+ {
+ /* nothing we can do here */
+ }
+
+ /// Get the capacity of the endpoint in the native type.
+ std::size_t capacity() const
+ {
+ return sizeof(sockaddr);
+ }
+
+ /// Compare two endpoints for equality.
+ friend bool operator==(const nl_endpoint<Protocol>& e1,
+ const nl_endpoint<Protocol>& e2)
+ {
+ return e1.sockaddr == e2.sockaddr;
+ }
+
+ /// Compare two endpoints for inequality.
+ friend bool operator!=(const nl_endpoint<Protocol>& e1,
+ const nl_endpoint<Protocol>& e2)
+ {
+ return !(e1.sockaddr == e2.sockaddr);
+ }
+
+ /// Compare endpoints for ordering.
+ friend bool operator<(const nl_endpoint<Protocol>& e1,
+ const nl_endpoint<Protocol>& e2)
+ {
+ return e1.sockaddr < e2.sockaddr;
+ }
+
+ /// Compare endpoints for ordering.
+ friend bool operator>(const nl_endpoint<Protocol>& e1,
+ const nl_endpoint<Protocol>& e2)
+ {
+ return e2.sockaddr < e1.sockaddr;
+ }
+
+ /// Compare endpoints for ordering.
+ friend bool operator<=(const nl_endpoint<Protocol>& e1,
+ const nl_endpoint<Protocol>& e2)
+ {
+ return !(e2 < e1);
+ }
+
+ /// Compare endpoints for ordering.
+ friend bool operator>=(const nl_endpoint<Protocol>& e1,
+ const nl_endpoint<Protocol>& e2)
+ {
+ return !(e1 < e2);
+ }
+
+private:
+ sockaddr_nl sockaddr;
+};
+
+class nl_protocol {
+public:
+ nl_protocol() {
+ proto = 0;
+ }
+ nl_protocol(int proto) {
+ this->proto = proto;
+ }
+ /// Obtain an identifier for the type of the protocol.
+ int type() const
+ {
+ return SOCK_RAW;
+ }
+ /// Obtain an identifier for the protocol.
+ int protocol() const
+ {
+ return proto;
+ }
+ /// Obtain an identifier for the protocol family.
+ int family() const
+ {
+ return PF_NETLINK;
+ }
+
+ typedef nl_endpoint<nl_protocol> endpoint;
+ typedef boost::asio::basic_raw_socket<nl_protocol> socket;
+
+private:
+ int proto;
+};
+
+typedef std::function< void (std::string, bool) > net_if_changed_handler_t;
+
+class netlink_connector : public std::enable_shared_from_this<netlink_connector> {
+public:
+ netlink_connector(boost::asio::io_service& _io, boost::asio::ip::address _address):
+ net_if_index_for_address_(0),
+ handler_(nullptr),
+ socket_(_io),
+ recv_buffer_(recv_buffer_size, 0),
+ address_(_address)
+ {
+ }
+ ~netlink_connector() {}
+
+ void register_net_if_changes_handler(net_if_changed_handler_t _handler);
+ void unregister_net_if_changes_handler();
+
+ void start();
+ void stop();
+
+private:
+ bool has_address(const struct ifaddrmsg * ifa_struct,
+ size_t length,
+ const unsigned int address);
+ void send_ifa_request();
+ void send_ifi_request();
+
+ void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+ void send_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+
+ std::map<int, unsigned int> net_if_flags_;
+ int net_if_index_for_address_;
+
+ net_if_changed_handler_t handler_;
+
+ boost::asio::basic_raw_socket<nl_protocol> socket_;
+
+ const size_t recv_buffer_size = 16384;
+ message_buffer_t recv_buffer_;
+
+ boost::asio::ip::address address_;
+};
+
+}
+
+#endif // NOT WIN32
+
+#endif /* NETLINK_CONNECTOR_HPP_ */
diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
index e6aaa33..9f5d19d 100644
--- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
@@ -21,9 +21,10 @@ class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl {
public:
tcp_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
endpoint_type _local,
- endpoint_type _remote,
+ endpoint_type _remote,
boost::asio::io_service &_io,
- std::uint32_t _max_message_size);
+ std::uint32_t _max_message_size,
+ std::uint32_t buffer_shrink_threshold);
virtual ~tcp_client_endpoint_impl();
void start();
@@ -44,9 +45,14 @@ private:
void connect();
void receive();
+ void calculate_shrink_count();
- receive_buffer_t recv_buffer_;
+ const std::uint32_t recv_buffer_size_initial_;
+ message_buffer_t recv_buffer_;
size_t recv_buffer_size_;
+ std::uint32_t missing_capacity_;
+ std::uint32_t shrink_count_;
+ const std::uint32_t buffer_shrink_threshold_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
index e976644..8ded105 100644
--- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
@@ -27,7 +27,8 @@ public:
tcp_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
endpoint_type _local,
boost::asio::io_service &_io,
- std::uint32_t _max_message_size);
+ std::uint32_t _max_message_size,
+ std::uint32_t _buffer_shrink_threshold);
virtual ~tcp_server_endpoint_impl();
void start();
@@ -39,8 +40,6 @@ public:
VSOMEIP_EXPORT bool is_established(std::shared_ptr<endpoint_definition> _endpoint);
- bool get_remote_address(boost::asio::ip::address &_address) const;
- unsigned short get_remote_port() const;
bool get_default_target(service_t, endpoint_type &) const;
unsigned short get_local_port() const;
@@ -61,7 +60,8 @@ private:
typedef boost::shared_ptr<connection> ptr;
static ptr create(std::weak_ptr<tcp_server_endpoint_impl> _server,
- std::uint32_t _max_message_size);
+ std::uint32_t _max_message_size,
+ std::uint32_t _buffer_shrink_threshold);
socket_type & get_socket();
void start();
@@ -74,28 +74,35 @@ private:
private:
connection(std::weak_ptr<tcp_server_endpoint_impl> _server,
- std::uint32_t _max_message_size);
+ std::uint32_t _max_message_size,
+ std::uint32_t _recv_buffer_size_initial,
+ std::uint32_t _buffer_shrink_threshold);
void send_magic_cookie(message_buffer_ptr_t &_buffer);
tcp_server_endpoint_impl::socket_type socket_;
std::weak_ptr<tcp_server_endpoint_impl> server_;
- uint32_t max_message_size_;
+ const uint32_t max_message_size_;
+ const uint32_t recv_buffer_size_initial_;
- receive_buffer_t recv_buffer_;
+ message_buffer_t recv_buffer_;
size_t recv_buffer_size_;
+ std::uint32_t missing_capacity_;
+ std::uint32_t shrink_count_;
+ const std::uint32_t buffer_shrink_threshold_;
private:
bool is_magic_cookie(size_t _offset) const;
void receive_cbk(boost::system::error_code const &_error,
std::size_t _bytes);
+ void calculate_shrink_count();
std::mutex stop_mutex_;
};
boost::asio::ip::tcp::acceptor acceptor_;
std::mutex connections_mutex_;
std::map<endpoint_type, connection::ptr> connections_;
- connection *current_;
+ const std::uint32_t buffer_shrink_threshold_;
private:
void remove_connection(connection *_connection);
diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp
index 07d2179..cd3bb25 100644
--- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp
@@ -47,7 +47,7 @@ private:
void connect();
void receive();
- receive_buffer_t recv_buffer_;
+ message_buffer_t recv_buffer_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
index 0f2f830..cdadb0a 100644
--- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
@@ -37,9 +37,6 @@ public:
const byte_t *_data, uint32_t _size, bool _flush);
void send_queued(queue_iterator_type _queue_iterator);
- bool get_remote_address(boost::asio::ip::address &_address) const;
- unsigned short get_remote_port() const;
-
void join(const std::string &_address);
void leave(const std::string &_address);
@@ -69,7 +66,7 @@ private:
std::map<service_t, endpoint_type> default_targets_;
std::set<std::string> joined_;
- receive_buffer_t recv_buffer_;
+ message_buffer_t recv_buffer_;
std::mutex stop_mutex_;
};
diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp
index 9a33aad..5027aa7 100644
--- a/implementation/endpoints/src/client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/client_endpoint_impl.cpp
@@ -7,6 +7,7 @@
#include <iomanip>
#include <sstream>
#include <thread>
+#include <limits>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
@@ -124,9 +125,17 @@ bool client_endpoint_impl<Protocol>::send(const uint8_t *_data,
for (uint32_t i = 0; i < _size; i++)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
+ if (endpoint_impl<Protocol>::max_message_size_ != MESSAGE_SIZE_UNLIMITED
+ && _size > endpoint_impl<Protocol>::max_message_size_) {
+ VSOMEIP_ERROR << "cei::send: Dropping to big message (" << std::dec
+ << _size << " Bytes). Maximum allowed message size is: "
+ << endpoint_impl<Protocol>::max_message_size_ << " Bytes.";
+ return false;
+ }
+
const bool queue_size_zero_on_entry(queue_.empty());
if (packetizer_->size() + _size > endpoint_impl<Protocol>::max_message_size_
&& !packetizer_->empty()) {
@@ -199,7 +208,7 @@ void client_endpoint_impl<Protocol>::connect_cbk(
// Double the timeout as long as the maximum allowed is larger
if (connect_timeout_ < VSOMEIP_MAX_CONNECT_TIMEOUT)
- connect_timeout_ <<= 1;
+ connect_timeout_ <<= 1;
if (is_connected_) {
is_connected_ = false;
@@ -245,15 +254,11 @@ void client_endpoint_impl<Protocol>::send_cbk(
}
} else if (_error == boost::asio::error::broken_pipe) {
is_connected_ = false;
- if (endpoint_impl<Protocol>::sending_blocked_ || error_handler_) {
+ if (endpoint_impl<Protocol>::sending_blocked_) {
{
std::lock_guard<std::mutex> its_lock(mutex_);
queue_.clear();
}
- if (error_handler_) {
- std::lock_guard<std::mutex> its_lock(error_handler_mutex_);
- error_handler_();
- }
}
if (socket_.is_open()) {
shutdown_and_close_socket();
@@ -278,13 +283,6 @@ void client_endpoint_impl<Protocol>::flush_cbk(
}
template<typename Protocol>
-void client_endpoint_impl<Protocol>::register_error_callback(
- endpoint_error_handler_t _callback) {
- std::lock_guard<std::mutex> its_lock(error_handler_mutex_);
- error_handler_ = _callback;
-}
-
-template<typename Protocol>
void client_endpoint_impl<Protocol>::shutdown_and_close_socket() {
std::lock_guard<std::mutex> its_lock(stop_mutex_);
if (socket_.is_open()) {
@@ -294,6 +292,18 @@ void client_endpoint_impl<Protocol>::shutdown_and_close_socket() {
}
}
+template<typename Protocol>
+bool client_endpoint_impl<Protocol>::get_remote_address(
+ boost::asio::ip::address &_address) const {
+ (void)_address;
+ return false;
+}
+
+template<typename Protocol>
+unsigned short client_endpoint_impl<Protocol>::get_remote_port() const {
+ return 0;
+}
+
// Instantiate template
#ifndef WIN32
template class client_endpoint_impl<boost::asio::local::stream_protocol>;
diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp
index 109cff8..7238d83 100644
--- a/implementation/endpoints/src/endpoint_impl.cpp
+++ b/implementation/endpoints/src/endpoint_impl.cpp
@@ -20,9 +20,9 @@ namespace vsomeip {
template<typename Protocol>
endpoint_impl<Protocol>::endpoint_impl(
std::shared_ptr<endpoint_host> _host,
- endpoint_type _local,
- boost::asio::io_service &_io,
- std::uint32_t _max_message_size)
+ endpoint_type _local,
+ boost::asio::io_service &_io,
+ std::uint32_t _max_message_size)
: service_(_io),
host_(_host),
is_supporting_magic_cookies_(false),
@@ -30,7 +30,7 @@ endpoint_impl<Protocol>::endpoint_impl(
max_message_size_(_max_message_size),
use_count_(0),
sending_blocked_(false),
- local_(_local) {
+ local_(_local) {
}
template<typename Protocol>
@@ -43,11 +43,6 @@ void endpoint_impl<Protocol>::enable_magic_cookies() {
}
template<typename Protocol>
-bool endpoint_impl<Protocol>::is_magic_cookie() const {
- return false;
-}
-
-template<typename Protocol>
uint32_t endpoint_impl<Protocol>::find_magic_cookie(
byte_t *_buffer, size_t _size) {
bool is_found(false);
@@ -114,23 +109,11 @@ void endpoint_impl<Protocol>::remove_default_target(service_t) {
}
template<typename Protocol>
-bool endpoint_impl<Protocol>::get_remote_address(
- boost::asio::ip::address &_address) const {
- (void)_address;
- return false;
-}
-
-template<typename Protocol>
unsigned short endpoint_impl<Protocol>::get_local_port() const {
return 0;
}
template<typename Protocol>
-unsigned short endpoint_impl<Protocol>::get_remote_port() const {
- return 0;
-}
-
-template<typename Protocol>
bool endpoint_impl<Protocol>::is_reliable() const {
return false;
}
diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp
index 1a13e91..1466ac0 100644
--- a/implementation/endpoints/src/local_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp
@@ -46,13 +46,6 @@ bool local_client_endpoint_impl::is_local() const {
void local_client_endpoint_impl::start() {
if (socket_.is_open()) {
sending_blocked_ = false;
- {
- std::lock_guard<std::mutex> its_lock(stop_mutex_);
- boost::system::error_code its_error;
- socket_.cancel(its_error);
- socket_.shutdown(socket_type::shutdown_both, its_error);
- socket_.close(its_error);
- }
restart();
} else {
connect();
@@ -122,7 +115,7 @@ msg << "lce<" << this << ">::sq: ";
for (std::size_t i = 0; i < its_buffer->size(); i++)
msg << std::setw(2) << std::setfill('0') << std::hex
<< (int)(*its_buffer)[i] << " ";
-VSOMEIP_DEBUG << msg.str();
+VSOMEIP_INFO << msg.str();
#endif
bufs.push_back(boost::asio::buffer(its_start_tag));
@@ -149,20 +142,42 @@ void local_client_endpoint_impl::send_magic_cookie() {
void local_client_endpoint_impl::receive_cbk(
boost::system::error_code const &_error, std::size_t _bytes) {
(void)_bytes;
- if (_error == boost::asio::error::operation_aborted) {
- // endpoint was stopped
- shutdown_and_close_socket();
- } else if (_error == boost::asio::error::connection_reset
- || _error == boost::asio::error::eof
- || _error != boost::asio::error::bad_descriptor) {
- VSOMEIP_TRACE << "local_client_endpoint:"
- " connection_reseted/EOF/bad_descriptor";
- } else if (_error) {
- VSOMEIP_ERROR << "Local endpoint received message ("
- << _error.message() << ")";
+ if (_error) {
+ if (_error == boost::asio::error::operation_aborted) {
+ // endpoint was stopped
+ shutdown_and_close_socket();
+ } else if (_error == boost::asio::error::connection_reset
+ || _error == boost::asio::error::eof
+ || _error == boost::asio::error::bad_descriptor) {
+ VSOMEIP_TRACE << "local_client_endpoint:"
+ " connection_reseted/EOF/bad_descriptor";
+ } else if (_error) {
+ VSOMEIP_ERROR << "Local endpoint received message ("
+ << _error.message() << ")";
+ }
+ // The error handler is set only if the endpoint is hosted by the
+ // routing manager. For the routing manager proxies, the corresponding
+ // client endpoint (that connect to the same client) are removed
+ // after the proxy has received the routing info.
+ if (error_handler_)
+ error_handler_();
} else {
receive();
}
}
+bool local_client_endpoint_impl::get_remote_address(
+ boost::asio::ip::address &_address) const {
+ (void)_address;
+ return false;
+}
+
+unsigned short local_client_endpoint_impl::get_remote_port() const {
+ return 0;
+}
+
+void local_client_endpoint_impl::register_error_handler(error_handler_t _error_handler) {
+ error_handler_ = _error_handler;
+}
+
} // namespace vsomeip
diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_server_endpoint_impl.cpp
index 851185a..697fd3b 100644
--- a/implementation/endpoints/src/local_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/local_server_endpoint_impl.cpp
@@ -14,6 +14,8 @@
#include "../include/local_server_endpoint_impl.hpp"
#include "../../logging/include/logger.hpp"
+#include "../../utility/include/byteorder.hpp"
+#include "../../configuration/include/internal.hpp"
#include "../../configuration/include/configuration.hpp"
// Credentials
@@ -26,9 +28,12 @@ namespace vsomeip {
local_server_endpoint_impl::local_server_endpoint_impl(
std::shared_ptr< endpoint_host > _host,
endpoint_type _local, boost::asio::io_service &_io,
- std::uint32_t _max_message_size)
+ std::uint32_t _max_message_size,
+ std::uint32_t _buffer_shrink_threshold)
: local_server_endpoint_base_impl(_host, _local, _io, _max_message_size),
- acceptor_(_io), current_(nullptr) {
+ acceptor_(_io),
+ current_(nullptr),
+ buffer_shrink_threshold_(_buffer_shrink_threshold) {
is_supporting_magic_cookies_ = false;
boost::system::error_code ec;
@@ -52,9 +57,12 @@ local_server_endpoint_impl::local_server_endpoint_impl(
std::shared_ptr< endpoint_host > _host,
endpoint_type _local, boost::asio::io_service &_io,
std::uint32_t _max_message_size,
- int native_socket)
+ int native_socket,
+ std::uint32_t _buffer_shrink_threshold)
: local_server_endpoint_base_impl(_host, _local, _io, _max_message_size),
- acceptor_(_io), current_(nullptr) {
+ acceptor_(_io),
+ current_(nullptr),
+ buffer_shrink_threshold_(_buffer_shrink_threshold) {
is_supporting_magic_cookies_ = false;
boost::system::error_code ec;
@@ -79,7 +87,7 @@ void local_server_endpoint_impl::start() {
if (acceptor_.is_open()) {
current_ = connection::create(
std::dynamic_pointer_cast<local_server_endpoint_impl>(
- shared_from_this()), max_message_size_);
+ shared_from_this()), buffer_shrink_threshold_);
acceptor_.async_accept(
current_->get_socket(),
@@ -161,8 +169,9 @@ void local_server_endpoint_impl::remove_connection(
void local_server_endpoint_impl::accept_cbk(
connection::ptr _connection, boost::system::error_code const &_error) {
- if (_error != boost::asio::error::bad_descriptor &&
- _error != boost::asio::error::operation_aborted) {
+ if (_error != boost::asio::error::bad_descriptor
+ && _error != boost::asio::error::operation_aborted
+ && _error != boost::asio::error::no_descriptors) {
start();
}
@@ -206,19 +215,28 @@ void local_server_endpoint_impl::accept_cbk(
local_server_endpoint_impl::connection::connection(
std::weak_ptr<local_server_endpoint_impl> _server,
- std::uint32_t _max_message_size)
+ std::uint32_t _initial_recv_buffer_size,
+ std::uint32_t _buffer_shrink_threshold)
: socket_(_server.lock()->service_),
server_(_server),
- max_message_size_(_max_message_size + 8),
- recv_buffer_(max_message_size_, 0),
- recv_buffer_size_(0), bound_client_(VSOMEIP_ROUTING_CLIENT) {
+ recv_buffer_size_initial_(_initial_recv_buffer_size + 8),
+ recv_buffer_(recv_buffer_size_initial_, 0),
+ recv_buffer_size_(0),
+ missing_capacity_(0),
+ shrink_count_(0),
+ buffer_shrink_threshold_(_buffer_shrink_threshold),
+ bound_client_(VSOMEIP_ROUTING_CLIENT) {
}
local_server_endpoint_impl::connection::ptr
local_server_endpoint_impl::connection::create(
std::weak_ptr<local_server_endpoint_impl> _server,
- std::uint32_t _max_message_size) {
- return ptr(new connection(_server, _max_message_size));
+ std::uint32_t _buffer_shrink_threshold) {
+ const std::uint32_t its_initial_buffer_size = VSOMEIP_COMMAND_HEADER_SIZE
+ + VSOMEIP_MAX_LOCAL_MESSAGE_SIZE + sizeof(instance_t) + sizeof(bool)
+ + sizeof(bool);
+ return ptr(new connection(_server, its_initial_buffer_size,
+ _buffer_shrink_threshold));
}
local_server_endpoint_impl::socket_type &
@@ -228,11 +246,24 @@ local_server_endpoint_impl::connection::get_socket() {
void local_server_endpoint_impl::connection::start() {
if (socket_.is_open()) {
- if (recv_buffer_size_ == max_message_size_) {
- // Overrun -> Reset buffer
- recv_buffer_size_ = 0;
+ const std::size_t its_capacity(recv_buffer_.capacity());
+ size_t buffer_size = its_capacity - recv_buffer_size_;
+ if (missing_capacity_) {
+ const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_);
+ if (its_capacity < its_required_capacity) {
+ recv_buffer_.reserve(its_required_capacity);
+ recv_buffer_.resize(its_required_capacity, 0x0);
+ }
+ buffer_size = missing_capacity_;
+ missing_capacity_ = 0;
+ } else if (buffer_shrink_threshold_
+ && shrink_count_ > buffer_shrink_threshold_
+ && recv_buffer_size_ == 0) {
+ recv_buffer_.resize(recv_buffer_size_initial_, 0x0);
+ recv_buffer_.shrink_to_fit();
+ buffer_size = recv_buffer_size_initial_;
+ shrink_count_ = 0;
}
- size_t buffer_size = max_message_size_ - recv_buffer_size_;
socket_.async_receive(
boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
std::bind(
@@ -273,7 +304,7 @@ void local_server_endpoint_impl::connection::send_queued(
for (std::size_t i = 0; i < its_buffer->size(); i++)
msg << std::setw(2) << std::setfill('0') << std::hex
<< (int)(*its_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
boost::asio::async_write(
socket_,
@@ -306,9 +337,10 @@ void local_server_endpoint_impl::connection::receive_cbk(
}
std::shared_ptr<endpoint_host> its_host = its_server->host_.lock();
if (its_host) {
- std::size_t its_start;
- std::size_t its_end;
+ std::size_t its_start = 0;
+ std::size_t its_end = 0;
std::size_t its_iteration_gap = 0;
+ std::uint32_t its_command_size = 0;
if (!_error && 0 < _bytes) {
#if 0
@@ -317,7 +349,7 @@ void local_server_endpoint_impl::connection::receive_cbk(
for (std::size_t i = 0; i < _bytes + recv_buffer_size_; i++)
msg << std::setw(2) << std::setfill('0') << std::hex
<< (int) (recv_buffer_[i]) << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
recv_buffer_size_ += _bytes;
@@ -332,14 +364,24 @@ void local_server_endpoint_impl::connection::receive_cbk(
recv_buffer_[its_start+1] != 0x37 ||
recv_buffer_[its_start+2] != 0x6d ||
recv_buffer_[its_start+3] != 0x07)) {
- its_start ++;
+ its_start++;
}
its_start = (its_start + 3 == recv_buffer_size_ + its_iteration_gap ?
MESSAGE_IS_EMPTY : its_start+4);
if (its_start != MESSAGE_IS_EMPTY) {
- its_end = its_start;
+ if (its_start + 6 < recv_buffer_size_ + its_iteration_gap) {
+ its_command_size = VSOMEIP_BYTES_TO_LONG(
+ recv_buffer_[its_start + 6],
+ recv_buffer_[its_start + 5],
+ recv_buffer_[its_start + 4],
+ recv_buffer_[its_start + 3]);
+
+ its_end = its_start + 6 + its_command_size;
+ } else {
+ its_end = its_start;
+ }
while (its_end + 3 < recv_buffer_size_ + its_iteration_gap &&
(recv_buffer_[its_end] != 0x07 ||
recv_buffer_[its_end+1] != 0x6d ||
@@ -347,6 +389,30 @@ void local_server_endpoint_impl::connection::receive_cbk(
recv_buffer_[its_end+3] != 0x67)) {
its_end ++;
}
+ // check if we received a full message
+ if (recv_buffer_size_ + its_iteration_gap < its_end + 4
+ || recv_buffer_[its_end] != 0x07
+ || recv_buffer_[its_end+1] != 0x6d
+ || recv_buffer_[its_end+2] != 0x37
+ || recv_buffer_[its_end+3] != 0x67) {
+ // start tag (4 Byte) + command (1 Byte) + client id (2 Byte)
+ // + command size (4 Byte) + data itself + stop tag (4 byte)
+ // = 15 Bytes not covered in command size.
+ if (its_command_size && its_command_size + 15 > recv_buffer_size_) {
+ missing_capacity_ = its_command_size + 15 - std::uint32_t(recv_buffer_size_);
+ } else if (recv_buffer_size_ < 11) {
+ // to little data to read out the command size
+ // minimal amount of data needed to read out command size = 11
+ missing_capacity_ = 11 - static_cast<std::uint32_t>(recv_buffer_size_);
+ } else {
+ VSOMEIP_ERROR << "lse::c<" << this
+ << ">rcb: recv_buffer_size is: " << std::dec
+ << recv_buffer_size_ << " but couldn't read "
+ "out command size. recv_buffer_capacity: "
+ << recv_buffer_.capacity()
+ << " its_iteration_gap: " << its_iteration_gap;
+ }
+ }
}
if (its_start != MESSAGE_IS_EMPTY &&
@@ -361,10 +427,12 @@ void local_server_endpoint_impl::connection::receive_cbk(
for (std::size_t i = its_start; i < its_end; i++)
local_msg << std::setw(2) << std::setfill('0') << std::hex
<< (int) recv_buffer_[i] << " ";
- VSOMEIP_DEBUG << local_msg.str();
+ VSOMEIP_INFO << local_msg.str();
#endif
-
+ calculate_shrink_count();
recv_buffer_size_ -= (its_end + 4 - its_iteration_gap);
+ missing_capacity_ = 0;
+ its_command_size = 0;
its_start = FOUND_MESSAGE;
its_iteration_gap = its_end + 4;
} else {
@@ -374,6 +442,11 @@ void local_server_endpoint_impl::connection::receive_cbk(
for (size_t i = 0; i < recv_buffer_size_; ++i) {
recv_buffer_[i] = recv_buffer_[i + its_iteration_gap];
}
+ // Still more capacity needed after shifting everything to front?
+ if (missing_capacity_ &&
+ missing_capacity_ <= recv_buffer_.capacity() - recv_buffer_size_) {
+ missing_capacity_ = 0;
+ }
}
}
} while (recv_buffer_size_ > 0 && its_start == FOUND_MESSAGE);
@@ -396,4 +469,16 @@ void local_server_endpoint_impl::connection::set_bound_client(client_t _client)
bound_client_ = _client;
}
+void local_server_endpoint_impl::connection::calculate_shrink_count() {
+ if (buffer_shrink_threshold_) {
+ if (recv_buffer_.capacity() != recv_buffer_size_initial_) {
+ if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) {
+ shrink_count_++;
+ } else {
+ shrink_count_ = 0;
+ }
+ }
+ }
+}
+
} // namespace vsomeip
diff --git a/implementation/endpoints/src/netlink_connector.cpp b/implementation/endpoints/src/netlink_connector.cpp
new file mode 100644
index 0000000..aab5363
--- /dev/null
+++ b/implementation/endpoints/src/netlink_connector.cpp
@@ -0,0 +1,262 @@
+// Copyright (C) 2014-2016 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/.
+
+#ifndef WIN32
+
+#include <thread>
+
+#include <boost/asio/write.hpp>
+#include <boost/asio/read.hpp>
+
+#include "../include/netlink_connector.hpp"
+#include "../../logging/include/logger.hpp"
+
+namespace vsomeip {
+
+void netlink_connector::register_net_if_changes_handler(net_if_changed_handler_t _handler) {
+ handler_ = _handler;
+}
+
+void netlink_connector::unregister_net_if_changes_handler() {
+ handler_ = nullptr;
+}
+
+void netlink_connector::stop() {
+ boost::system::error_code its_error;
+ socket_.close(its_error);
+ if (its_error) {
+ VSOMEIP_WARNING << "Error closing NETLINK socket!";
+ }
+}
+
+void netlink_connector::start() {
+ boost::system::error_code ec;
+ if (socket_.is_open()) {
+ socket_.close(ec);
+ if (ec) {
+ VSOMEIP_WARNING << "Error closing NETLINK socket: " << ec.message();
+ }
+ }
+ socket_.open(nl_protocol(NETLINK_ROUTE), ec);
+ if (ec) {
+ VSOMEIP_WARNING << "Error opening NETLINK socket: " << ec.message();
+ if (handler_) {
+ handler_("n/a", true);
+ }
+ return;
+ }
+ if (socket_.is_open()) {
+ socket_.bind(nl_endpoint<nl_protocol>(RTMGRP_LINK|RTMGRP_IPV4_IFADDR|RTMGRP_IPV6_IFADDR), ec);
+
+ if (ec) {
+ VSOMEIP_WARNING << "Error binding NETLINK socket: " << ec.message();
+ if (handler_) {
+ handler_("n/a", true);
+ }
+ return;
+ }
+
+ send_ifa_request();
+
+ socket_.async_receive(
+ boost::asio::buffer(&recv_buffer_[0], recv_buffer_size),
+ std::bind(
+ &netlink_connector::receive_cbk,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+ } else {
+ VSOMEIP_WARNING << "Error opening NETLINK socket!";
+ if (handler_) {
+ handler_("n/a", true);
+ }
+ }
+}
+
+void netlink_connector::receive_cbk(boost::system::error_code const &_error,
+ std::size_t _bytes) {
+ if (!_error) {
+ size_t len = _bytes;
+
+ unsigned int address;
+ if (address_.is_v4()) {
+ inet_pton(AF_INET, address_.to_string().c_str(), &address);
+ } else {
+ inet_pton(AF_INET6, address_.to_string().c_str(), &address);
+ }
+
+ struct nlmsghdr *nlh = (struct nlmsghdr *)&recv_buffer_[0];
+
+ while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE)) {
+ char ifname[1024];
+ struct ifinfomsg *ifi = (ifinfomsg *)NLMSG_DATA(nlh);
+ struct ifaddrmsg *ifa = (ifaddrmsg *)NLMSG_DATA(nlh);
+ switch (nlh->nlmsg_type) {
+ case RTM_NEWADDR:
+ // New Address information
+ if (has_address((struct ifaddrmsg *)NLMSG_DATA(nlh),
+ IFA_PAYLOAD(nlh), address)) {
+ net_if_index_for_address_ = ifa->ifa_index;
+ auto its_if = net_if_flags_.find(ifa->ifa_index);
+ if (its_if != net_if_flags_.end()) {
+ if ((its_if->second & IFF_UP) &&
+ (its_if->second & IFF_RUNNING)) {
+ if (handler_) {
+ if_indextoname(ifa->ifa_index,ifname);
+ handler_(ifname, true);
+ }
+ } else {
+ if (handler_) {
+ if_indextoname(ifa->ifa_index,ifname);
+ handler_(ifname, false);
+ }
+ }
+ } else {
+ // Request interface information
+ // as we don't know about up/running state!
+ send_ifi_request();
+ }
+ }
+ break;
+ case RTM_NEWLINK:
+ // New Interface information
+ net_if_flags_[ifi->ifi_index] = ifi->ifi_flags;
+ if (net_if_index_for_address_ == ifi->ifi_index) {
+ if ((ifi->ifi_flags & IFF_UP) &&
+ (ifi->ifi_flags & IFF_RUNNING)) {
+ if (handler_) {
+ if_indextoname(ifi->ifi_index,ifname);
+ handler_(ifname, true);
+ }
+ } else {
+ if (handler_) {
+ if_indextoname(ifi->ifi_index,ifname);
+ handler_(ifname, false);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ nlh = NLMSG_NEXT(nlh, len);
+ }
+ socket_.async_receive(
+ boost::asio::buffer(&recv_buffer_[0], recv_buffer_size),
+ std::bind(
+ &netlink_connector::receive_cbk,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+ } else {
+ if (_error != boost::asio::error::operation_aborted) {
+ VSOMEIP_WARNING << "Error receive_cbk NETLINK socket!" << _error.message();
+ boost::system::error_code its_error;
+ if (socket_.is_open()) {
+ socket_.close(its_error);
+ if (its_error) {
+ VSOMEIP_WARNING << "Error closing NETLINK socket!" << its_error.message();
+ }
+ }
+ if (handler_) {
+ handler_("n/a", true);
+ }
+ }
+ }
+}
+
+void netlink_connector::send_cbk(boost::system::error_code const &_error, std::size_t _bytes) {
+ (void)_bytes;
+ if (_error) {
+ VSOMEIP_WARNING << "Netlink send error : " << _error.message();
+ if (handler_) {
+ handler_("n/a", true);
+ }
+ }
+}
+
+void netlink_connector::send_ifa_request() {
+ typedef struct {
+ struct nlmsghdr nlhdr;
+ struct ifaddrmsg addrmsg;
+ } netlink_address_msg;
+ netlink_address_msg get_address_msg;
+ memset(&get_address_msg, 0, sizeof(get_address_msg));
+ get_address_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ get_address_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+ get_address_msg.nlhdr.nlmsg_type = RTM_GETADDR;
+ if (address_.is_v4()) {
+ get_address_msg.addrmsg.ifa_family = AF_INET;
+ } else {
+ get_address_msg.addrmsg.ifa_family = AF_INET6;
+ }
+
+ socket_.async_send(
+ boost::asio::buffer(&get_address_msg, get_address_msg.nlhdr.nlmsg_len),
+ std::bind(
+ &netlink_connector::send_cbk,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+}
+
+void netlink_connector::send_ifi_request() {
+ typedef struct {
+ struct nlmsghdr nlhdr;
+ struct ifinfomsg infomsg;
+ } netlink_link_msg;
+ netlink_link_msg get_link_msg;
+ memset(&get_link_msg, 0, sizeof(get_link_msg));
+ get_link_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ get_link_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+ get_link_msg.nlhdr.nlmsg_type = RTM_GETLINK;
+ get_link_msg.infomsg.ifi_family = AF_UNSPEC;
+
+ socket_.async_send(
+ boost::asio::buffer(&get_link_msg, get_link_msg.nlhdr.nlmsg_len),
+ std::bind(
+ &netlink_connector::send_cbk,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+}
+
+bool netlink_connector::has_address(const struct ifaddrmsg * ifa_struct,
+ size_t length,
+ const unsigned int address) {
+
+ struct rtattr *retrta;
+ retrta = (struct rtattr *)IFA_RTA(ifa_struct);
+ while RTA_OK(retrta, length) {
+ if (retrta->rta_type == IFA_ADDRESS) {
+ char pradd[128];
+ unsigned int * tmp_address = (unsigned int *)RTA_DATA(retrta);
+ if (address_.is_v4()) {
+ inet_ntop(AF_INET, tmp_address, pradd, sizeof(pradd));
+ } else {
+ inet_ntop(AF_INET6, tmp_address, pradd, sizeof(pradd));
+ }
+ if (address == *tmp_address) {
+ return true;
+ }
+ }
+ retrta = RTA_NEXT(retrta, length);
+ }
+
+ return false;
+}
+
+} // namespace vsomeip
+
+#endif
+
diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp
index c8e513b..4d4686b 100644
--- a/implementation/endpoints/src/server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/server_endpoint_impl.cpp
@@ -5,6 +5,7 @@
#include <iomanip>
#include <sstream>
+#include <limits>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
@@ -55,7 +56,7 @@ bool server_endpoint_impl<Protocol>::send(const uint8_t *_data,
msg << "sei::send ";
for (uint32_t i = 0; i < _size; i++)
msg << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
endpoint_type its_target;
bool is_valid_target(false);
@@ -110,6 +111,14 @@ bool server_endpoint_impl<Protocol>::send_intern(
return false;
}
+ if (endpoint_impl<Protocol>::max_message_size_ != MESSAGE_SIZE_UNLIMITED
+ && _size > endpoint_impl<Protocol>::max_message_size_) {
+ VSOMEIP_ERROR << "sei::send_intern: Dropping to big message (" << _size
+ << " Bytes). Maximum allowed message size is: "
+ << endpoint_impl<Protocol>::max_message_size_ << " Bytes.";
+ return false;
+ }
+
auto found_packetizer = packetizer_.find(_target);
if (found_packetizer != packetizer_.end()) {
target_packetizer = found_packetizer->second;
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
index 5165e4b..808efe5 100644
--- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
@@ -14,6 +14,7 @@
#include "../include/tcp_client_endpoint_impl.hpp"
#include "../../logging/include/logger.hpp"
#include "../../utility/include/utility.hpp"
+#include "../../configuration/include/internal.hpp"
namespace ip = boost::asio::ip;
@@ -24,18 +25,23 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl(
endpoint_type _local,
endpoint_type _remote,
boost::asio::io_service &_io,
- std::uint32_t _max_message_size)
+ std::uint32_t _max_message_size,
+ std::uint32_t _buffer_shrink_threshold)
: tcp_client_endpoint_base_impl(_host, _local, _remote, _io, _max_message_size),
- recv_buffer_(_max_message_size, 0),
- recv_buffer_size_(0) {
+ recv_buffer_size_initial_(VSOMEIP_SOMEIP_HEADER_SIZE),
+ recv_buffer_(recv_buffer_size_initial_, 0),
+ recv_buffer_size_(0),
+ missing_capacity_(0),
+ shrink_count_(0),
+ buffer_shrink_threshold_(_buffer_shrink_threshold) {
is_supporting_magic_cookies_ = true;
}
tcp_client_endpoint_impl::~tcp_client_endpoint_impl() {
- std::shared_ptr<endpoint_host> its_host = host_.lock();
- if (its_host) {
- its_host->release_port(local_.port(), true);
- }
+ std::shared_ptr<endpoint_host> its_host = host_.lock();
+ if (its_host) {
+ its_host->release_port(local_.port(), true);
+ }
}
bool tcp_client_endpoint_impl::is_local() const {
@@ -85,20 +91,35 @@ void tcp_client_endpoint_impl::connect() {
}
void tcp_client_endpoint_impl::receive() {
- if (recv_buffer_size_ == max_message_size_) {
- // Overrun -> Reset buffer
- recv_buffer_size_ = 0;
+ if(socket_.is_open()) {
+ const std::size_t its_capacity(recv_buffer_.capacity());
+ size_t buffer_size = its_capacity - recv_buffer_size_;
+ if (missing_capacity_) {
+ const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_);
+ if (its_capacity < its_required_capacity) {
+ recv_buffer_.reserve(its_required_capacity);
+ recv_buffer_.resize(its_required_capacity, 0x0);
+ }
+ buffer_size = missing_capacity_;
+ missing_capacity_ = 0;
+ } else if (buffer_shrink_threshold_
+ && shrink_count_ > buffer_shrink_threshold_
+ && recv_buffer_size_ == 0) {
+ recv_buffer_.resize(recv_buffer_size_initial_, 0x0);
+ recv_buffer_.shrink_to_fit();
+ buffer_size = recv_buffer_size_initial_;
+ shrink_count_ = 0;
+ }
+ socket_.async_receive(
+ boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
+ std::bind(
+ &tcp_client_endpoint_impl::receive_cbk,
+ std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
- size_t buffer_size = max_message_size_ - recv_buffer_size_;
- socket_.async_receive(
- boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
- std::bind(
- &tcp_client_endpoint_impl::receive_cbk,
- std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()),
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
}
void tcp_client_endpoint_impl::send_queued() {
@@ -119,7 +140,7 @@ void tcp_client_endpoint_impl::send_queued() {
for (std::size_t i = 0; i < its_buffer->size(); i++)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int)(*its_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
boost::asio::async_write(
@@ -136,18 +157,28 @@ void tcp_client_endpoint_impl::send_queued() {
bool tcp_client_endpoint_impl::get_remote_address(
boost::asio::ip::address &_address) const {
- _address = remote_.address();
+ const boost::asio::ip::address its_address = remote_.address();
+ if (its_address.is_unspecified()) {
+ return false;
+ }
+ _address = its_address;
return true;
}
unsigned short tcp_client_endpoint_impl::get_local_port() const {
boost::system::error_code its_error;
- return socket_.local_endpoint(its_error).port();
+ if (socket_.is_open()) {
+ return socket_.local_endpoint(its_error).port();
+ }
+ return 0;
}
unsigned short tcp_client_endpoint_impl::get_remote_port() const {
boost::system::error_code its_error;
- return socket_.remote_endpoint(its_error).port();
+ if (socket_.is_open()) {
+ return socket_.remote_endpoint(its_error).port();
+ }
+ return 0;
}
bool tcp_client_endpoint_impl::is_reliable() const {
@@ -159,7 +190,8 @@ bool tcp_client_endpoint_impl::is_magic_cookie(size_t _offset) const {
}
void tcp_client_endpoint_impl::send_magic_cookie(message_buffer_ptr_t &_buffer) {
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
+ if (max_message_size_ == MESSAGE_SIZE_UNLIMITED
+ || max_message_size_ - _buffer->size() >=
VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
_buffer->insert(
_buffer->begin(),
@@ -184,13 +216,17 @@ void tcp_client_endpoint_impl::receive_cbk(
for (std::size_t i = 0; i < _bytes + recv_buffer_size_; ++i)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int) recv_buffer_[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
std::shared_ptr<endpoint_host> its_host = host_.lock();
if (its_host) {
if (!_error && 0 < _bytes) {
recv_buffer_size_ += _bytes;
+ boost::system::error_code its_error;
+ endpoint_type its_endpoint(socket_.remote_endpoint(its_error));
+ const boost::asio::ip::address its_remote_address(its_endpoint.address());
+ const std::uint16_t its_remote_port(its_endpoint.port());
size_t its_iteration_gap = 0;
bool has_full_message;
do {
@@ -217,25 +253,42 @@ void tcp_client_endpoint_impl::receive_cbk(
if (needs_forwarding) {
if (!has_enabled_magic_cookies_) {
its_host->on_message(&recv_buffer_[its_iteration_gap],
- current_message_size, this);
+ current_message_size, this,
+ boost::asio::ip::address(),
+ VSOMEIP_ROUTING_CLIENT,
+ its_remote_address,
+ its_remote_port);
} else {
// Only call on_message without a magic cookie in front of the buffer!
if (!is_magic_cookie(its_iteration_gap)) {
its_host->on_message(&recv_buffer_[its_iteration_gap],
- current_message_size, this);
+ current_message_size, this,
+ boost::asio::ip::address(),
+ VSOMEIP_ROUTING_CLIENT,
+ its_remote_address,
+ its_remote_port);
}
}
}
+ calculate_shrink_count();
recv_buffer_size_ -= current_message_size;
its_iteration_gap += current_message_size;
- } else if (has_enabled_magic_cookies_ && recv_buffer_size_ > 0){
+ missing_capacity_ = 0;
+ } else if (current_message_size > recv_buffer_size_) {
+ missing_capacity_ = current_message_size
+ - static_cast<std::uint32_t>(recv_buffer_size_);
+ } else if (VSOMEIP_SOMEIP_HEADER_SIZE > recv_buffer_size_) {
+ missing_capacity_ = VSOMEIP_SOMEIP_HEADER_SIZE
+ - static_cast<std::uint32_t>(recv_buffer_size_);
+ } else if (has_enabled_magic_cookies_ && recv_buffer_size_ > 0) {
uint32_t its_offset = find_magic_cookie(&recv_buffer_[its_iteration_gap], recv_buffer_size_);
if (its_offset < recv_buffer_size_) {
recv_buffer_size_ -= its_offset;
its_iteration_gap += its_offset;
has_full_message = true; // trigger next loop
}
- } else if (current_message_size > max_message_size_) {
+ } else if (max_message_size_ != MESSAGE_SIZE_UNLIMITED &&
+ current_message_size > max_message_size_) {
if (has_enabled_magic_cookies_) {
VSOMEIP_ERROR << "Received a TCP message which exceeds "
<< "maximum message size ("
@@ -252,6 +305,13 @@ void tcp_client_endpoint_impl::receive_cbk(
recv_buffer_size_ = 0;
return;
}
+ } else {
+ VSOMEIP_ERROR << "tce::c<" << this
+ << ">rcb: recv_buffer_size is: " << std::dec
+ << recv_buffer_size_ << " but couldn't read "
+ "out message_size. recv_buffer_capacity: "
+ << recv_buffer_.capacity()
+ << " its_iteration_gap: " << its_iteration_gap;
}
} while (has_full_message && recv_buffer_size_);
if (its_iteration_gap) {
@@ -259,6 +319,11 @@ void tcp_client_endpoint_impl::receive_cbk(
for (size_t i = 0; i < recv_buffer_size_; ++i) {
recv_buffer_[i] = recv_buffer_[i + its_iteration_gap];
}
+ // Still more capacity needed after shifting everything to front?
+ if (missing_capacity_ &&
+ missing_capacity_ <= recv_buffer_.capacity() - recv_buffer_size_) {
+ missing_capacity_ = 0;
+ }
}
receive();
} else {
@@ -273,4 +338,16 @@ void tcp_client_endpoint_impl::receive_cbk(
}
}
+void tcp_client_endpoint_impl::calculate_shrink_count() {
+ if (buffer_shrink_threshold_) {
+ if (recv_buffer_.capacity() != recv_buffer_size_initial_) {
+ if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) {
+ shrink_count_++;
+ } else {
+ shrink_count_ = 0;
+ }
+ }
+ }
+}
+
} // namespace vsomeip
diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
index 8e98fd0..4c5bdc7 100644
--- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
@@ -14,6 +14,7 @@
#include "../include/tcp_server_endpoint_impl.hpp"
#include "../../logging/include/logger.hpp"
#include "../../utility/include/utility.hpp"
+#include "../../configuration/include/internal.hpp"
namespace ip = boost::asio::ip;
@@ -21,10 +22,11 @@ namespace vsomeip {
tcp_server_endpoint_impl::tcp_server_endpoint_impl(
std::shared_ptr<endpoint_host> _host, endpoint_type _local,
- boost::asio::io_service &_io, std::uint32_t _max_message_size)
+ boost::asio::io_service &_io, std::uint32_t _max_message_size,
+ std::uint32_t _buffer_shrink_threshold)
: tcp_server_endpoint_base_impl(_host, _local, _io, _max_message_size),
acceptor_(_io),
- current_(0) {
+ buffer_shrink_threshold_(_buffer_shrink_threshold) {
is_supporting_magic_cookies_ = true;
boost::system::error_code ec;
@@ -48,7 +50,8 @@ bool tcp_server_endpoint_impl::is_local() const {
void tcp_server_endpoint_impl::start() {
connection::ptr new_connection = connection::create(
std::dynamic_pointer_cast<tcp_server_endpoint_impl>(
- shared_from_this()), max_message_size_);
+ shared_from_this()), max_message_size_,
+ buffer_shrink_threshold_);
acceptor_.async_accept(new_connection->get_socket(),
std::bind(&tcp_server_endpoint_impl::accept_cbk,
@@ -92,7 +95,7 @@ void tcp_server_endpoint_impl::send_queued(queue_iterator_type _queue_iterator)
if (connection_iterator != connections_.end()) {
its_connection = connection_iterator->second;
} else {
- VSOMEIP_DEBUG << "Didn't find connection: "
+ VSOMEIP_INFO << "Didn't find connection: "
<< _queue_iterator->first.address().to_string() << ":" << std::dec
<< static_cast<std::uint16_t>(_queue_iterator->first.port())
<< " dropping message.";
@@ -113,7 +116,7 @@ bool tcp_server_endpoint_impl::is_established(std::shared_ptr<endpoint_definitio
if (connection_iterator != connections_.end()) {
is_connected = true;
} else {
- VSOMEIP_DEBUG << "Didn't find TCP connection: Subscription "
+ VSOMEIP_INFO << "Didn't find TCP connection: Subscription "
<< "rejected for: " << endpoint.address().to_string() << ":"
<< std::dec << static_cast<std::uint16_t>(endpoint.port());
}
@@ -121,36 +124,6 @@ bool tcp_server_endpoint_impl::is_established(std::shared_ptr<endpoint_definitio
return is_connected;
}
-bool tcp_server_endpoint_impl::get_remote_address(
- boost::asio::ip::address &_address) const {
-
- if (current_) {
- boost::system::error_code its_error;
- tcp_server_endpoint_impl::endpoint_type its_endpoint =
- current_->get_socket().remote_endpoint(its_error);
- if (!its_error) {
- boost::asio::ip::address its_address = its_endpoint.address();
- if (!its_address.is_unspecified()) {
- _address = its_address;
- return true;
- }
- }
- }
- return false;
-}
-
-unsigned short tcp_server_endpoint_impl::get_remote_port() const {
- if (current_) {
- boost::system::error_code its_error;
- tcp_server_endpoint_impl::endpoint_type its_endpoint =
- current_->get_socket().remote_endpoint(its_error);
- if (!its_error) {
- return its_endpoint.port();
- }
- }
- return 0;
-}
-
bool tcp_server_endpoint_impl::get_default_target(service_t,
tcp_server_endpoint_impl::endpoint_type &) const {
return false;
@@ -161,6 +134,7 @@ void tcp_server_endpoint_impl::remove_connection(
std::lock_guard<std::mutex> its_lock(connections_mutex_);
for (auto it = connections_.begin(); it != connections_.end();) {
if (it->second.get() == _connection) {
+
it = connections_.erase(it);
break;
} else {
@@ -183,10 +157,11 @@ void tcp_server_endpoint_impl::accept_cbk(connection::ptr _connection,
}
}
if (_error != boost::asio::error::bad_descriptor
- && _error != boost::asio::error::operation_aborted) {
+ && _error != boost::asio::error::operation_aborted
+ && _error != boost::asio::error::no_descriptors) {
start();
} else {
- VSOMEIP_DEBUG << "Endpoint was stopped, don't starting again";
+ VSOMEIP_INFO << "Endpoint was stopped, don't starting again";
}
}
@@ -204,18 +179,30 @@ bool tcp_server_endpoint_impl::is_reliable() const {
///////////////////////////////////////////////////////////////////////////////
tcp_server_endpoint_impl::connection::connection(
std::weak_ptr<tcp_server_endpoint_impl> _server,
- std::uint32_t _max_message_size) :
- socket_(_server.lock()->service_), server_(_server),
+ std::uint32_t _max_message_size,
+ std::uint32_t _initial_recv_buffer_size,
+ std::uint32_t _buffer_shrink_threshold) :
+ socket_(_server.lock()->service_),
+ server_(_server),
max_message_size_(_max_message_size),
- recv_buffer_(_max_message_size, 0),
- recv_buffer_size_(0) {
+ recv_buffer_size_initial_(_initial_recv_buffer_size),
+ recv_buffer_(_initial_recv_buffer_size, 0),
+ recv_buffer_size_(0),
+ missing_capacity_(0),
+ shrink_count_(0),
+ buffer_shrink_threshold_(_buffer_shrink_threshold) {
}
tcp_server_endpoint_impl::connection::ptr
tcp_server_endpoint_impl::connection::create(
std::weak_ptr<tcp_server_endpoint_impl> _server,
- std::uint32_t _max_message_size) {
- return ptr(new connection(_server, _max_message_size));
+ std::uint32_t _max_message_size, std::uint32_t _buffer_shrink_threshold) {
+ const std::uint32_t its_initial_receveive_buffer_size =
+ VSOMEIP_SOMEIP_HEADER_SIZE + 8 + MAGIC_COOKIE_SIZE + 8
+ + VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+ return ptr(new connection(_server, _max_message_size,
+ its_initial_receveive_buffer_size,
+ _buffer_shrink_threshold));
}
tcp_server_endpoint_impl::socket_type &
@@ -231,13 +218,26 @@ void tcp_server_endpoint_impl::connection::start() {
}
void tcp_server_endpoint_impl::connection::receive() {
- if (recv_buffer_size_ == max_message_size_) {
- // Overrun -> Reset buffer
- recv_buffer_size_ = 0;
- }
std::lock_guard<std::mutex> its_lock(stop_mutex_);
if(socket_.is_open()) {
- size_t buffer_size = max_message_size_ - recv_buffer_size_;
+ const std::size_t its_capacity(recv_buffer_.capacity());
+ size_t buffer_size = its_capacity - recv_buffer_size_;
+ if (missing_capacity_) {
+ const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_);
+ if (its_capacity < its_required_capacity) {
+ recv_buffer_.reserve(its_required_capacity);
+ recv_buffer_.resize(its_required_capacity, 0x0);
+ }
+ buffer_size = missing_capacity_;
+ missing_capacity_ = 0;
+ } else if (buffer_shrink_threshold_
+ && shrink_count_ > buffer_shrink_threshold_
+ && recv_buffer_size_ == 0) {
+ recv_buffer_.resize(recv_buffer_size_initial_, 0x0);
+ recv_buffer_.shrink_to_fit();
+ buffer_size = recv_buffer_size_initial_;
+ shrink_count_ = 0;
+ }
socket_.async_receive(boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
std::bind(&tcp_server_endpoint_impl::connection::receive_cbk,
shared_from_this(), std::placeholders::_1,
@@ -276,7 +276,8 @@ void tcp_server_endpoint_impl::connection::send_queued(
void tcp_server_endpoint_impl::connection::send_magic_cookie(
message_buffer_ptr_t &_buffer) {
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
+ if (recv_buffer_size_initial_ == MESSAGE_SIZE_UNLIMITED
+ || recv_buffer_size_initial_ - _buffer->size() >=
VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
_buffer->insert(_buffer->begin(), SERVICE_COOKIE,
SERVICE_COOKIE + sizeof(SERVICE_COOKIE));
@@ -306,13 +307,17 @@ void tcp_server_endpoint_impl::connection::receive_cbk(
for (std::size_t i = 0; i < _bytes + recv_buffer_size_; ++i)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int) recv_buffer_[i] << " ";
- VSOMEIP_DEBUG<< msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
std::shared_ptr<endpoint_host> its_host = its_server->host_.lock();
if (its_host) {
if (!_error && 0 < _bytes) {
recv_buffer_size_ += _bytes;
+ boost::system::error_code its_error;
+ endpoint_type its_endpoint(socket_.remote_endpoint(its_error));
+ const boost::asio::ip::address its_remote_address(its_endpoint.address());
+ const std::uint16_t its_remote_port(its_endpoint.port());
size_t its_iteration_gap = 0;
bool has_full_message;
do {
@@ -334,7 +339,8 @@ void tcp_server_endpoint_impl::connection::receive_cbk(
VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
if (!is_magic_cookie(its_iteration_gap)) {
its_host->on_error(&recv_buffer_[its_iteration_gap],
- static_cast<length_t>(recv_buffer_size_), its_server.get());
+ static_cast<length_t>(recv_buffer_size_),its_server.get(),
+ its_remote_address, its_remote_port);
}
current_message_size = its_offset;
needs_forwarding = false;
@@ -357,27 +363,32 @@ void tcp_server_endpoint_impl::connection::receive_cbk(
std::lock_guard<std::mutex> its_lock(stop_mutex_);
if (socket_.is_open()) {
its_server->clients_mutex_.lock();
- boost::system::error_code its_error;
- endpoint_type its_endpoint(socket_.remote_endpoint(its_error));
if (!its_error) {
its_server->clients_[its_client][its_session] = its_endpoint;
}
its_server->clients_mutex_.unlock();
- its_server->current_ = this;
}
}
}
if (!its_server->has_enabled_magic_cookies_) {
its_host->on_message(&recv_buffer_[its_iteration_gap],
- current_message_size, its_server.get());
+ current_message_size, its_server.get(),
+ boost::asio::ip::address(),
+ VSOMEIP_ROUTING_CLIENT, its_remote_address,
+ its_remote_port);
} else {
// Only call on_message without a magic cookie in front of the buffer!
if (!is_magic_cookie(its_iteration_gap)) {
its_host->on_message(&recv_buffer_[its_iteration_gap],
- current_message_size, its_server.get());
+ current_message_size, its_server.get(),
+ boost::asio::ip::address(),
+ VSOMEIP_ROUTING_CLIENT,
+ its_remote_address, its_remote_port);
}
}
}
+ calculate_shrink_count();
+ missing_capacity_ = 0;
recv_buffer_size_ -= current_message_size;
its_iteration_gap += current_message_size;
} else if (its_server->has_enabled_magic_cookies_ && recv_buffer_size_ > 0){
@@ -388,21 +399,25 @@ void tcp_server_endpoint_impl::connection::receive_cbk(
VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
if (!is_magic_cookie(its_iteration_gap)) {
its_host->on_error(&recv_buffer_[its_iteration_gap],
- static_cast<length_t>(recv_buffer_size_), its_server.get());
+ static_cast<length_t>(recv_buffer_size_), its_server.get(),
+ its_remote_address, its_remote_port);
}
recv_buffer_size_ -= its_offset;
its_iteration_gap += its_offset;
has_full_message = true; // trigger next loop
if (!is_magic_cookie(its_iteration_gap)) {
its_host->on_error(&recv_buffer_[its_iteration_gap],
- static_cast<length_t>(recv_buffer_size_), its_server.get());
+ static_cast<length_t>(recv_buffer_size_), its_server.get(),
+ its_remote_address, its_remote_port);
}
}
- } else if (current_message_size > max_message_size_) {
+ } else if (max_message_size_ != MESSAGE_SIZE_UNLIMITED
+ && current_message_size > max_message_size_) {
if (its_server->has_enabled_magic_cookies_) {
VSOMEIP_ERROR << "Received a TCP message which exceeds "
<< "maximum message size ("
<< std::dec << current_message_size
+ << " > " << std::dec << max_message_size_
<< "). Magic Cookies are enabled: "
<< "Resetting receiver.";
recv_buffer_size_ = 0;
@@ -410,18 +425,41 @@ void tcp_server_endpoint_impl::connection::receive_cbk(
VSOMEIP_ERROR << "Received a TCP message which exceeds "
<< "maximum message size ("
<< std::dec << current_message_size
+ << " > " << std::dec << max_message_size_
<< ") Magic cookies are disabled: "
<< "Connection will be disabled!";
recv_buffer_size_ = 0;
return;
}
}
+
+ if (!has_full_message) {
+ if (current_message_size > recv_buffer_size_) {
+ missing_capacity_ = current_message_size
+ - static_cast<std::uint32_t>(recv_buffer_size_);
+ } else if (VSOMEIP_SOMEIP_HEADER_SIZE > recv_buffer_size_) {
+ missing_capacity_ = VSOMEIP_SOMEIP_HEADER_SIZE
+ - static_cast<std::uint32_t>(recv_buffer_size_);
+ } else {
+ VSOMEIP_ERROR << "tse::c<" << this
+ << ">rcb: recv_buffer_size is: " << std::dec
+ << recv_buffer_size_ << " but couldn't read "
+ "out message_size. recv_buffer_capacity: "
+ << recv_buffer_.capacity()
+ << " its_iteration_gap: " << its_iteration_gap;
+ }
+ }
} while (has_full_message && recv_buffer_size_);
if (its_iteration_gap) {
// Copy incomplete message to front for next receive_cbk iteration
for (size_t i = 0; i < recv_buffer_size_; ++i) {
recv_buffer_[i] = recv_buffer_[i + its_iteration_gap];
}
+ // Still more capacity needed after shifting everything to front?
+ if (missing_capacity_ &&
+ missing_capacity_ <= recv_buffer_.capacity() - recv_buffer_size_) {
+ missing_capacity_ = 0;
+ }
}
receive();
}
@@ -436,6 +474,18 @@ void tcp_server_endpoint_impl::connection::receive_cbk(
}
}
+void tcp_server_endpoint_impl::connection::calculate_shrink_count() {
+ if (buffer_shrink_threshold_) {
+ if (recv_buffer_.capacity() != recv_buffer_size_initial_) {
+ if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) {
+ shrink_count_++;
+ } else {
+ shrink_count_ = 0;
+ }
+ }
+ }
+}
+
client_t tcp_server_endpoint_impl::get_client(std::shared_ptr<endpoint_definition> _endpoint) {
endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port());
{
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
index 4513845..6025252 100644
--- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
@@ -17,19 +17,19 @@ namespace vsomeip {
udp_client_endpoint_impl::udp_client_endpoint_impl(
std::shared_ptr< endpoint_host > _host,
- endpoint_type _local,
- endpoint_type _remote,
+ endpoint_type _local,
+ endpoint_type _remote,
boost::asio::io_service &_io)
: udp_client_endpoint_base_impl(_host, _local, _remote, _io,
- VSOMEIP_MAX_UDP_MESSAGE_SIZE),
+ VSOMEIP_MAX_UDP_MESSAGE_SIZE),
recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0) {
}
udp_client_endpoint_impl::~udp_client_endpoint_impl() {
- std::shared_ptr<endpoint_host> its_host = host_.lock();
- if (its_host) {
- its_host->release_port(local_.port(), false);
- }
+ std::shared_ptr<endpoint_host> its_host = host_.lock();
+ if (its_host) {
+ its_host->release_port(local_.port(), false);
+ }
}
bool udp_client_endpoint_impl::is_local() const {
@@ -37,13 +37,18 @@ bool udp_client_endpoint_impl::is_local() const {
}
void udp_client_endpoint_impl::connect() {
- // In case a client endpoint port was configured,
- // bind to it before connecting
- if (local_.port() != ILLEGAL_PORT) {
- socket_.bind(local_);
- }
+ // In case a client endpoint port was configured,
+ // bind to it before connecting
+ if (local_.port() != ILLEGAL_PORT) {
+ boost::system::error_code its_bind_error;
+ socket_.bind(local_, its_bind_error);
+ if(its_bind_error) {
+ VSOMEIP_WARNING << "tcp_client_endpoint::connect: "
+ "Error binding socket: " << its_bind_error.message();
+ }
+ }
- socket_.async_connect(
+ socket_.async_connect(
remote_,
std::bind(
&udp_client_endpoint_base_impl::connect_cbk,
@@ -78,7 +83,7 @@ void udp_client_endpoint_impl::send_queued() {
for (std::size_t i = 0; i < its_buffer->size(); i++)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int)(*its_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
socket_.async_send(
boost::asio::buffer(*its_buffer),
@@ -108,18 +113,28 @@ void udp_client_endpoint_impl::receive() {
bool udp_client_endpoint_impl::get_remote_address(
boost::asio::ip::address &_address) const {
- _address = remote_.address();
+ const boost::asio::ip::address its_address = remote_.address();
+ if (its_address.is_unspecified()) {
+ return false;
+ }
+ _address = its_address;
return true;
}
unsigned short udp_client_endpoint_impl::get_local_port() const {
boost::system::error_code its_error;
- return socket_.local_endpoint(its_error).port();
+ if (socket_.is_open()) {
+ return socket_.local_endpoint(its_error).port();
+ }
+ return 0;
}
unsigned short udp_client_endpoint_impl::get_remote_port() const {
boost::system::error_code its_error;
- return socket_.remote_endpoint(its_error).port();
+ if (socket_.is_open()) {
+ return socket_.remote_endpoint(its_error).port();
+ }
+ return 0;
}
void udp_client_endpoint_impl::receive_cbk(
@@ -137,10 +152,15 @@ void udp_client_endpoint_impl::receive_cbk(
for (std::size_t i = 0; i < _bytes + recv_buffer_size_; ++i)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int) recv_buffer_[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
std::size_t remaining_bytes = _bytes;
std::size_t i = 0;
+ boost::system::error_code its_error;
+ endpoint_type its_endpoint(socket_.remote_endpoint(its_error));
+ const boost::asio::ip::address its_remote_address(its_endpoint.address());
+ const std::uint16_t its_remote_port(its_endpoint.port());
+
do {
uint32_t current_message_size
= utility::get_message_size(&this->recv_buffer_[i],
@@ -149,11 +169,17 @@ void udp_client_endpoint_impl::receive_cbk(
current_message_size <= remaining_bytes) {
remaining_bytes -= current_message_size;
- its_host->on_message(&recv_buffer_[i], current_message_size, this);
- } else {
- VSOMEIP_ERROR << "Received a unreliable vSomeIP message with bad length field";
- remaining_bytes = 0;
- }
+ its_host->on_message(&recv_buffer_[i], current_message_size,
+ this, boost::asio::ip::address(),
+ VSOMEIP_ROUTING_CLIENT, its_remote_address,
+ its_remote_port);
+ } else {
+ VSOMEIP_ERROR << "Received a unreliable vSomeIP message with bad "
+ "length field. Message size: " << current_message_size
+ << " Bytes. From: " << remote_.address() << ":"
+ << remote_.port() << ". Dropping message.";
+ remaining_bytes = 0;
+ }
i += current_message_size;
} while (remaining_bytes > 0);
}
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
index 1585826..28079d1 100644
--- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
@@ -129,7 +129,7 @@ void udp_server_endpoint_impl::send_queued(
for (std::size_t i = 0; i < its_buffer->size(); ++i)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int)(*its_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
socket_.async_send_to(
boost::asio::buffer(*its_buffer),
@@ -144,21 +144,6 @@ void udp_server_endpoint_impl::send_queued(
);
}
-bool udp_server_endpoint_impl::get_remote_address(
- boost::asio::ip::address &_address) const {
- boost::asio::ip::address its_address = remote_.address();
- if (its_address.is_unspecified()) {
- return false;
- } else {
- _address = its_address;
- }
- return true;
-}
-
-unsigned short udp_server_endpoint_impl::get_remote_port() const {
- return remote_.port();
-}
-
bool udp_server_endpoint_impl::is_joined(const std::string &_address) const {
return (joined_.find(_address) != joined_.end());
}
@@ -193,7 +178,7 @@ void udp_server_endpoint_impl::join(const std::string &_address) {
}
joined_.insert(_address);
} else {
- VSOMEIP_DEBUG << "udp_server_endpoint_impl::join: "
+ VSOMEIP_INFO << "udp_server_endpoint_impl::join: "
"Trying to join already joined address: " << _address;
}
}
@@ -257,13 +242,15 @@ void udp_server_endpoint_impl::receive_cbk(
for (std::size_t i = 0; i < _bytes; ++i)
msg << std::hex << std::setw(2) << std::setfill('0')
<< (int) recv_buffer_[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
std::shared_ptr<endpoint_host> its_host = this->host_.lock();
if (its_host) {
if (!_error && 0 < _bytes) {
std::size_t remaining_bytes = _bytes;
std::size_t i = 0;
+ const boost::asio::ip::address its_remote_address(remote_.address());
+ const std::uint16_t its_remote_port(remote_.port());
do {
uint32_t current_message_size
= utility::get_message_size(&this->recv_buffer_[i],
@@ -290,7 +277,10 @@ void udp_server_endpoint_impl::receive_cbk(
if (its_service != VSOMEIP_SD_SERVICE ||
(current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE &&
current_message_size >= remaining_bytes)) {
- its_host->on_message(&recv_buffer_[i], current_message_size, this, _destination);
+ its_host->on_message(&recv_buffer_[i],
+ current_message_size, this, _destination,
+ VSOMEIP_ROUTING_CLIENT, its_remote_address,
+ its_remote_port);
} else {
//ignore messages for service discovery with shorter SomeIP length
VSOMEIP_ERROR << "Received an unreliable vSomeIP SD message with too short length field";
@@ -301,7 +291,9 @@ void udp_server_endpoint_impl::receive_cbk(
service_t its_service = VSOMEIP_BYTES_TO_WORD(recv_buffer_[VSOMEIP_SERVICE_POS_MIN],
recv_buffer_[VSOMEIP_SERVICE_POS_MAX]);
if (its_service != VSOMEIP_SD_SERVICE) {
- its_host->on_error(&recv_buffer_[i], (uint32_t)remaining_bytes, this);
+ its_host->on_error(&recv_buffer_[i],
+ (uint32_t)remaining_bytes, this,
+ its_remote_address, its_remote_port);
}
remaining_bytes = 0;
}
diff --git a/implementation/helper/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/boost/asio/detail/socket_ops_ext.hpp
index 9280830..a272202 100644
--- a/implementation/helper/boost/asio/detail/socket_ops_ext.hpp
+++ b/implementation/helper/boost/asio/detail/socket_ops_ext.hpp
@@ -37,7 +37,7 @@ BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state,
BOOST_ASIO_DECL void complete_iocp_recvfrom(
const weak_cancel_token_type& cancel_token,
boost::system::error_code& ec,
- boost::asio::ip::address& da);
+ boost::asio::ip::address& da);
#else // defined(BOOST_ASIO_HAS_IOCP)
diff --git a/implementation/logging/src/dlt_sink_backend.cpp b/implementation/logging/src/dlt_sink_backend.cpp
index 9da5ae9..0af7722 100644
--- a/implementation/logging/src/dlt_sink_backend.cpp
+++ b/implementation/logging/src/dlt_sink_backend.cpp
@@ -21,9 +21,7 @@ dlt_sink_backend::dlt_sink_backend(const std::string &_app_id,
const std::string &_context_id) {
(void)_app_id;
#ifdef USE_DLT
- DLT_REGISTER_CONTEXT_LL_TS(dlt_, _context_id.c_str(),
- VSOMEIP_LOG_DEFAULT_CONTEXT_NAME, DLT_LOG_DEBUG,
- DLT_TRACE_STATUS_ON);
+ DLT_REGISTER_CONTEXT(dlt_, _context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME);
#else
(void)_context_id;
#endif
diff --git a/implementation/message/include/deserializer.hpp b/implementation/message/include/deserializer.hpp
index 0588aa7..7add37c 100644
--- a/implementation/message/include/deserializer.hpp
+++ b/implementation/message/include/deserializer.hpp
@@ -17,8 +17,9 @@ class message;
class deserializer {
public:
- VSOMEIP_EXPORT deserializer();
- VSOMEIP_EXPORT deserializer(byte_t *_data, std::size_t _length);
+ VSOMEIP_EXPORT deserializer(std::uint32_t _buffer_shrink_threshold);
+ VSOMEIP_EXPORT deserializer(byte_t *_data, std::size_t _length,
+ std::uint32_t _buffer_shrink_threshold);
VSOMEIP_EXPORT deserializer(const deserializer& _other);
VSOMEIP_EXPORT virtual ~deserializer();
@@ -55,6 +56,10 @@ protected:
std::vector<byte_t> data_;
std::vector<byte_t>::iterator position_;
std::size_t remaining_;
+private:
+ const std::uint32_t buffer_shrink_threshold_;
+ std::uint32_t shrink_count_;
+
};
} // namespace vsomeip
diff --git a/implementation/message/include/serializer.hpp b/implementation/message/include/serializer.hpp
index a61f9ef..f19c853 100644
--- a/implementation/message/include/serializer.hpp
+++ b/implementation/message/include/serializer.hpp
@@ -17,7 +17,7 @@ class serializable;
class VSOMEIP_IMPORT_EXPORT serializer {
public:
- serializer();
+ serializer(std::uint32_t _buffer_shrink_threshold);
virtual ~serializer();
bool serialize(const serializable *_from);
@@ -26,12 +26,12 @@ public:
bool serialize(const uint16_t _value);
bool serialize(const uint32_t _value, bool _omit_last_byte = false);
bool serialize(const uint8_t *_data, uint32_t _length);
+ bool serialize(const std::vector<byte_t> &_data);
- virtual uint8_t * get_data() const;
+ virtual const uint8_t * get_data() const;
virtual uint32_t get_capacity() const;
virtual uint32_t get_size() const;
- virtual void create_data(uint32_t _capacity);
virtual void set_data(uint8_t *_data, uint32_t _capacity);
virtual void reset();
@@ -40,11 +40,9 @@ public:
virtual void show();
#endif
private:
- byte_t * data_;
- uint32_t capacity_;
-
- byte_t *position_;
- uint32_t remaining_;
+ std::vector<byte_t> data_;
+ std::uint32_t shrink_count_;
+ std::uint32_t buffer_shrink_threshold_;
};
} // namespace vsomeip
diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp
index fb6f670..63713e3 100644
--- a/implementation/message/src/deserializer.cpp
+++ b/implementation/message/src/deserializer.cpp
@@ -17,20 +17,28 @@
namespace vsomeip {
-deserializer::deserializer()
+deserializer::deserializer(std::uint32_t _buffer_shrink_threshold)
: position_(data_.begin()),
- remaining_(0) {
+ remaining_(0),
+ buffer_shrink_threshold_(_buffer_shrink_threshold),
+ shrink_count_(0) {
}
-deserializer::deserializer(byte_t *_data, std::size_t _length)
+deserializer::deserializer(byte_t *_data, std::size_t _length,
+ std::uint32_t _buffer_shrink_threshold)
: data_(_data, _data + _length),
position_(data_.begin()),
- remaining_(_length) {
+ remaining_(_length),
+ buffer_shrink_threshold_(_buffer_shrink_threshold),
+ shrink_count_(0) {
}
deserializer::deserializer(const deserializer &_other)
: data_(_other.data_),
- position_(_other.position_){
+ position_(_other.position_),
+ remaining_(_other.remaining_),
+ buffer_shrink_threshold_(_other.buffer_shrink_threshold_),
+ shrink_count_(_other.shrink_count_) {
}
deserializer::~deserializer() {
@@ -183,9 +191,20 @@ void deserializer::drop_data(std::size_t _length) {
}
void deserializer::reset() {
- data_.erase(data_.begin(), position_);
+ if (buffer_shrink_threshold_) {
+ if (data_.size() < (data_.capacity() >> 1)) {
+ shrink_count_++;
+ } else {
+ shrink_count_ = 0;
+ }
+ }
+ data_.clear();
position_ = data_.begin();
remaining_ = data_.size();
+ if (buffer_shrink_threshold_ && shrink_count_ > buffer_shrink_threshold_) {
+ data_.shrink_to_fit();
+ shrink_count_ = 0;
+ }
}
#ifdef VSOMEIP_DEBUGGING
@@ -198,7 +217,7 @@ void deserializer::show() const {
for (int i = 0; i < data_.size(); ++i)
its_message << std::hex << std::setw(2) << std::setfill('0')
<< (int)data_[i] << " ";
- VSOMEIP_DEBUG << its_message;
+ VSOMEIP_INFO << its_message;
}
#endif
diff --git a/implementation/message/src/message_header_impl.cpp b/implementation/message/src/message_header_impl.cpp
index 3262c8d..fb33bc1 100644
--- a/implementation/message/src/message_header_impl.cpp
+++ b/implementation/message/src/message_header_impl.cpp
@@ -13,22 +13,23 @@
namespace vsomeip {
message_header_impl::message_header_impl()
- : service_(0x0), method_(0x0),
+ : service_(0x0), method_(0x0), length_(0x0),
client_(0x0), session_(0x0),
protocol_version_(0x1), interface_version_(0x0),
type_(message_type_e::MT_UNKNOWN),
code_(return_code_e::E_UNKNOWN),
- instance_(0x0) {
+ instance_(0x0), owner_(0x0) {
};
message_header_impl::message_header_impl(const message_header_impl &_header)
: service_(_header.service_), method_(_header.method_),
+ length_(_header.length_),
client_(_header.client_), session_(_header.session_),
protocol_version_(_header.protocol_version_),
interface_version_(_header.interface_version_),
type_(_header.type_),
code_(_header.code_),
- instance_(_header.instance_) {
+ instance_(_header.instance_), owner_(_header.owner_) {
};
bool message_header_impl::serialize(serializer *_to) const {
diff --git a/implementation/message/src/payload_impl.cpp b/implementation/message/src/payload_impl.cpp
index 663a7b8..8920e0c 100644
--- a/implementation/message/src/payload_impl.cpp
+++ b/implementation/message/src/payload_impl.cpp
@@ -69,7 +69,7 @@ void payload_impl::set_data(std::vector< byte_t > &&_data) {
}
bool payload_impl::serialize(serializer *_to) const {
- return (0 != _to && _to->serialize(data_.data(), uint32_t(data_.size())));
+ return (0 != _to && _to->serialize(data_));
}
bool payload_impl::deserialize(deserializer *_from) {
diff --git a/implementation/message/src/serializer.cpp b/implementation/message/src/serializer.cpp
index 6c064ab..97ba410 100644
--- a/implementation/message/src/serializer.cpp
+++ b/implementation/message/src/serializer.cpp
@@ -3,29 +3,28 @@
// 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 <cstring>
+//#include <cstring>
#ifdef VSOMEIP_DEBUGGING
#include <iomanip>
#include <sstream>
-
-#include "../../logging/include/logger.hpp"
#endif
#include <vsomeip/internal/serializable.hpp>
#include "../include/serializer.hpp"
#include "../../utility/include/byteorder.hpp"
+#include "../../logging/include/logger.hpp"
namespace vsomeip {
-serializer::serializer()
- : data_(0), capacity_(0), position_(0), remaining_(0) {
+serializer::serializer(std::uint32_t _buffer_shrink_threshold) :
+ data_(0),
+ shrink_count_(0),
+ buffer_shrink_threshold_(_buffer_shrink_threshold) {
}
serializer::~serializer() {
- if (0 != data_)
- delete [] data_;
};
bool serializer::serialize(const serializable *_from) {
@@ -33,104 +32,90 @@ bool serializer::serialize(const serializable *_from) {
}
bool serializer::serialize(const uint8_t _value) {
- if (1 > remaining_)
- return false;
-
- *position_++ = _value;
- remaining_--;
-
+ data_.push_back(_value);
return true;
}
bool serializer::serialize(const uint16_t _value) {
- if (2 > remaining_)
- return false;
-
- *position_++ = VSOMEIP_WORD_BYTE1(_value);
- *position_++ = VSOMEIP_WORD_BYTE0(_value);
- remaining_ -= 2;
-
+ data_.push_back(VSOMEIP_WORD_BYTE1(_value));
+ data_.push_back(VSOMEIP_WORD_BYTE0(_value));
return true;
}
bool serializer::serialize(const uint32_t _value, bool _omit_last_byte) {
- if (3 > remaining_ || (!_omit_last_byte && 4 > remaining_))
- return false;
-
if (!_omit_last_byte) {
- *position_++ = VSOMEIP_LONG_BYTE3(_value);
- remaining_--;
+ data_.push_back(VSOMEIP_LONG_BYTE3(_value));
}
- *position_++ = VSOMEIP_LONG_BYTE2(_value);
- *position_++ = VSOMEIP_LONG_BYTE1(_value);
- *position_++ = VSOMEIP_LONG_BYTE0(_value);
- remaining_ -= 3;
-
+ data_.push_back(VSOMEIP_LONG_BYTE2(_value));
+ data_.push_back(VSOMEIP_LONG_BYTE1(_value));
+ data_.push_back(VSOMEIP_LONG_BYTE0(_value));
return true;
}
bool serializer::serialize(const uint8_t *_data, uint32_t _length) {
- if (_length > remaining_)
+ try {
+ data_.insert(data_.end(), _data, _data + _length);
+ } catch(const std::bad_alloc &e) {
+ VSOMEIP_ERROR << "Couldn't allocate memory in serializer::serialize(*_data, length)" << e.what();
return false;
+ }
+ return true;
+}
- ::memcpy(position_, _data, _length);
- position_ += _length;
- remaining_ -= _length;
-
+bool serializer::serialize(const std::vector<byte_t> &_data) {
+ try {
+ data_.insert(data_.end(),_data.begin(), _data.end());
+ } catch(const std::bad_alloc &e) {
+ VSOMEIP_ERROR << "Couldn't allocate memory in serializer::serialize(vector)" << e.what();
+ return false;
+ }
return true;
}
-byte_t * serializer::get_data() const {
- return data_;
+const byte_t * serializer::get_data() const {
+ return data_.data();
}
uint32_t serializer::get_capacity() const {
- return capacity_;
+ return static_cast<std::uint32_t>(data_.max_size());
}
uint32_t serializer::get_size() const {
- return capacity_ - remaining_;
-}
-
-void serializer::create_data(uint32_t _capacity) {
- if (0 != data_)
- delete [] data_;
-
- data_ = new byte_t[_capacity];
- position_ = data_;
- if (0 != data_) {
- capacity_ = remaining_ = _capacity;
- } else {
- capacity_ = remaining_ = 0;
- }
+ return static_cast<std::uint32_t>(data_.size());
}
void serializer::set_data(byte_t *_data, uint32_t _capacity) {
- delete [] data_;
-
- data_ = _data;
- position_ = _data;
-
- if (0 != data_) {
- capacity_ = remaining_ = _capacity;
- } else {
- capacity_ = remaining_ = 0;
+ data_.clear();
+ try {
+ data_.insert(data_.end(), _data, _data + _capacity);
+ } catch(const std::bad_alloc &e) {
+ VSOMEIP_ERROR << "Couldn't allocate memory in serializer::set_data" << e.what();
}
}
void serializer::reset() {
- position_ = data_;
- remaining_ = capacity_;
+ if (buffer_shrink_threshold_) {
+ if (data_.size() < (data_.capacity() >> 1)) {
+ shrink_count_++;
+ } else {
+ shrink_count_ = 0;
+ }
+ }
+ data_.clear();
+ if (buffer_shrink_threshold_ && shrink_count_ > buffer_shrink_threshold_) {
+ data_.shrink_to_fit();
+ shrink_count_ = 0;
+ }
}
#ifdef VSOMEIP_DEBUGGING
void serializer::show() {
std::stringstream its_data;
its_data << "SERIALIZED: ";
- for (int i = 0; i < position_ - data_; ++i)
+ for (const byte_t& e : data_)
its_data << std::setw(2) << std::setfill('0')
- << std::hex << (int)data_[i];
- VSOMEIP_DEBUG << its_data.str();
+ << std::hex << (int)e;
+ VSOMEIP_INFO << its_data.str();
}
#endif
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp
index ef7e7eb..6e1de4a 100644
--- a/implementation/routing/include/event.hpp
+++ b/implementation/routing/include/event.hpp
@@ -124,6 +124,7 @@ private:
bool is_set_;
bool is_provided_;
+ std::mutex refs_mutex_;
std::map<client_t, std::map<bool, uint32_t>> refs_;
bool is_shadow_;
diff --git a/implementation/routing/include/routing_manager_base.hpp b/implementation/routing/include/routing_manager_base.hpp
index a1320ec..75d42c4 100644
--- a/implementation/routing/include/routing_manager_base.hpp
+++ b/implementation/routing/include/routing_manager_base.hpp
@@ -106,15 +106,17 @@ public:
virtual void on_disconnect(std::shared_ptr<endpoint> _endpoint) = 0;
virtual void on_message(const byte_t *_data, length_t _length,
endpoint *_receiver, const boost::asio::ip::address &_destination
- = boost::asio::ip::address(), client_t _bound_client = VSOMEIP_ROUTING_CLIENT) = 0;
+ = boost::asio::ip::address(), client_t _bound_client = VSOMEIP_ROUTING_CLIENT,
+ const boost::asio::ip::address &_remote_address = boost::asio::ip::address(),
+ std::uint16_t _remote_port = 0) = 0;
virtual void on_error(const byte_t *_data, length_t _length,
- endpoint *_receiver) = 0;
+ endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) = 0;
#ifndef WIN32
virtual bool check_credentials(client_t _client, uid_t _uid, gid_t _gid);
#endif
- virtual void on_clientendpoint_error(client_t _client);
-
virtual void set_routing_state(routing_state_e _routing_state) = 0;
protected:
@@ -172,6 +174,14 @@ protected:
void remove_pending_subscription(service_t _service, instance_t _instance);
+ void send_pending_notify_ones(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, client_t _client);
+
+private:
+ std::shared_ptr<endpoint> create_local_unlocked(client_t _client);
+ std::shared_ptr<endpoint> find_local_unlocked(client_t _client);
+
+protected:
routing_manager_host *host_;
boost::asio::io_service &io_;
client_t client_;
@@ -227,6 +237,12 @@ private:
std::map<client_t, std::shared_ptr<endpoint> > local_endpoints_;
mutable std::mutex local_endpoint_mutex_;
+
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<eventgroup_t,
+ std::shared_ptr<message> > > > pending_notify_ones_;
+ std::mutex pending_notify_ones_mutex_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp
index 3a60d8c..27a1b1e 100644
--- a/implementation/routing/include/routing_manager_host.hpp
+++ b/implementation/routing/include/routing_manager_host.hpp
@@ -30,7 +30,7 @@ public:
virtual void on_availability(service_t _service, instance_t _instance,
bool _is_available, major_version_t _major = DEFAULT_MAJOR, minor_version_t _minor = DEFAULT_MINOR) = 0;
virtual void on_state(state_type_e _state) = 0;
- virtual void on_message(std::shared_ptr<message> _message) = 0;
+ virtual void on_message(const std::shared_ptr<message> &&_message) = 0;
virtual void on_error(error_code_e _error) = 0;
virtual bool on_subscription(service_t _service, instance_t _instance, eventgroup_t _eventgroup,
client_t _client, bool _subscribed) = 0;
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp
index 81c1530..2671566 100644
--- a/implementation/routing/include/routing_manager_impl.hpp
+++ b/implementation/routing/include/routing_manager_impl.hpp
@@ -21,11 +21,12 @@
#include "routing_manager_base.hpp"
#include "routing_manager_stub_host.hpp"
+
+#include "../../endpoints/include/netlink_connector.hpp"
#include "../../service_discovery/include/service_discovery_host.hpp"
namespace vsomeip {
-class client_endpoint;
class configuration;
class deserializer;
class eventgroupinfo;
@@ -130,6 +131,9 @@ public:
void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor);
+ void on_availability(service_t _service, instance_t _instance,
+ bool _is_available, major_version_t _major, minor_version_t _minor);
+
void on_pong(client_t _client);
// interface "endpoint_host"
@@ -138,10 +142,14 @@ public:
bool _reliable, client_t _client);
void on_connect(std::shared_ptr<endpoint> _endpoint);
void on_disconnect(std::shared_ptr<endpoint> _endpoint);
- void on_error(const byte_t *_data, length_t _length, endpoint *_receiver);
+ void on_error(const byte_t *_data, length_t _length, endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
void on_message(const byte_t *_data, length_t _length, endpoint *_receiver,
const boost::asio::ip::address &_destination,
- client_t _bound_client);
+ client_t _bound_client,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
void on_message(service_t _service, instance_t _instance,
const byte_t *_data, length_t _size, bool _reliable);
void on_notification(client_t _client, service_t _service,
@@ -244,10 +252,16 @@ private:
void send_error(return_code_e _return_code, const byte_t *_data,
length_t _size, instance_t _instance, bool _reliable,
- endpoint *_receiver);
+ endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
void identify_for_subscribe(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major);
+ instance_t _instance, major_version_t _major,
+ subscription_type_e _subscription_type);
+ bool send_identify_message(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ bool _reliable);
bool supports_selective(service_t _service, instance_t _instance);
@@ -276,6 +290,8 @@ private:
void remove_identifying_client(service_t _service, instance_t _instance, client_t _client);
+ void unsubscribe_specific_client_at_sd(service_t _service, instance_t _instance, client_t _client);
+
inline std::shared_ptr<endpoint> find_local(service_t _service, instance_t _instance) {
return routing_manager_base::find_local(_service, _instance);
}
@@ -284,6 +300,10 @@ private:
instance_t _instance, eventgroup_t _eventgroup,
major_version_t _major, subscription_type_e _subscription_type);
+ void on_net_if_state_changed(std::string _if, bool _available);
+
+ void start_ip_routing();
+
std::shared_ptr<routing_manager_stub> stub_;
std::shared_ptr<sd::service_discovery> discovery_;
@@ -330,6 +350,13 @@ private:
boost::asio::steady_timer version_log_timer_;
+ bool if_state_running_;
+ std::mutex pending_sd_offers_mutex_;
+ std::vector<std::pair<service_t, instance_t>> pending_sd_offers_;
+#ifndef WIN32
+ std::shared_ptr<netlink_connector> netlink_connector_;
+#endif
+
#ifndef WITHOUT_SYSTEMD
boost::asio::steady_timer watchdog_timer_;
void watchdog_cbk(boost::system::error_code const &_error);
diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp
index 33c6c26..b3ae769 100644
--- a/implementation/routing/include/routing_manager_proxy.hpp
+++ b/implementation/routing/include/routing_manager_proxy.hpp
@@ -83,8 +83,12 @@ public:
void on_disconnect(std::shared_ptr<endpoint> _endpoint);
void on_message(const byte_t *_data, length_t _length, endpoint *_receiver,
const boost::asio::ip::address &_destination,
- client_t _bound_client);
- void on_error(const byte_t *_data, length_t _length, endpoint *_receiver);
+ client_t _bound_client,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
+ void on_error(const byte_t *_data, length_t _length, endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
void release_port(uint16_t _port, bool _reliable);
void on_routing_info(const byte_t *_data, uint32_t _size);
diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp
index f1e657a..9cc0255 100644
--- a/implementation/routing/include/routing_manager_stub.hpp
+++ b/implementation/routing/include/routing_manager_stub.hpp
@@ -44,8 +44,12 @@ public:
void on_disconnect(std::shared_ptr<endpoint> _endpoint);
void on_message(const byte_t *_data, length_t _length, endpoint *_receiver,
const boost::asio::ip::address &_destination,
- client_t _bound_client);
- void on_error(const byte_t *_data, length_t _length, endpoint *_receiver);
+ client_t _bound_client,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
+ void on_error(const byte_t *_data, length_t _length, endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port);
void release_port(uint16_t _port, bool _reliable);
void on_offer_service(client_t _client, service_t _service,
@@ -75,6 +79,7 @@ public:
void create_local_receiver();
bool send_ping(client_t _client);
+ bool is_registered(client_t _client) const;
void deregister_erroneous_client(client_t _client);
client_t get_client() const;
#ifndef WIN32
@@ -133,6 +138,7 @@ private:
DEREGISTER_ERROR_CASE = 0x3
};
std::map<client_t, std::vector<registration_type_e>> pending_client_registrations_;
+ const std::uint32_t max_local_message_size_;
static const std::vector<byte_t> its_ping_;
const std::chrono::milliseconds configured_watchdog_timeout_;
boost::asio::steady_timer pinged_clients_timer_;
diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp
index aa8fe02..65bb28b 100644
--- a/implementation/routing/include/routing_manager_stub_host.hpp
+++ b/implementation/routing/include/routing_manager_stub_host.hpp
@@ -63,6 +63,9 @@ public:
instance_t _instance, major_version_t _major,
minor_version_t _minor) = 0;
+ virtual void on_availability(service_t _service, instance_t _instance,
+ bool _is_available, major_version_t _major, minor_version_t _minor) = 0;
+
virtual std::shared_ptr<endpoint> find_local(client_t _client) = 0;
virtual std::shared_ptr<endpoint> find_or_create_local(
diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp
index 653f262..b6947d0 100644
--- a/implementation/routing/src/event.cpp
+++ b/implementation/routing/src/event.cpp
@@ -118,7 +118,7 @@ void event::set_payload(const std::shared_ptr<payload> &_payload,
}
}
} else {
- VSOMEIP_DEBUG << "Can't set payload for event " << std::hex
+ VSOMEIP_INFO << "Can't set payload for event " << std::hex
<< message_->get_method() << " as it isn't provided";
}
}
@@ -134,7 +134,7 @@ void event::set_payload(const std::shared_ptr<payload> &_payload, client_t _clie
}
}
} else {
- VSOMEIP_DEBUG << "Can't set payload for event " << std::hex
+ VSOMEIP_INFO << "Can't set payload for event " << std::hex
<< message_->get_method() << " as it isn't provided";
}
}
@@ -151,7 +151,7 @@ void event::set_payload(const std::shared_ptr<payload> &_payload,
}
}
} else {
- VSOMEIP_DEBUG << "Can't set payload for event " << std::hex
+ VSOMEIP_INFO << "Can't set payload for event " << std::hex
<< message_->get_method() << " as it isn't provided";
}
}
@@ -221,7 +221,7 @@ void event::notify(bool _flush) {
if (is_set_) {
routing_->send(VSOMEIP_ROUTING_CLIENT, message_, _flush);
} else {
- VSOMEIP_DEBUG << "Notify event " << std::hex << message_->get_method()
+ VSOMEIP_INFO << "Notify event " << std::hex << message_->get_method()
<< "failed. Event payload not set!";
}
}
@@ -230,7 +230,7 @@ void event::notify_one(const std::shared_ptr<endpoint_definition> &_target, bool
if (is_set_) {
routing_->send_to(_target, message_, _flush);
} else {
- VSOMEIP_DEBUG << "Notify one event " << std::hex << message_->get_method()
+ VSOMEIP_INFO << "Notify one event " << std::hex << message_->get_method()
<< "failed. Event payload not set!";
}
}
@@ -239,7 +239,7 @@ void event::notify_one(client_t _client, bool _flush) {
if (is_set_) {
routing_->send(_client, message_, _flush);
} else {
- VSOMEIP_DEBUG << "Notify one event " << std::hex << message_->get_method()
+ VSOMEIP_INFO << "Notify one event " << std::hex << message_->get_method()
<< " to client " << _client << " failed. Event payload not set!";
}
}
@@ -266,6 +266,7 @@ void event::reset_payload(const std::shared_ptr<payload> &_payload) {
}
void event::add_ref(client_t _client, bool _is_provided) {
+ std::lock_guard<std::mutex> its_lock(refs_mutex_);
auto its_client = refs_.find(_client);
if (its_client == refs_.end()) {
refs_[_client][_is_provided] = 1;
@@ -280,6 +281,7 @@ void event::add_ref(client_t _client, bool _is_provided) {
}
void event::remove_ref(client_t _client, bool _is_provided) {
+ std::lock_guard<std::mutex> its_lock(refs_mutex_);
auto its_client = refs_.find(_client);
if (its_client != refs_.end()) {
auto its_provided = its_client->second.find(_is_provided);
@@ -296,6 +298,7 @@ void event::remove_ref(client_t _client, bool _is_provided) {
}
bool event::has_ref() {
+ std::lock_guard<std::mutex> its_lock(refs_mutex_);
return refs_.size() != 0;
}
diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp
index fd63c4d..3b3e657 100644
--- a/implementation/routing/src/eventgroupinfo.cpp
+++ b/implementation/routing/src/eventgroupinfo.cpp
@@ -14,11 +14,11 @@
namespace vsomeip {
eventgroupinfo::eventgroupinfo()
- : major_(DEFAULT_MAJOR), ttl_(DEFAULT_TTL) {
+ : major_(DEFAULT_MAJOR), ttl_(DEFAULT_TTL), port_(ILLEGAL_PORT), threshold_(0) {
}
eventgroupinfo::eventgroupinfo(major_version_t _major, ttl_t _ttl)
- : major_(_major), ttl_(_ttl) {
+ : major_(_major), ttl_(_ttl), port_(ILLEGAL_PORT), threshold_(0) {
}
eventgroupinfo::~eventgroupinfo() {
diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp
index 89a5843..751a588 100644
--- a/implementation/routing/src/routing_manager_base.cpp
+++ b/implementation/routing/src/routing_manager_base.cpp
@@ -5,6 +5,8 @@
#include <iomanip>
+#include <vsomeip/runtime.hpp>
+
#include "../../utility/include/utility.hpp"
#include "../../utility/include/byteorder.hpp"
#include "../include/routing_manager_base.hpp"
@@ -20,13 +22,18 @@ routing_manager_base::routing_manager_base(routing_manager_host *_host) :
io_(host_->get_io()),
client_(host_->get_client()),
configuration_(host_->get_configuration()),
- serializer_(std::make_shared<serializer>())
+ serializer_(
+ std::make_shared<serializer>(
+ configuration_->get_buffer_shrink_threshold()))
#ifdef USE_DLT
, tc_(tc::trace_connector::get())
#endif
{
+ const uint32_t its_buffer_shrink_threshold =
+ configuration_->get_buffer_shrink_threshold();
for (int i = 0; i < VSOMEIP_MAX_DESERIALIZER; ++i) {
- deserializers_.push(std::make_shared<deserializer>());
+ deserializers_.push(
+ std::make_shared<deserializer>(its_buffer_shrink_threshold));
}
}
@@ -42,7 +49,6 @@ client_t routing_manager_base::get_client() const {
}
void routing_manager_base::init() {
- serializer_->create_data(configuration_->get_max_message_size_local());
}
bool routing_manager_base::offer_service(client_t _client, service_t _service,
@@ -74,6 +80,7 @@ void routing_manager_base::stop_offer_service(client_t _client, service_t _servi
(void)_client;
(void)_major;
(void)_minor;
+ std::map<event_t, std::shared_ptr<event> > events;
{
std::lock_guard<std::mutex> its_lock(events_mutex_);
auto its_events_service = events_.find(_service);
@@ -81,10 +88,14 @@ void routing_manager_base::stop_offer_service(client_t _client, service_t _servi
auto its_events_instance = its_events_service->second.find(_instance);
if (its_events_instance != its_events_service->second.end()) {
for (auto &e : its_events_instance->second)
- e.second->unset_payload();
+ events[e.first] = e.second;
+
}
}
}
+ for (auto &e : events) {
+ e.second->unset_payload();
+ }
{
std::lock_guard<std::mutex> its_lock(eventgroup_clients_mutex_);
auto its_service = eventgroup_clients_.find(_service);
@@ -346,6 +357,8 @@ void routing_manager_base::notify_one(service_t _service, instance_t _instance,
if (its_event) {
// Event is valid for service/instance
bool found_eventgroup(false);
+ bool already_subscribed(false);
+ eventgroup_t valid_group = 0;
// Iterate over all groups of the event to ensure at least
// one valid eventgroup for service/instance exists.
for (auto its_group : its_event->get_eventgroups()) {
@@ -353,11 +366,48 @@ void routing_manager_base::notify_one(service_t _service, instance_t _instance,
if (its_eventgroup) {
// Eventgroup is valid for service/instance
found_eventgroup = true;
+ valid_group = its_group;
+ if (find_local(_client)) {
+ std::lock_guard<std::mutex> its_lock(eventgroup_clients_mutex_);
+ auto its_service = eventgroup_clients_.find(_service);
+ if (its_service != eventgroup_clients_.end()) {
+ auto its_instance = its_service->second.find(_instance);
+ if (its_instance != its_service->second.end()) {
+ auto found_eventgroup = its_instance->second.find(its_group);
+ if (found_eventgroup != its_instance->second.end()) {
+ auto its_client = found_eventgroup->second.find(_client);
+ if (its_client != found_eventgroup->second.end()) {
+ already_subscribed = true;
+ }
+ }
+ }
+ }
+ } else {
+ // Remotes always needs to be marked as subscribed here
+ already_subscribed = true;
+ }
break;
}
}
if (found_eventgroup) {
- its_event->set_payload(_payload, _client, _force, _flush);
+ if (already_subscribed) {
+ its_event->set_payload(_payload, _client, _force, _flush);
+ } else {
+ std::shared_ptr<message> its_notification
+ = runtime::get()->create_notification();
+ its_notification->set_service(_service);
+ its_notification->set_instance(_instance);
+ its_notification->set_method(_event);
+ its_notification->set_payload(_payload);
+ auto service_info = find_service(_service, _instance);
+ if (service_info) {
+ its_notification->set_interface_version(service_info->get_major());
+ }
+ {
+ std::lock_guard<std::mutex> its_lock(pending_notify_ones_mutex_);
+ pending_notify_ones_[_service][_instance][valid_group] = its_notification;
+ }
+ }
}
} else {
VSOMEIP_WARNING << "Attempt to update the undefined event/field ["
@@ -366,6 +416,23 @@ void routing_manager_base::notify_one(service_t _service, instance_t _instance,
}
}
+void routing_manager_base::send_pending_notify_ones(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, client_t _client) {
+ std::lock_guard<std::mutex> its_lock(pending_notify_ones_mutex_);
+ auto its_service = pending_notify_ones_.find(_service);
+ if (its_service != pending_notify_ones_.end()) {
+ auto its_instance = its_service->second.find(_instance);
+ if (its_instance != its_service->second.end()) {
+ auto its_group = its_instance->second.find(_eventgroup);
+ if (its_group != its_instance->second.end()) {
+ notify_one(_service, _instance, its_group->second->get_method(),
+ its_group->second->get_payload(), _client, false, true);
+ its_instance->second.erase(_eventgroup);
+ }
+ }
+ }
+}
+
bool routing_manager_base::send(client_t its_client,
std::shared_ptr<message> _message,
bool _flush) {
@@ -472,19 +539,17 @@ client_t routing_manager_base::find_local_client(service_t _service, instance_t
return its_client;
}
-std::shared_ptr<endpoint> routing_manager_base::create_local(client_t _client) {
- std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
-
+std::shared_ptr<endpoint> routing_manager_base::create_local_unlocked(client_t _client) {
std::stringstream its_path;
its_path << VSOMEIP_BASE_PATH << std::hex << _client;
#ifdef WIN32
boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
int port = VSOMEIP_INTERNAL_BASE_PORT + _client;
- VSOMEIP_DEBUG<< "Connecting to ["
+ VSOMEIP_INFO << "Connecting to ["
<< std::hex << _client << "] at " << port;
#else
- VSOMEIP_DEBUG << "Client [" << std::hex << get_client() << "] is connecting to ["
+ VSOMEIP_INFO << "Client [" << std::hex << get_client() << "] is connecting to ["
<< std::hex << _client << "] at " << its_path.str();
#endif
std::shared_ptr<local_client_endpoint_impl> its_endpoint = std::make_shared<
@@ -501,24 +566,25 @@ std::shared_ptr<endpoint> routing_manager_base::create_local(client_t _client) {
// The routing master should not get an end-point when calling find_local
// with VSOMEIP_ROUTING_CLIENT as parameter
// as it indicates remote communication!
-
local_endpoints_[_client] = std::static_pointer_cast<endpoint>(its_endpoint);
- if (routing_manager_impl *rm_impl = dynamic_cast<routing_manager_impl*>(this)) {
- its_endpoint->register_error_callback(
+
+ routing_manager_impl *its_manager = dynamic_cast<routing_manager_impl*>(this);
+ if (its_manager != nullptr) {
+ its_endpoint->register_error_handler(
std::bind(&routing_manager_impl::on_clientendpoint_error,
- rm_impl, _client));
- } else {
- its_endpoint->register_error_callback(
- std::bind(&routing_manager_base::on_clientendpoint_error, this,
- _client));
+ its_manager, _client));
}
}
return (its_endpoint);
}
-std::shared_ptr<endpoint> routing_manager_base::find_local(client_t _client) {
+std::shared_ptr<endpoint> routing_manager_base::create_local(client_t _client) {
std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ return create_local_unlocked(_client);
+}
+
+std::shared_ptr<endpoint> routing_manager_base::find_local_unlocked(client_t _client) {
std::shared_ptr<endpoint> its_endpoint;
auto found_endpoint = local_endpoints_.find(_client);
if (found_endpoint != local_endpoints_.end()) {
@@ -527,10 +593,16 @@ std::shared_ptr<endpoint> routing_manager_base::find_local(client_t _client) {
return (its_endpoint);
}
+std::shared_ptr<endpoint> routing_manager_base::find_local(client_t _client) {
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ return find_local_unlocked(_client);
+}
+
std::shared_ptr<endpoint> routing_manager_base::find_or_create_local(client_t _client) {
- std::shared_ptr<endpoint> its_endpoint(find_local(_client));
+ std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
+ std::shared_ptr<endpoint> its_endpoint(find_local_unlocked(_client));
if (!its_endpoint) {
- its_endpoint = create_local(_client);
+ its_endpoint = create_local_unlocked(_client);
its_endpoint->start();
}
return (its_endpoint);
@@ -540,7 +612,7 @@ void routing_manager_base::remove_local(client_t _client) {
std::shared_ptr<endpoint> its_endpoint(find_local(_client));
if (its_endpoint) {
its_endpoint->stop();
- VSOMEIP_DEBUG << "Client [" << std::hex << get_client() << "] is closing connection to ["
+ VSOMEIP_INFO << "Client [" << std::hex << get_client() << "] is closing connection to ["
<< std::hex << _client << "]";
std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_);
local_endpoints_.erase(_client);
@@ -743,7 +815,7 @@ bool routing_manager_base::send_local_notification(client_t _client,
#ifdef USE_DLT
// Trace the message if a local client but will _not_ be forwarded to the routing manager
if (has_local && !has_remote) {
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -759,19 +831,18 @@ bool routing_manager_base::send_local(
std::shared_ptr<endpoint>& _target, client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
bool _flush, bool _reliable, uint8_t _command) const {
-
+ std::size_t its_complete_size = _size + sizeof(instance_t)
+ + sizeof(bool) + sizeof(bool);
client_t sender = get_client();
- size_t additional_size = 0;
if (_command == VSOMEIP_NOTIFY_ONE) {
- additional_size +=sizeof(client_t);
+ its_complete_size +=sizeof(client_t);
}
std::vector<byte_t> its_command(
- VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t)
- + sizeof(bool) + sizeof(bool) + additional_size);
+ VSOMEIP_COMMAND_HEADER_SIZE + its_complete_size);
its_command[VSOMEIP_COMMAND_TYPE_POS] = _command;
std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &sender,
sizeof(client_t));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size,
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_complete_size,
sizeof(_size));
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], _data,
_size);
@@ -811,12 +882,6 @@ bool routing_manager_base::insert_subscription(
return true;
}
-void routing_manager_base::on_clientendpoint_error(client_t _client) {
- VSOMEIP_ERROR << "Client endpoint error for application: " << std::hex
- << std::setfill('0') << std::setw(4) << _client;
- remove_local(_client);
-}
-
std::shared_ptr<deserializer> routing_manager_base::get_deserializer() {
std::unique_lock<std::mutex> its_lock(deserializer_mutex_);
while (deserializers_.empty()) {
diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp
index 7a27e4e..c1daec7 100644
--- a/implementation/routing/src/routing_manager_impl.cpp
+++ b/implementation/routing/src/routing_manager_impl.cpp
@@ -47,7 +47,8 @@ namespace vsomeip {
routing_manager_impl::routing_manager_impl(routing_manager_host *_host) :
routing_manager_base(_host),
- version_log_timer_(_host->get_io())
+ version_log_timer_(_host->get_io()),
+ if_state_running_(false)
#ifndef WITHOUT_SYSTEMD
, watchdog_timer_(_host->get_io())
#endif
@@ -87,16 +88,22 @@ void routing_manager_impl::init() {
discovery_ = (*its_runtime)->create_service_discovery(this);
discovery_->init();
}
- } else {
- init_routing_info(); // Static routing
}
}
void routing_manager_impl::start() {
- stub_->start();
- if (discovery_)
- discovery_->start();
+#ifndef WIN32
+ netlink_connector_ = std::make_shared<netlink_connector>(host_->get_io(),
+ configuration_->get_unicast_address());
+ netlink_connector_->register_net_if_changes_handler(
+ std::bind(&routing_manager_impl::on_net_if_state_changed,
+ this, std::placeholders::_1, std::placeholders::_2));
+ netlink_connector_->start();
+#else
+ start_ip_routing();
+#endif
+ stub_->start();
host_->on_state(state_type_e::ST_REGISTERED);
if (configuration_->log_version()) {
@@ -115,6 +122,11 @@ void routing_manager_impl::start() {
void routing_manager_impl::stop() {
version_log_timer_.cancel();
+#ifndef WIN32
+ if (netlink_connector_) {
+ netlink_connector_->stop();
+ }
+#endif
#ifndef WITHOUT_SYSTEMD
watchdog_timer_.cancel();
@@ -136,7 +148,7 @@ void routing_manager_impl::stop() {
bool routing_manager_impl::offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor) {
- VSOMEIP_DEBUG << "OFFER("
+ VSOMEIP_INFO << "OFFER("
<< std::hex << std::setw(4) << std::setfill('0') << _client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance
@@ -146,7 +158,14 @@ bool routing_manager_impl::offer_service(client_t _client, service_t _service,
return false;
}
- init_service_info(_service, _instance, true);
+ {
+ std::lock_guard<std::mutex> its_lock(pending_sd_offers_mutex_);
+ if (if_state_running_) {
+ init_service_info(_service, _instance, true);
+ } else {
+ pending_sd_offers_.push_back(std::make_pair(_service, _instance));
+ }
+ }
{
std::lock_guard<std::mutex> its_lock(events_mutex_);
@@ -181,7 +200,7 @@ bool routing_manager_impl::offer_service(client_t _client, service_t _service,
send_pending_subscriptions(_service, _instance, _major);
}
stub_->on_offer_service(_client, _service, _instance, _major, _minor);
- host_->on_availability(_service, _instance, true, _major, _minor);
+ on_availability(_service, _instance, true, _major, _minor);
return true;
}
@@ -189,23 +208,35 @@ void routing_manager_impl::stop_offer_service(client_t _client,
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) {
- VSOMEIP_DEBUG << "STOP OFFER("
+ VSOMEIP_INFO << "STOP OFFER("
<< std::hex << std::setw(4) << std::setfill('0') << _client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance
<< ":" << std::dec << int(_major) << "." << _minor << "]";
+ {
+ std::lock_guard<std::mutex> its_lock(pending_sd_offers_mutex_);
+ for (auto it = pending_sd_offers_.begin(); it != pending_sd_offers_.end(); ) {
+ if (it->first == _service && it->second == _instance) {
+ it = pending_sd_offers_.erase(it);
+ break;
+ } else {
+ ++it;
+ }
+ }
+ }
+
routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor);
on_stop_offer_service(_client, _service, _instance, _major, _minor);
stub_->on_stop_offer_service(_client, _service, _instance, _major, _minor);
- host_->on_availability(_service, _instance, false, _major, _minor);
+ on_availability(_service, _instance, false, _major, _minor);
}
void routing_manager_impl::request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor,
bool _use_exclusive_proxy) {
- VSOMEIP_DEBUG << "REQUEST("
+ VSOMEIP_INFO << "REQUEST("
<< std::hex << std::setw(4) << std::setfill('0') << _client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << ":"
@@ -226,7 +257,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service,
discovery_->request_service(_service, _instance, _major, _minor,
DEFAULT_TTL);
} else {
- VSOMEIP_DEBUG << std::hex
+ VSOMEIP_INFO << std::hex
<< "Avoid trigger SD find-service message"
<< " for local service/instance/major/minor: "
<< _service << "/" << _instance << std::dec
@@ -269,7 +300,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service,
void routing_manager_impl::release_service(client_t _client, service_t _service,
instance_t _instance) {
- VSOMEIP_DEBUG << "RELEASE("
+ VSOMEIP_INFO << "RELEASE("
<< std::hex << std::setw(4) << std::setfill('0') << _client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "]";
@@ -292,9 +323,11 @@ void routing_manager_impl::release_service(client_t _client, service_t _service,
std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
if(its_info && !its_info->is_local()) {
+ unsubscribe_specific_client_at_sd(_service, _instance, _client);
if(!its_info->get_requesters_size()) {
if(discovery_) {
discovery_->release_service(_service, _instance);
+ discovery_->unsubscribe_client(_service, _instance, VSOMEIP_ROUTING_CLIENT);
}
clear_client_endpoints(_service, _instance, true);
clear_client_endpoints(_service, _instance, false);
@@ -319,7 +352,7 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
subscription_type_e _subscription_type) {
- VSOMEIP_DEBUG << "SUBSCRIBE("
+ VSOMEIP_INFO << "SUBSCRIBE("
<< std::hex << std::setw(4) << std::setfill('0') << _client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "."
@@ -339,6 +372,7 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service,
stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup);
}
routing_manager_base::subscribe(_client, _service, _instance, _eventgroup, _major, _subscription_type);
+ send_pending_notify_ones(_service, _instance, _eventgroup, _client);
} else {
if (discovery_) {
client_t subscriber = VSOMEIP_ROUTING_CLIENT;
@@ -365,7 +399,7 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service,
}
}
if(identify) {
- identify_for_subscribe(_client, _service, _instance, _major);
+ identify_for_subscribe(_client, _service, _instance, _major, _subscription_type);
}
}
bool inserted = insert_subscription(_service, _instance, _eventgroup, _client);
@@ -404,7 +438,7 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service,
void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup) {
- VSOMEIP_DEBUG << "UNSUBSCRIBE("
+ VSOMEIP_INFO << "UNSUBSCRIBE("
<< std::hex << std::setw(4) << std::setfill('0') << _client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << _service << "."
<< std::hex << std::setw(4) << std::setfill('0') << _instance << "."
@@ -447,8 +481,14 @@ void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
}
}
}
- if( last_subscriber_removed )
+ if (subscriber == VSOMEIP_ROUTING_CLIENT && last_subscriber_removed) {
+ // for normal subscribers only unsubscribe via SD if last
+ // subscriber was removed
+ discovery_->unsubscribe(_service, _instance, _eventgroup, subscriber);
+ } else if (subscriber != VSOMEIP_ROUTING_CLIENT) {
+ // for selective subscribers always unsubscribe at the SD
discovery_->unsubscribe(_service, _instance, _eventgroup, subscriber);
+ }
} else {
stub_->send_unsubscribe(find_local(_service, _instance),
_client, _service, _instance, _eventgroup, false);
@@ -493,7 +533,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
} else if (is_notification && _client) { // Selective notifications!
if (_client == get_client()) {
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -509,7 +549,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
if (its_target) {
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -545,7 +585,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
its_target = find_or_create_remote_client(its_service, _instance, _reliable, client);
if (its_target) {
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -600,7 +640,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
}
#ifdef USE_DLT
if (has_sent) {
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -618,7 +658,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data,
(sd_info_ ? sd_info_->get_endpoint(false) : nullptr) : its_info->get_endpoint(_reliable);
if (its_target) {
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -671,7 +711,7 @@ bool routing_manager_impl::send_to(
if (its_endpoint) {
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -691,7 +731,7 @@ bool routing_manager_impl::send_to(const std::shared_ptr<endpoint_definition> &_
if (its_endpoint) {
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
@@ -782,15 +822,23 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance,
}
}
-void routing_manager_impl::on_error(const byte_t *_data, length_t _length, endpoint *_receiver) {
+void routing_manager_impl::on_availability(service_t _service, instance_t _instance,
+ bool _is_available, major_version_t _major, minor_version_t _minor) {
+ host_->on_availability(_service, _instance, _is_available, _major, _minor);
+}
+
+void routing_manager_impl::on_error(
+ const byte_t *_data, length_t _length, endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
instance_t its_instance = 0;
if (_length >= VSOMEIP_SERVICE_POS_MAX) {
service_t its_service = VSOMEIP_BYTES_TO_WORD(
_data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
its_instance = find_instance(its_service, _receiver);
}
- send_error(return_code_e::E_MALFORMED_MESSAGE, _data, _length,
- its_instance, _receiver->is_reliable(), _receiver);
+ send_error(return_code_e::E_MALFORMED_MESSAGE, _data, _length, its_instance,
+ _receiver->is_reliable(), _receiver, _remote_address, _remote_port);
}
void routing_manager_impl::release_port(uint16_t _port, bool _reliable) {
@@ -800,13 +848,15 @@ void routing_manager_impl::release_port(uint16_t _port, bool _reliable) {
void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver, const boost::asio::ip::address &_destination,
- client_t _bound_client) {
+ client_t _bound_client,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
#if 0
std::stringstream msg;
msg << "rmi::on_message: ";
for (uint32_t i = 0; i < _size; ++i)
msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
(void)_bound_client;
service_t its_service;
@@ -818,16 +868,15 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
_data[VSOMEIP_METHOD_POS_MAX]);
if (discovery_ && its_method == sd::method) {
- if (configuration_->get_sd_port() == _receiver->get_remote_port()) {
- boost::asio::ip::address its_address;
- if (_receiver->get_remote_address(its_address)) {
- discovery_->on_message(_data, _size, its_address, _destination);
+ if (configuration_->get_sd_port() == _remote_port) {
+ if (!_remote_address.is_unspecified()) {
+ discovery_->on_message(_data, _size, _remote_address, _destination);
} else {
VSOMEIP_ERROR << "Ignored SD message from unknown address.";
}
} else {
VSOMEIP_ERROR << "Ignored SD message from unknown port ("
- << _receiver->get_remote_port() << ")";
+ << _remote_port << ")";
}
}
} else {
@@ -843,7 +892,8 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
if(!(_size >= VSOMEIP_MESSAGE_TYPE_POS && utility::is_request_no_return(_data[VSOMEIP_MESSAGE_TYPE_POS]))) {
if (return_code != return_code_e::E_OK && return_code != return_code_e::E_NOT_OK) {
send_error(return_code, _data, _size, its_instance,
- _receiver->is_reliable(), _receiver);
+ _receiver->is_reliable(), _receiver,
+ _remote_address, _remote_port);
return;
}
} else if(return_code != return_code_e::E_OK && return_code != return_code_e::E_NOT_OK) {
@@ -893,13 +943,20 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
}
}
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
- if (its_header.prepare(_receiver, false))
- tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
- _data, its_data_size);
+ const boost::asio::ip::address_v4 its_remote_address =
+ _remote_address.is_v4() ? _remote_address.to_v4() :
+ boost::asio::ip::address_v4::from_string("6.6.6.6");
+ tc::protocol_e its_protocol =
+ _receiver->is_local() ? tc::protocol_e::local :
+ _receiver->is_reliable() ? tc::protocol_e::tcp :
+ tc::protocol_e::udp;
+ its_header.prepare(its_remote_address, _remote_port, its_protocol, false);
+ tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, _data,
+ its_data_size);
#endif
}
@@ -914,7 +971,7 @@ void routing_manager_impl::on_message(
<< _service << ", " << _instance << "): ";
for (uint32_t i = 0; i < _size; ++i)
msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
client_t its_client;
@@ -1031,8 +1088,7 @@ void routing_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) {
}
}
for (const auto &s : services_to_report_) {
- host_->on_availability(s.service_id_, s.instance_id_, true, s.major_,
- s.minor_);
+ on_availability(s.service_id_, s.instance_id_, true, s.major_, s.minor_);
if (s.reliable_) {
stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, s.service_id_,
s.instance_id_, s.major_, s.minor_);
@@ -1060,7 +1116,7 @@ void routing_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
if(!its_info){
return;
}
- host_->on_availability(its_service.first, its_instance.first,
+ on_availability(its_service.first, its_instance.first,
false, its_info->get_major(), its_info->get_minor());
}
}
@@ -1072,7 +1128,7 @@ void routing_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
if(!its_info){
return;
}
- host_->on_availability(its_service.first, its_instance.first,
+ on_availability(its_service.first, its_instance.first,
false, its_info->get_major(), its_info->get_minor());
}
}
@@ -1119,17 +1175,22 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se
}
}
}
+ std::map<event_t, std::shared_ptr<event> > events;
{
- std::lock_guard<std::mutex> its_lock(events_mutex_);
+ std::unique_lock<std::mutex> its_lock(events_mutex_);
auto its_events_service = events_.find(_service);
if (its_events_service != events_.end()) {
auto its_events_instance = its_events_service->second.find(_instance);
if (its_events_instance != its_events_service->second.end()) {
- for (auto &e : its_events_instance->second)
- e.second->unset_payload();
+ for (auto &e : its_events_instance->second) {
+ events[e.first] = e.second;
+ }
}
}
}
+ for (auto &e : events) {
+ e.second->unset_payload();
+ }
{
std::lock_guard<std::mutex> its_lock(eventgroup_clients_mutex_);
auto its_service = eventgroup_clients_.find(_service);
@@ -1236,7 +1297,7 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
if (its_message) {
its_message->set_instance(_instance);
its_message->set_reliable(_reliable);
- host_->on_message(its_message);
+ host_->on_message(std::move(its_message));
is_delivered = true;
} else {
VSOMEIP_ERROR << "Routing manager: deliver_message: "
@@ -1305,18 +1366,25 @@ std::shared_ptr<endpoint> routing_manager_impl::create_service_discovery_endpoin
std::shared_ptr<endpoint> its_service_endpoint = find_server_endpoint(_port,
_reliable);
if (!its_service_endpoint) {
- its_service_endpoint = create_server_endpoint(_port, _reliable, true);
-
- if (its_service_endpoint) {
- sd_info_ = std::make_shared<serviceinfo>(ANY_MAJOR, ANY_MINOR, DEFAULT_TTL,
- false); // false, because we do _not_ want to announce it...
- sd_info_->set_endpoint(its_service_endpoint, _reliable);
- its_service_endpoint->add_default_target(VSOMEIP_SD_SERVICE,
- _address, _port);
- its_service_endpoint->join(_address);
- } else {
- VSOMEIP_ERROR << "Service Discovery endpoint could not be created. "
- "Please check your network configuration.";
+ try {
+ its_service_endpoint = create_server_endpoint(_port, _reliable,
+ true);
+
+ if (its_service_endpoint) {
+ sd_info_ = std::make_shared<serviceinfo>(ANY_MAJOR, ANY_MINOR,
+ DEFAULT_TTL, false); // false, because we do _not_ want to announce it...
+ sd_info_->set_endpoint(its_service_endpoint, _reliable);
+ its_service_endpoint->add_default_target(VSOMEIP_SD_SERVICE,
+ _address, _port);
+ its_service_endpoint->join(_address);
+ } else {
+ VSOMEIP_ERROR<< "Service Discovery endpoint could not be created. "
+ "Please check your network configuration.";
+ }
+ } catch (const std::exception &e) {
+ host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
+ VSOMEIP_ERROR << "Service Discovery endpoint could not be created: "
+ << e.what();
}
}
return its_service_endpoint;
@@ -1398,7 +1466,7 @@ void routing_manager_impl::init_service_info(
if (ILLEGAL_PORT == its_reliable_port
&& ILLEGAL_PORT == its_unreliable_port) {
- VSOMEIP_DEBUG << "Port configuration missing for ["
+ VSOMEIP_INFO << "Port configuration missing for ["
<< std::hex << _service << "." << _instance
<< "]. Service is internal.";
}
@@ -1427,7 +1495,8 @@ std::shared_ptr<endpoint> routing_manager_impl::create_client_endpoint(
boost::asio::ip::tcp::endpoint(_address, _remote_port),
io_,
configuration_->get_message_size_reliable(
- _address.to_string(), _remote_port));
+ _address.to_string(), _remote_port),
+ configuration_->get_buffer_shrink_threshold());
if (configuration_->has_enabled_magic_cookies(_address.to_string(),
_remote_port)) {
@@ -1465,7 +1534,8 @@ std::shared_ptr<endpoint> routing_manager_impl::create_server_endpoint(
shared_from_this(),
boost::asio::ip::tcp::endpoint(its_unicast, _port), io_,
configuration_->get_message_size_reliable(
- its_unicast.to_string(), _port));
+ its_unicast.to_string(), _port),
+ configuration_->get_buffer_shrink_threshold());
if (configuration_->has_enabled_magic_cookies(
its_unicast.to_string(), _port) ||
configuration_->has_enabled_magic_cookies(
@@ -1495,7 +1565,7 @@ std::shared_ptr<endpoint> routing_manager_impl::create_server_endpoint(
server_endpoints_[_port][_reliable] = its_endpoint;
its_endpoint->start();
}
- } catch (std::exception &e) {
+ } catch (const std::exception &e) {
host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
VSOMEIP_ERROR << e.what();
}
@@ -1887,8 +1957,8 @@ std::chrono::milliseconds routing_manager_impl::add_routing_info(
&& (major_minor_pair.second <= _minor
|| _minor == DEFAULT_MINOR
|| major_minor_pair.second == ANY_MINOR)) {
- host_->on_availability(_service, _instance,
- true, its_info->get_major(), its_info->get_minor());
+ on_availability(_service, _instance,
+ true, its_info->get_major(), its_info->get_minor());
if (!stub_->contained_in_routing_info(
VSOMEIP_ROUTING_CLIENT, _service, _instance,
its_info->get_major(),
@@ -1916,7 +1986,7 @@ std::chrono::milliseconds routing_manager_impl::add_routing_info(
= endpoint_definition::get(_unreliable_address, _unreliable_port, false);
remote_service_info_[_service][_instance][false] = endpoint_def;
if (!is_reliable_known) {
- host_->on_availability(_service, _instance, true, _major, _minor);
+ on_availability(_service, _instance, true, _major, _minor);
stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor);
}
}
@@ -1931,7 +2001,7 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst
if(!its_info)
return;
- host_->on_availability(_service, _instance, false, its_info->get_major(), its_info->get_minor());
+ on_availability(_service, _instance, false, its_info->get_major(), its_info->get_minor());
stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, its_info->get_major(), its_info->get_minor());
// Implicit unsubscribe
{
@@ -2022,7 +2092,7 @@ std::chrono::milliseconds routing_manager_impl::update_routing_info(std::chrono:
for (auto &s : its_expired_offers) {
for (auto &i : s.second) {
- VSOMEIP_DEBUG << "update_routing_info: elapsed=" << _elapsed.count()
+ VSOMEIP_INFO << "update_routing_info: elapsed=" << _elapsed.count()
<< " : delete service/instance " << std::hex << s.first << "/" << i.first;
del_routing_info(s.first, i.first, i.second.first, i.second.second);
}
@@ -2043,15 +2113,19 @@ void routing_manager_impl::expire_services(const boost::asio::ip::address &_addr
}
bool is_gone(false);
boost::asio::ip::address its_address;
- std::shared_ptr<endpoint> its_endpoint = i.second->get_endpoint(true);
- if (its_endpoint) {
- if (its_endpoint->get_remote_address(its_address)) {
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(
+ i.second->get_endpoint(true));
+ if (its_client_endpoint) {
+ if (its_client_endpoint->get_remote_address(its_address)) {
is_gone = (its_address == _address);
}
} else {
- its_endpoint = i.second->get_endpoint(false);
- if (its_endpoint) {
- if (its_endpoint->get_remote_address(its_address)) {
+ its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(
+ i.second->get_endpoint(false));
+ if (its_client_endpoint) {
+ if (its_client_endpoint->get_remote_address(its_address)) {
is_gone = (its_address == _address);
}
}
@@ -2070,7 +2144,7 @@ void routing_manager_impl::expire_services(const boost::asio::ip::address &_addr
for (auto &s : its_expired_offers) {
for (auto &i : s.second) {
- VSOMEIP_DEBUG << "expire_services for address: " << _address.to_string()
+ VSOMEIP_INFO << "expire_services for address: " << _address.to_string()
<< " : delete service/instance " << std::hex << s.first << "/" << i.first;
del_routing_info(s.first, i.first, i.second.first, i.second.second);
}
@@ -2175,13 +2249,13 @@ bool routing_manager_impl::on_subscribe_accepted(service_t _service, instance_t
}
if (client != VSOMEIP_ROUTING_CLIENT) {
- VSOMEIP_DEBUG << "Subscription accepted: eventgroup=" << _eventgroup
+ VSOMEIP_INFO << "Subscription accepted: eventgroup=" << _eventgroup
<< " : target: " << _target->get_address().to_string()
<< ":" << std::dec <<_target->get_port()
<< (_target->is_reliable() ? " reliable" : " unreliable")
<< " from client: 0x" << std::hex << client << ".";
} else {
- VSOMEIP_DEBUG << "Subscription accepted: eventgroup: " << _eventgroup
+ VSOMEIP_INFO << "Subscription accepted: eventgroup: " << _eventgroup
<< " : target: " << _target->get_address().to_string()
<< ":" << std::dec <<_target->get_port()
<< (_target->is_reliable() ? " reliable" : " unreliable")
@@ -2267,12 +2341,12 @@ void routing_manager_impl::on_unsubscribe(service_t _service,
client_t its_client = find_client(_service, _instance, its_eventgroup, _target);
if (its_client != VSOMEIP_ROUTING_CLIENT) {
- VSOMEIP_DEBUG << "on_unsubscribe: target: " << _target->get_address().to_string()
+ VSOMEIP_INFO << "on_unsubscribe: target: " << _target->get_address().to_string()
<< ":" << std::dec <<_target->get_port()
<< (_target->is_reliable() ? " reliable" : " unreliable")
<< " from client: 0x" << std::hex << its_client;
} else {
- VSOMEIP_DEBUG << "on_unsubscribe: target: " << _target->get_address().to_string()
+ VSOMEIP_INFO << "on_unsubscribe: target: " << _target->get_address().to_string()
<< ":" << std::dec <<_target->get_port()
<< (_target->is_reliable() ? " reliable" : " unreliable");
}
@@ -2609,7 +2683,9 @@ return_code_e routing_manager_impl::check_error(const byte_t *_data, length_t _s
void routing_manager_impl::send_error(return_code_e _return_code,
const byte_t *_data, length_t _size,
instance_t _instance, bool _reliable,
- endpoint *_receiver) {
+ endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
client_t its_client = 0;
service_t its_service = 0;
@@ -2646,53 +2722,21 @@ void routing_manager_impl::send_error(return_code_e _return_code,
error_message->set_return_code(_return_code);
error_message->set_service(its_service);
error_message->set_session(its_session);
-
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(error_message.get())) {
- if (_receiver) {
- boost::asio::ip::address adr;
- uint16_t port;
- if (_receiver->is_reliable()) {
- auto endpoint = dynamic_cast<tcp_server_endpoint_impl*>(_receiver);
- if(!endpoint) {
- return;
- }
- if (!endpoint->get_remote_address(adr)) {
- VSOMEIP_ERROR << "routing_manager_impl::send_error: "
- "couldn't determine remote address (reliable)";
- return;
- }
- port = endpoint->get_remote_port();
- if (!port) {
- VSOMEIP_ERROR << "routing_manager_impl::send_error: "
- "couldn't determine remote port (reliable)";
- return;
- }
- } else {
- auto endpoint = dynamic_cast<udp_server_endpoint_impl*>(_receiver);
- if (!endpoint) {
- return;
- }
- if (!endpoint->get_remote_address(adr)) {
- VSOMEIP_ERROR << "routing_manager_impl::send_error: "
- "couldn't determine remote address (unreliable)";
- return;
- }
- port = endpoint->get_remote_port();
- if (!port) {
- VSOMEIP_ERROR << "routing_manager_impl::send_error: "
- "couldn't determine remote port (unreliable)";
- return;
- }
- }
- auto its_endpoint_def =
- std::make_shared<endpoint_definition>(adr, port, _receiver->is_reliable());
- its_endpoint_def->set_remote_port(_receiver->get_local_port());
- send_to(its_endpoint_def, serializer_->get_data(), serializer_->get_size(), true);
+ {
+ std::lock_guard<std::mutex> its_lock(serialize_mutex_);
+ if (serializer_->serialize(error_message.get())) {
+ if (_receiver) {
+ auto its_endpoint_def = std::make_shared<endpoint_definition>(
+ _remote_address, _remote_port,
+ _receiver->is_reliable());
+ its_endpoint_def->set_remote_port(_receiver->get_local_port());
+ send_to(its_endpoint_def, serializer_->get_data(),
+ serializer_->get_size(), true);
+ }
+ serializer_->reset();
+ } else {
+ VSOMEIP_ERROR<< "Failed to serialize error message.";
}
- serializer_->reset();
- } else {
- VSOMEIP_ERROR << "Failed to serialize error message.";
}
}
@@ -2716,55 +2760,72 @@ void routing_manager_impl::on_identify_response(client_t _client, service_t _ser
}
void routing_manager_impl::identify_for_subscribe(client_t _client,
- service_t _service, instance_t _instance, major_version_t _major) {
- if (!has_identified(_client, _service, _instance, false) &&
- !is_identifying(_client, _service, _instance, false)) {
- auto unreliable_endpoint = find_or_create_remote_client(_service, _instance, false, _client);
- if (unreliable_endpoint) {
- {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- identifying_clients_[_service][_instance][false].insert(_client);
- }
- auto message = runtime::get()->create_message(false);
- message->set_service(_service);
- message->set_instance(_instance);
- message->set_client(_client);
- message->set_method(ANY_METHOD - 1);
- message->set_interface_version(_major);
- message->set_message_type(message_type_e::MT_REQUEST);
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(message.get())) {
- unreliable_endpoint->send(serializer_->get_data(),
- serializer_->get_size());
- serializer_->reset();
- }
- }
- }
- if (!has_identified(_client, _service, _instance, true) &&
- !is_identifying(_client, _service, _instance, true)) {
- auto reliable_endpoint = find_or_create_remote_client(_service, _instance, true, _client);
- if (reliable_endpoint) {
- {
- std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
- identifying_clients_[_service][_instance][true].insert(_client);
+ service_t _service, instance_t _instance, major_version_t _major,
+ subscription_type_e _subscription_type) {
+
+ if (_subscription_type == subscription_type_e::SU_RELIABLE_AND_UNRELIABLE
+ || _subscription_type == subscription_type_e::SU_PREFER_UNRELIABLE
+ || _subscription_type == subscription_type_e::SU_UNRELIABLE) {
+ if (!has_identified(_client, _service, _instance, false)
+ && !is_identifying(_client, _service, _instance, false)) {
+ if (!send_identify_message(_client, _service, _instance, _major,
+ false) && _subscription_type
+ == subscription_type_e::SU_PREFER_UNRELIABLE) {
+ send_identify_message(_client, _service, _instance, _major,
+ true);
}
- auto message = runtime::get()->create_message(true);
- message->set_service(_service);
- message->set_instance(_instance);
- message->set_client(_client);
- message->set_method(ANY_METHOD - 1);
- message->set_interface_version(_major);
- message->set_message_type(message_type_e::MT_REQUEST);
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(message.get())) {
- reliable_endpoint->send(serializer_->get_data(),
- serializer_->get_size());
- serializer_->reset();
+ }
+ }
+
+ if (_subscription_type == subscription_type_e::SU_RELIABLE_AND_UNRELIABLE
+ || _subscription_type == subscription_type_e::SU_PREFER_RELIABLE
+ || _subscription_type == subscription_type_e::SU_RELIABLE) {
+ if (!has_identified(_client, _service, _instance, true)
+ && !is_identifying(_client, _service, _instance, true)) {
+ if (!send_identify_message(_client, _service, _instance, _major,
+ true) && _subscription_type
+ == subscription_type_e::SU_PREFER_RELIABLE) {
+ send_identify_message(_client, _service, _instance, _major,
+ false);
}
}
}
}
+bool routing_manager_impl::send_identify_message(client_t _client,
+ service_t _service,
+ instance_t _instance,
+ major_version_t _major,
+ bool _reliable) {
+ auto its_endpoint = find_or_create_remote_client(_service, _instance,
+ _reliable, _client);
+ if (!its_endpoint) {
+ return false;
+ }
+ {
+ std::lock_guard<std::mutex> its_lock(identified_clients_mutex_);
+ identifying_clients_[_service][_instance][_reliable].insert(_client);
+ }
+ auto message = runtime::get()->create_message(_reliable);
+ message->set_service(_service);
+ message->set_instance(_instance);
+ message->set_client(_client);
+ message->set_method(ANY_METHOD - 1);
+ message->set_interface_version(_major);
+ message->set_message_type(message_type_e::MT_REQUEST);
+ {
+ std::lock_guard<std::mutex> its_lock(serialize_mutex_);
+ if (serializer_->serialize(message.get())) {
+ its_endpoint->send(serializer_->get_data(), serializer_->get_size());
+ serializer_->reset();
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+
bool routing_manager_impl::supports_selective(service_t _service, instance_t _instance) {
bool supports_selective(false);
auto its_service = remote_service_info_.find(_service);
@@ -2884,7 +2945,7 @@ routing_manager_impl::expire_subscriptions() {
its_instance.first, its_eventgroup.first, true);
}
- VSOMEIP_DEBUG << "Expired subscription ("
+ VSOMEIP_INFO << "Expired subscription ("
<< std::hex << its_service.first << "."
<< its_instance .first << "."
<< its_eventgroup.first << " from "
@@ -3141,10 +3202,12 @@ void routing_manager_impl::on_pong(client_t _client) {
}
void routing_manager_impl::on_clientendpoint_error(client_t _client) {
- VSOMEIP_WARNING << "Application/Client "
- << std::hex << std::setw(4) << std::setfill('0')
- << _client << " will be deregistered because of an client endpoint error.";
- stub_->deregister_erroneous_client(_client);
+ if (stub_->is_registered(_client)) {
+ VSOMEIP_WARNING << "Application/Client "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << _client << " will be deregistered because of an client endpoint error.";
+ stub_->deregister_erroneous_client(_client);
+ }
}
void routing_manager_impl::confirm_pending_offers(client_t _client) {
@@ -3208,6 +3271,7 @@ void routing_manager_impl::remove_specific_client_endpoint(client_t _client, ser
if(found_instance != found_service->second.end()) {
auto its_client = found_instance->second.find(_client);
if (its_client != found_instance->second.end()) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
if (remote_services_.find(_service) != remote_services_.end()) {
if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) {
auto endpoint = remote_services_[_service][_instance][_client][_reliable];
@@ -3307,6 +3371,26 @@ void routing_manager_impl::remove_identifying_client(service_t _service, instanc
}
}
+void routing_manager_impl::unsubscribe_specific_client_at_sd(
+ service_t _service, instance_t _instance, client_t _client) {
+ bool found(false);
+ {
+ std::lock_guard<std::mutex> its_lock(specific_endpoint_clients_mutex_);
+ auto its_service = specific_endpoint_clients_.find(_service);
+ if (its_service != specific_endpoint_clients_.end()) {
+ auto its_instance = its_service->second.find(_instance);
+ if (its_instance != its_service->second.end()) {
+ if (its_instance->second.find(_client) != its_instance->second.end()) {
+ found = true;
+ }
+ }
+ }
+ }
+ if (found && discovery_) {
+ discovery_->unsubscribe_client(_service, _instance, _client);
+ }
+}
+
void routing_manager_impl::send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
subscription_type_e _subscription_type) {
@@ -3377,5 +3461,34 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) {
}
}
+void routing_manager_impl::on_net_if_state_changed(std::string _if, bool _available) {
+ if (_available != if_state_running_) {
+ if (_available) {
+ VSOMEIP_INFO << "Network interface \"" << _if << "\" is up and running.";
+ start_ip_routing();
+#ifndef WIN32
+ if (netlink_connector_) {
+ netlink_connector_->unregister_net_if_changes_handler();
+ }
+#endif
+ }
+ }
+}
+
+void routing_manager_impl::start_ip_routing() {
+ std::lock_guard<std::mutex> its_lock(pending_sd_offers_mutex_);
+ if_state_running_ = true;
+
+ if (discovery_) {
+ discovery_->start();
+ } else {
+ init_routing_info();
+ }
+
+ for (auto its_service : pending_sd_offers_) {
+ init_service_info(its_service.first, its_service.second, true);
+ }
+ pending_sd_offers_.clear();
+}
} // namespace vsomeip
diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp
index b762a17..f60218d 100644
--- a/implementation/routing/src/routing_manager_proxy.cpp
+++ b/implementation/routing/src/routing_manager_proxy.cpp
@@ -573,11 +573,11 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
its_target = find_local(_client);
if (its_target) {
#ifdef USE_DLT
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
- if (its_header.prepare(its_target, true))
+ if (its_header.prepare(nullptr, true))
tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
_data, its_data_size);
#endif
@@ -610,11 +610,11 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
}
#ifdef USE_DLT
else if (its_target != sender_) {
- uint16_t its_data_size
+ const uint16_t its_data_size
= uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size);
tc::trace_header its_header;
- if (its_header.prepare(its_target, true))
+ if (its_header.prepare(nullptr, true))
tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE,
_data, its_data_size);
}
@@ -680,7 +680,7 @@ void routing_manager_proxy::on_connect(std::shared_ptr<endpoint> _endpoint) {
}
is_connected_ = true;
if (is_connected_ && is_started_) {
- VSOMEIP_DEBUG << std::hex << "Client " << client_
+ VSOMEIP_INFO << std::hex << "Client " << client_
<< " successfully connected to routing ~> registering..";
register_application();
}
@@ -693,14 +693,18 @@ void routing_manager_proxy::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
}
}
-void routing_manager_proxy::on_error(const byte_t *_data, length_t _length,
- endpoint *_receiver) {
+void routing_manager_proxy::on_error(
+ const byte_t *_data, length_t _length, endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
// Implement me when needed
(void)(_data);
(void)(_length);
(void)(_receiver);
+ (void)(_remote_address);
+ (void)(_remote_port);
}
void routing_manager_proxy::release_port(uint16_t _port, bool _reliable) {
@@ -711,15 +715,19 @@ void routing_manager_proxy::release_port(uint16_t _port, bool _reliable) {
void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver, const boost::asio::ip::address &_destination,
- client_t _bound_client) {
+ client_t _bound_client,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
(void)_receiver;
(void)_destination;
+ (void)_remote_address;
+ (void)_remote_port;
#if 0
std::stringstream msg;
msg << "rmp::on_message: ";
for (int i = 0; i < _size; ++i)
msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
byte_t its_command;
client_t its_client;
@@ -758,10 +766,14 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
bool its_reliable;
std::memcpy(&its_reliable, &_data[_size - sizeof(bool)],
sizeof(its_reliable));
+ // reduce by size of instance, flush and reliable flag
+ const std::uint32_t its_message_size = its_length -
+ static_cast<uint32_t>(sizeof(its_instance)
+ + sizeof(bool) + sizeof(bool));
auto a_deserializer = get_deserializer();
a_deserializer->set_data(&_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- its_length);
+ its_message_size);
std::shared_ptr<message> its_message(a_deserializer->deserialize_message());
a_deserializer->reset();
put_deserializer(a_deserializer);
@@ -800,7 +812,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
return;
}
}
- host_->on_message(its_message);
+ host_->on_message(std::move(its_message));
} else {
VSOMEIP_ERROR << "Routing proxy: on_message: "
<< "SomeIP-Header deserialization failed!";
@@ -866,6 +878,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
routing_manager_base::subscribe(its_client, its_service, its_instance,
its_eventgroup, its_major, subscription_type_e::SU_RELIABLE_AND_UNRELIABLE);
send_subscribe_ack(its_client, its_service, its_instance, its_eventgroup);
+ send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client);
}
} else {
// Local & not yet known subscriber ~> set pending until subscriber gets known!
@@ -874,8 +887,8 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
subscription_type_e::SU_RELIABLE_AND_UNRELIABLE};
std::lock_guard<std::mutex> its_lock(pending_ingoing_subscripitons_mutex_);
pending_ingoing_subscripitons_[its_client].insert(subscription);
- }
- VSOMEIP_DEBUG << "SUBSCRIBE("
+ }
+ VSOMEIP_INFO << "SUBSCRIBE("
<< std::hex << std::setw(4) << std::setfill('0') << its_client <<"): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
@@ -903,7 +916,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
its_instance, its_eventgroup);
}
}
- VSOMEIP_DEBUG << "UNSUBSCRIBE("
+ VSOMEIP_INFO << "UNSUBSCRIBE("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
@@ -919,7 +932,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
sizeof(its_eventgroup));
on_subscribe_nack(its_client, its_service, its_instance, its_eventgroup);
- VSOMEIP_DEBUG << "SUBSCRIBE NACK("
+ VSOMEIP_INFO << "SUBSCRIBE NACK("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
@@ -935,7 +948,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
sizeof(its_eventgroup));
on_subscribe_ack(its_client, its_service, its_instance, its_eventgroup);
- VSOMEIP_DEBUG << "SUBSCRIBE ACK("
+ VSOMEIP_INFO << "SUBSCRIBE ACK("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
@@ -955,7 +968,7 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
msg << "rmp::on_routing_info(" << std::hex << client_ << "): ";
for (uint32_t i = 0; i < _size; ++i)
msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
inner_state_type_e its_state(inner_state_type_e::ST_DEREGISTERED);
bool restart_sender(_size == 1); // 1 indicates a routing master stop
@@ -1158,6 +1171,8 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
subscription_type_e::SU_RELIABLE_AND_UNRELIABLE);
send_subscribe_ack(si.client_id_, si.service_id_,
si.instance_id_, si.eventgroup_id_);
+ send_pending_notify_ones(si.service_id_,
+ si.instance_id_, si.eventgroup_id_, si.client_id_);
}
pending_ingoing_subscripitons_.erase(si.client_id_);
}
@@ -1422,6 +1437,7 @@ void routing_manager_proxy::on_stop_offer_service(service_t _service,
minor_version_t _minor) {
(void) _major;
(void) _minor;
+ std::map<event_t, std::shared_ptr<event> > events;
{
std::lock_guard<std::mutex> its_lock(events_mutex_);
auto its_events_service = events_.find(_service);
@@ -1429,10 +1445,13 @@ void routing_manager_proxy::on_stop_offer_service(service_t _service,
auto its_events_instance = its_events_service->second.find(_instance);
if (its_events_instance != its_events_service->second.end()) {
for (auto &e : its_events_instance->second)
- e.second->unset_payload();
+ events[e.first] = e.second;
}
}
}
+ for (auto &e : events) {
+ e.second->unset_payload();
+ }
}
void routing_manager_proxy::send_pending_commands() {
@@ -1486,11 +1505,12 @@ void routing_manager_proxy::init_receiver() {
#else
boost::asio::local::stream_protocol::endpoint(its_client.str()),
#endif
- io_, configuration_->get_max_message_size_local());
+ io_, configuration_->get_max_message_size_local(),
+ configuration_->get_buffer_shrink_threshold());
#ifdef WIN32
- VSOMEIP_DEBUG << "Listening at " << port;
+ VSOMEIP_INFO << "Listening at " << port;
#else
- VSOMEIP_DEBUG<< "Listening at " << its_client.str();
+ VSOMEIP_INFO << "Listening at " << its_client.str();
#endif
} catch (const std::exception &e) {
host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp
index 3874a07..a55d61b 100644
--- a/implementation/routing/src/routing_manager_stub.cpp
+++ b/implementation/routing/src/routing_manager_stub.cpp
@@ -50,7 +50,9 @@ routing_manager_stub::routing_manager_stub(
local_receiver_(nullptr),
configuration_(_configuration),
routingCommandSize_(VSOMEIP_ROUTING_INFO_SIZE_INIT),
+ is_socket_activated_(false),
client_registration_running_(false),
+ max_local_message_size_(configuration_->get_max_message_size_local()),
configured_watchdog_timeout_(configuration_->get_watchdog_timeout()),
pinged_clients_timer_(io_) {
}
@@ -80,7 +82,7 @@ void routing_manager_stub::start() {
<< configuration_->get_watchdog_timeout()
<< " : Allowed missing pongs = "
<< configuration_->get_allowed_missing_pongs()
- << ".";
+ << ".";
start_watchdog();
} else {
VSOMEIP_INFO << "Watchdog is disabled!";
@@ -140,27 +142,35 @@ void routing_manager_stub::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
(void)_endpoint;
}
-void routing_manager_stub::on_error(const byte_t *_data, length_t _length,
- endpoint *_receiver) {
+void routing_manager_stub::on_error(
+ const byte_t *_data, length_t _length, endpoint *_receiver,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
// Implement me when needed
(void)(_data);
(void)(_length);
(void)(_receiver);
+ (void)(_remote_address);
+ (void)(_remote_port);
}
void routing_manager_stub::release_port(uint16_t _port, bool _reliable) {
- (void)_port;
- (void)_reliable;
- // intentionally empty
+ (void)_port;
+ (void)_reliable;
+ // intentionally empty
}
void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver, const boost::asio::ip::address &_destination,
- client_t _bound_client) {
+ client_t _bound_client,
+ const boost::asio::ip::address &_remote_address,
+ std::uint16_t _remote_port) {
(void)_receiver;
(void)_destination;
+ (void)_remote_address;
+ (void) _remote_port;
#if 0
std::stringstream msg;
msg << "rms::on_message: ";
@@ -312,7 +322,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
sizeof(its_eventgroup));
host_->on_subscribe_ack(its_client, its_service, its_instance, its_eventgroup);
- VSOMEIP_DEBUG << "SUBSCRIBE ACK("
+ VSOMEIP_INFO << "SUBSCRIBE ACK("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
@@ -327,14 +337,14 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
sizeof(its_eventgroup));
host_->on_subscribe_nack(its_client, its_service, its_instance, its_eventgroup);
- VSOMEIP_DEBUG << "SUBSCRIBE NACK("
+ VSOMEIP_INFO << "SUBSCRIBE NACK("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "]";
break;
- case VSOMEIP_SEND:
+ case VSOMEIP_SEND: {
its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS];
its_service = VSOMEIP_BYTES_TO_WORD(
its_data[VSOMEIP_SERVICE_POS_MIN],
@@ -366,20 +376,28 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
return;
}
}
- host_->on_message(its_service, its_instance, its_data, its_size, its_reliable);
+ // reduce by size of instance, flush and reliable flag
+ const std::uint32_t its_message_size = its_size -
+ static_cast<std::uint32_t>(sizeof(its_instance)
+ + sizeof(bool) + sizeof(bool));
+ host_->on_message(its_service, its_instance, its_data, its_message_size, its_reliable);
break;
-
- case VSOMEIP_NOTIFY:
+ }
+ case VSOMEIP_NOTIFY: {
its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS];
its_service = VSOMEIP_BYTES_TO_WORD(
its_data[VSOMEIP_SERVICE_POS_MIN],
its_data[VSOMEIP_SERVICE_POS_MAX]);
std::memcpy(&its_instance, &_data[_size - sizeof(instance_t)
- sizeof(bool) - sizeof(bool)], sizeof(its_instance));
- host_->on_notification(VSOMEIP_ROUTING_CLIENT, its_service, its_instance,
- its_data, its_size);
+ // reduce by size of instance, flush and reliable flag
+ const std::uint32_t its_message_size = its_size -
+ static_cast<uint32_t>(sizeof(its_instance)
+ + sizeof(bool) + sizeof(bool));
+ host_->on_notification(VSOMEIP_ROUTING_CLIENT, its_service, its_instance, its_data, its_message_size);
break;
- case VSOMEIP_NOTIFY_ONE:
+ }
+ case VSOMEIP_NOTIFY_ONE: {
its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS];
its_service = VSOMEIP_BYTES_TO_WORD(
its_data[VSOMEIP_SERVICE_POS_MIN],
@@ -388,10 +406,14 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(bool) - sizeof(bool) - sizeof(client_t)],
sizeof(its_instance));
std::memcpy(&its_target_client, &_data[_size - sizeof(client_t)], sizeof(client_t));
+ // reduce by size of instance, flush, reliable flag and target client
+ const std::uint32_t its_message_size = its_size -
+ static_cast<uint32_t>(sizeof(its_instance)
+ + sizeof(bool) + sizeof(bool) + sizeof(client_t));
host_->on_notification(its_target_client, its_service, its_instance,
- its_data, its_size, true);
+ its_data, its_message_size, true);
break;
-
+ }
case VSOMEIP_REQUEST_SERVICE:
std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
sizeof(its_service));
@@ -454,7 +476,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
host_->register_shadow_event(its_client, its_service,
its_instance, its_event, its_eventgroups,
is_field, is_provided);
- VSOMEIP_DEBUG << "REGISTER EVENT("
+ VSOMEIP_INFO << "REGISTER EVENT("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
@@ -480,7 +502,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
}
host_->unregister_shadow_event(its_client, its_service, its_instance,
its_event, is_provided);
- VSOMEIP_DEBUG << "UNREGISTER EVENT("
+ VSOMEIP_INFO << "UNREGISTER EVENT("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << "): ["
<< std::hex << std::setw(4) << std::setfill('0') << its_service << "."
<< std::hex << std::setw(4) << std::setfill('0') << its_instance << "."
@@ -506,7 +528,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
break;
case VSOMEIP_REGISTERED_ACK:
- VSOMEIP_DEBUG << "REGISTERED_ACK("
+ VSOMEIP_INFO << "REGISTERED_ACK("
<< std::hex << std::setw(4) << std::setfill('0') << its_client << ")";
std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
broadcast_routing_info(false, its_client);
@@ -536,6 +558,8 @@ void routing_manager_stub::on_deregister_application(client_t _client) {
for (auto &its_instance : its_service.second) {
auto its_version = its_instance.second;
routing_info_mutex_.unlock();
+ host_->on_availability(its_service.first, its_instance.first,
+ false, its_version.first, its_version.second);
host_->on_stop_offer_service(_client, its_service.first,
its_instance.first, its_version.first,
its_version.second);
@@ -619,29 +643,30 @@ void routing_manager_stub::init_routing_endpoint() {
std::make_shared < local_server_endpoint_impl
> (shared_from_this(),
boost::asio::local::stream_protocol::endpoint(endpoint_path_),
- io_, configuration_->get_max_message_size_local(), native_socket_fd);
+ io_, configuration_->get_max_message_size_local(), native_socket_fd,
+ configuration_->get_buffer_shrink_threshold());
} catch (const std::exception &e) {
VSOMEIP_ERROR << ERROR_INFO[static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED)]
<< " (" << static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED) << ")";
- VSOMEIP_ERROR << "routing_manager_stub::init_endpoint Client ID: "
+ VSOMEIP_ERROR << "routing_manager_stub::init_routing_endpoint Client ID: "
<< std::hex << VSOMEIP_ROUTING_CLIENT << ": " << e.what();
}
#endif
is_socket_activated_ = true;
} else {
- #if WIN32
- ::_unlink(endpoint_path_.c_str());
- int port = VSOMEIP_INTERNAL_BASE_PORT;
- VSOMEIP_DEBUG << "Routing endpoint at " << port;
- #else
- if (-1 == ::unlink(endpoint_path_.c_str()) && errno != ENOENT) {
- VSOMEIP_ERROR << "routing_manager_stub::init_endpoint unlink failed ("
- << endpoint_path_ << "): "<< std::strerror(errno);
- }
- VSOMEIP_DEBUG << "init_routing_endpoint Routing endpoint at " << endpoint_path_;
-
- const mode_t previous_mask(::umask(static_cast<mode_t>(configuration_->get_umask())));
- #endif
+ #if WIN32
+ ::_unlink(endpoint_path_.c_str());
+ int port = VSOMEIP_INTERNAL_BASE_PORT;
+ VSOMEIP_INFO << "Routing endpoint at " << port;
+ #else
+ if (-1 == ::unlink(endpoint_path_.c_str()) && errno != ENOENT) {
+ VSOMEIP_ERROR << "routing_manager_stub::init_endpoint unlink failed ("
+ << endpoint_path_ << "): "<< std::strerror(errno);
+ }
+ VSOMEIP_INFO << "init_routing_endpoint Routing endpoint at " << endpoint_path_;
+
+ const mode_t previous_mask(::umask(static_cast<mode_t>(configuration_->get_umask())));
+ #endif
try {
endpoint_ =
@@ -652,16 +677,17 @@ void routing_manager_stub::init_routing_endpoint() {
#else
boost::asio::local::stream_protocol::endpoint(endpoint_path_),
#endif
- io_, configuration_->get_max_message_size_local());
+ io_, configuration_->get_max_message_size_local(),
+ configuration_->get_buffer_shrink_threshold());
} catch (const std::exception &e) {
VSOMEIP_ERROR << ERROR_INFO[static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED)]
<< " (" << static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED) << ")";
- VSOMEIP_ERROR << "routing_manager_stub::init_endpoint Client ID: "
+ VSOMEIP_ERROR << "routing_manager_stub::init_routing_endpoint Client ID: "
<< std::hex << VSOMEIP_ROUTING_CLIENT << ": " << e.what();
}
#ifndef WIN32
::umask(previous_mask);
- #endif
+ #endif
is_socket_activated_ = false;
}
}
@@ -813,11 +839,12 @@ void routing_manager_stub::send_routing_info(client_t _client, bool _empty) {
msg << "rms::send_routing_info ";
for (uint32_t i = 0; i < its_size; ++i)
msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
// Send routing info or error!
- if(its_command.size() <= VSOMEIP_MAX_LOCAL_MESSAGE_SIZE) {
+ if(its_command.size() <= max_local_message_size_
+ || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) {
its_endpoint->send(&its_command[0], uint32_t(its_size), true);
} else {
VSOMEIP_ERROR << "Routing info exceeds maximum message size: Can't send!";
@@ -1075,7 +1102,8 @@ void routing_manager_stub::create_local_receiver() {
#else
boost::asio::local::stream_protocol::endpoint(local_receiver_path_),
#endif
- io_, configuration_->get_max_message_size_local());
+ io_, configuration_->get_max_message_size_local(),
+ configuration_->get_buffer_shrink_threshold());
} catch (const std::exception &e) {
VSOMEIP_ERROR << ERROR_INFO[static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED)]
<< " (" << static_cast<int>(error_code_e::SERVER_ENDPOINT_CREATION_FAILED) << ")";
@@ -1235,6 +1263,11 @@ void routing_manager_stub::remove_from_pinged_clients(client_t _client) {
std::placeholders::_1));
}
+bool routing_manager_stub::is_registered(client_t _client) const {
+ std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
+ return (routing_info_.find(_client) != routing_info_.end());
+}
+
void routing_manager_stub::deregister_erroneous_client(client_t _client) {
std::lock_guard<std::mutex> its_lock(client_registration_mutex_);
VSOMEIP_INFO << "Application/Client "
diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp
index 88d00bc..0f5582f 100644
--- a/implementation/runtime/include/application_impl.hpp
+++ b/implementation/runtime/include/application_impl.hpp
@@ -146,7 +146,7 @@ public:
VSOMEIP_EXPORT void on_state(state_type_e _state);
VSOMEIP_EXPORT void on_availability(service_t _service, instance_t _instance,
bool _is_available, major_version_t _major, minor_version_t _minor);
- VSOMEIP_EXPORT void on_message(std::shared_ptr<message> _message);
+ VSOMEIP_EXPORT void on_message(const std::shared_ptr<message> &&_message);
VSOMEIP_EXPORT void on_error(error_code_e _error);
VSOMEIP_EXPORT bool on_subscription(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, client_t _client, bool _subscribed);
@@ -290,7 +290,6 @@ private:
std::mutex dispatcher_mutex_;
// Condition to wakeup the dispatcher thread
mutable std::condition_variable dispatcher_condition_;
- boost::asio::steady_timer dispatcher_timer_;
std::size_t max_dispatchers_;
std::size_t max_dispatch_time_;
diff --git a/implementation/runtime/include/runtime_impl.hpp b/implementation/runtime/include/runtime_impl.hpp
index e761d8a..20c7c49 100644
--- a/implementation/runtime/include/runtime_impl.hpp
+++ b/implementation/runtime/include/runtime_impl.hpp
@@ -8,6 +8,7 @@
#include <vsomeip/runtime.hpp>
#include <map>
+#include <mutex>
namespace vsomeip {
@@ -39,11 +40,16 @@ public:
std::shared_ptr<application> get_application(
const std::string &_name) const;
+ void remove_application( const std::string &_name);
+
private:
static std::shared_ptr<runtime> the_runtime_;
static std::map<std::string, std::string> properties_;
std::map<std::string, std::weak_ptr<application>> applications_;
+
+ mutable std::mutex applications_mutex_;
+ static uint32_t postfix_id;
};
} // namespace vsomeip
diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp
index ccf4e05..f2fd422 100644
--- a/implementation/runtime/src/application_impl.cpp
+++ b/implementation/runtime/src/application_impl.cpp
@@ -43,7 +43,6 @@ application_impl::application_impl(const std::string &_name)
catched_signal_(false),
#endif
is_dispatching_(false),
- dispatcher_timer_(io_),
max_dispatchers_(VSOMEIP_MAX_DISPATCHERS),
max_dispatch_time_(VSOMEIP_MAX_DISPATCH_TIME),
logger_(logger::get()),
@@ -54,7 +53,7 @@ application_impl::application_impl(const std::string &_name)
}
application_impl::~application_impl() {
-
+ runtime_->remove_application(name_);
}
void application_impl::set_configuration(
@@ -182,7 +181,7 @@ bool application_impl::init() {
its_trace_connector->set_sd_enabled(enable_sd_tracing);
#endif
- VSOMEIP_DEBUG << "Application(" << (name_ != "" ? name_ : "unnamed")
+ VSOMEIP_INFO << "Application(" << (name_ != "" ? name_ : "unnamed")
<< ", " << std::hex << client_ << ") is initialized ("
<< std::dec << max_dispatchers_ << ", "
<< std::dec << max_dispatch_time_ << ").";
@@ -217,6 +216,7 @@ bool application_impl::init() {
}
void application_impl::start() {
+ const size_t io_thread_count = configuration_->get_io_thread_count(name_);
{
std::lock_guard<std::mutex> its_lock(start_stop_mutex_);
if (io_.stopped()) {
@@ -240,7 +240,8 @@ void application_impl::start() {
}
stopped_ = false;
stopped_called_ = false;
- VSOMEIP_INFO << "Starting vsomeip application \"" << name_ << "\".";
+ VSOMEIP_INFO << "Starting vsomeip application \"" << name_ << "\" using "
+ << std::dec << io_thread_count << " threads";
is_dispatching_ = true;
@@ -258,7 +259,7 @@ void application_impl::start() {
if (routing_)
routing_->start();
- for (int i = 0; i < 3; i++) {
+ for (size_t i = 0; i < io_thread_count - 1; i++) {
std::shared_ptr<std::thread> its_thread
= std::make_shared<std::thread>([this, i] {
io_.run();
@@ -271,6 +272,8 @@ void application_impl::start() {
app_counter__++;
app_counter_mutex__.unlock();
+ io_.run();
+
if (stop_thread_.joinable()) {
stop_thread_.join();
}
@@ -1012,7 +1015,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance,
}
}
-void application_impl::on_message(std::shared_ptr<message> _message) {
+void application_impl::on_message(const std::shared_ptr<message> &&_message) {
service_t its_service = _message->get_service();
instance_t its_instance = _message->get_instance();
method_t its_method = _message->get_method();
@@ -1105,7 +1108,7 @@ void application_impl::on_message(std::shared_ptr<message> _message) {
auto handler = its_handler.handler_;
std::shared_ptr<sync_handler> its_sync_handler =
std::make_shared<sync_handler>([handler, _message]() {
- handler(_message);
+ handler(std::move(_message));
});
handlers_.push_back(its_sync_handler);
}
@@ -1143,6 +1146,13 @@ void application_impl::main_dispatch() {
its_lock.lock();
remove_elapsed_dispatchers();
+
+ if(!is_dispatching_) {
+ its_lock.unlock();
+#ifdef WIN32
+ return;
+#endif
+ }
}
}
}
@@ -1179,10 +1189,11 @@ void application_impl::dispatch() {
void application_impl::invoke_handler(std::shared_ptr<sync_handler> &_handler) {
std::thread::id its_id = std::this_thread::get_id();
- dispatcher_timer_.expires_from_now(std::chrono::milliseconds(max_dispatch_time_));
- dispatcher_timer_.async_wait([this, its_id](const boost::system::error_code &_error) {
+ boost::asio::steady_timer its_dispatcher_timer(io_);
+ its_dispatcher_timer.expires_from_now(std::chrono::milliseconds(max_dispatch_time_));
+ its_dispatcher_timer.async_wait([this, its_id](const boost::system::error_code &_error) {
if (!_error) {
- VSOMEIP_DEBUG << "Blocking call detected. Client=" << std::hex << get_client();
+ VSOMEIP_INFO << "Blocking call detected. Client=" << std::hex << get_client();
std::lock_guard<std::mutex> its_lock(dispatcher_mutex_);
blocked_dispatchers_.insert(its_id);
@@ -1200,7 +1211,7 @@ void application_impl::invoke_handler(std::shared_ptr<sync_handler> &_handler) {
});
_handler->handler_();
- dispatcher_timer_.cancel();
+ its_dispatcher_timer.cancel();
{
std::lock_guard<std::mutex> its_lock(dispatcher_mutex_);
blocked_dispatchers_.erase(its_id);
@@ -1325,7 +1336,7 @@ void application_impl::send_back_cached_event(service_t _service,
its_message->set_instance(_instance);
its_message->set_payload(its_event->get_payload());
its_message->set_initial(true);
- on_message(its_message);
+ on_message(std::move(its_message));
}
}
@@ -1342,7 +1353,7 @@ void application_impl::send_back_cached_eventgroup(service_t _service,
its_message->set_instance(_instance);
its_message->set_payload(its_event->get_payload());
its_message->set_initial(true);
- on_message(its_message);
+ on_message(std::move(its_message));
}
}
}
diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp
index cf8c6e6..194368f 100644
--- a/implementation/runtime/src/runtime_impl.cpp
+++ b/implementation/runtime/src/runtime_impl.cpp
@@ -14,6 +14,7 @@ namespace vsomeip {
std::map<std::string, std::string> runtime_impl::properties_;
std::shared_ptr<runtime> runtime_impl::the_runtime_ = std::make_shared<runtime_impl>();
+uint32_t runtime_impl::postfix_id = 0;
std::string runtime_impl::get_property(const std::string &_name) {
auto found_property = properties_.find(_name);
@@ -35,8 +36,14 @@ runtime_impl::~runtime_impl() {
std::shared_ptr<application> runtime_impl::create_application(
const std::string &_name) {
- std::shared_ptr<application> application = std::make_shared<application_impl>(_name);
- applications_[_name] = application;
+ std::lock_guard<std::mutex> its_lock(applications_mutex_);
+ std::string its_name_ = _name;
+ auto found_application = applications_.find(_name);
+ if( found_application != applications_.end()) {
+ its_name_ += "_" + std::to_string(postfix_id++);
+ }
+ std::shared_ptr<application> application = std::make_shared<application_impl>(its_name_);
+ applications_[its_name_] = application;
return application;
}
@@ -105,10 +112,20 @@ std::shared_ptr<payload> runtime_impl::create_payload(
std::shared_ptr<application> runtime_impl::get_application(
const std::string &_name) const {
+ std::lock_guard<std::mutex> its_lock(applications_mutex_);
auto found_application = applications_.find(_name);
if(found_application != applications_.end())
return found_application->second.lock();
return nullptr;
}
+void runtime_impl::remove_application(
+ const std::string &_name) {
+ std::lock_guard<std::mutex> its_lock(applications_mutex_);
+ auto found_application = applications_.find(_name);
+ if(found_application != applications_.end()) {
+ applications_.erase(_name);
+ }
+}
+
} // namespace vsomeip
diff --git a/implementation/service_discovery/include/deserializer.hpp b/implementation/service_discovery/include/deserializer.hpp
index 085bc7c..ba9a82f 100755
--- a/implementation/service_discovery/include/deserializer.hpp
+++ b/implementation/service_discovery/include/deserializer.hpp
@@ -15,8 +15,9 @@ class message_impl;
class deserializer: public vsomeip::deserializer {
public:
- deserializer();
- deserializer(uint8_t *_data, std::size_t _length);
+ deserializer(std::uint32_t _shrink_buffer_threshold);
+ deserializer(uint8_t *_data, std::size_t _length,
+ std::uint32_t _shrink_buffer_threshold);
deserializer(const deserializer &_other);
virtual ~deserializer();
diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp
index 14c95bc..d3a62fc 100644
--- a/implementation/service_discovery/include/service_discovery.hpp
+++ b/implementation/service_discovery/include/service_discovery.hpp
@@ -43,6 +43,8 @@ public:
virtual void unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, client_t _client) = 0;
virtual void unsubscribe_all(service_t _service, instance_t _instance) = 0;
+ virtual void unsubscribe_client(service_t _service, instance_t _instance,
+ client_t _client) = 0;
virtual bool send(bool _is_announcing, bool _is_find = false) = 0;
diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp
index f2a9e3c..e367c0b 100644
--- a/implementation/service_discovery/include/service_discovery_impl.hpp
+++ b/implementation/service_discovery/include/service_discovery_impl.hpp
@@ -20,6 +20,7 @@
#include "ip_option_impl.hpp"
#include "ipv4_option_impl.hpp"
#include "ipv6_option_impl.hpp"
+#include "deserializer.hpp"
namespace vsomeip {
@@ -71,6 +72,8 @@ public:
void unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, client_t _client);
void unsubscribe_all(service_t _service, instance_t _instance);
+ void unsubscribe_client(service_t _service, instance_t _instance,
+ client_t _client);
bool send(bool _is_announcing, bool _is_find);
@@ -100,7 +103,7 @@ private:
const boost::asio::ip::address &_address, uint16_t _port,
bool _is_reliable);
void insert_find_entries(std::shared_ptr<message_impl> &_message,
- requests_t &_requests, uint32_t _start, uint32_t &_size, bool &_done);
+ uint32_t _start, uint32_t &_size, bool &_done);
void insert_offer_entries(std::shared_ptr<message_impl> &_message,
const services_t &_services, uint32_t &_start,
uint32_t _size, bool &_done, bool _ignore_phase);
@@ -172,7 +175,6 @@ private:
std::chrono::milliseconds stop_ttl_timer();
void check_ttl(const boost::system::error_code &_error);
- boost::asio::ip::address get_current_remote_address() const;
void start_subscription_expiration_timer();
void stop_subscription_expiration_timer();
@@ -317,6 +319,10 @@ private:
boost::asio::steady_timer main_phase_timer_;
bool is_suspended_;
+
+ std::string sd_multicast_;
+
+ boost::asio::ip::address current_remote_address_;
};
} // namespace sd
diff --git a/implementation/service_discovery/src/deserializer.cpp b/implementation/service_discovery/src/deserializer.cpp
index 744c463..351676f 100644
--- a/implementation/service_discovery/src/deserializer.cpp
+++ b/implementation/service_discovery/src/deserializer.cpp
@@ -9,12 +9,13 @@
namespace vsomeip {
namespace sd {
-deserializer::deserializer()
- : vsomeip::deserializer() {
+deserializer::deserializer(std::uint32_t _shrink_buffer_threshold)
+ : vsomeip::deserializer(_shrink_buffer_threshold) {
}
-deserializer::deserializer(uint8_t *_data, std::size_t _length)
- : vsomeip::deserializer(_data, _length) {
+deserializer::deserializer(uint8_t *_data, std::size_t _length,
+ std::uint32_t _shrink_buffer_threshold)
+ : vsomeip::deserializer(_data, _length, _shrink_buffer_threshold) {
}
deserializer::deserializer(const deserializer &_other)
diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp
index 94a03b4..e33027a 100644
--- a/implementation/service_discovery/src/service_discovery_impl.cpp
+++ b/implementation/service_discovery/src/service_discovery_impl.cpp
@@ -25,6 +25,7 @@
#include "../../configuration/include/configuration.hpp"
#include "../../configuration/include/internal.hpp"
#include "../../endpoints/include/endpoint.hpp"
+#include "../../endpoints/include/client_endpoint.hpp"
#include "../../endpoints/include/endpoint_definition.hpp"
#include "../../endpoints/include/tcp_server_endpoint_impl.hpp"
#include "../../endpoints/include/udp_server_endpoint_impl.hpp"
@@ -41,8 +42,12 @@ service_discovery_impl::service_discovery_impl(service_discovery_host *_host)
host_(_host),
port_(VSOMEIP_SD_DEFAULT_PORT),
reliable_(false),
- serializer_(std::make_shared<serializer>()),
- deserializer_(std::make_shared<deserializer>()),
+ serializer_(
+ std::make_shared<serializer>(
+ host_->get_configuration()->get_buffer_shrink_threshold())),
+ deserializer_(
+ std::make_shared<deserializer>(
+ host_->get_configuration()->get_buffer_shrink_threshold())),
ttl_timer_(_host->get_io()),
smallest_ttl_(DEFAULT_TTL),
ttl_(VSOMEIP_SD_DEFAULT_TTL),
@@ -55,7 +60,7 @@ service_discovery_impl::service_discovery_impl(service_discovery_host *_host)
cyclic_offer_delay_(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY),
offer_debounce_timer_(_host->get_io()),
main_phase_timer_(_host->get_io()),
- is_suspended_(false) {
+ is_suspended_(true) {
std::chrono::seconds smallest_ttl(DEFAULT_TTL);
smallest_ttl_ = std::chrono::duration_cast<std::chrono::milliseconds>(smallest_ttl);
@@ -81,6 +86,7 @@ void service_discovery_impl::init() {
host_->get_configuration();
if (its_configuration) {
unicast_ = its_configuration->get_unicast_address();
+ sd_multicast_ = its_configuration->get_sd_multicast();
port_ = its_configuration->get_sd_port();
reliable_ = (its_configuration->get_sd_protocol()
@@ -88,14 +94,6 @@ void service_discovery_impl::init() {
max_message_size_ = (reliable_ ? VSOMEIP_MAX_TCP_SD_PAYLOAD :
VSOMEIP_MAX_UDP_SD_PAYLOAD);
- serializer_->create_data(
- reliable_ ?
- VSOMEIP_MAX_TCP_MESSAGE_SIZE :
- VSOMEIP_MAX_UDP_MESSAGE_SIZE);
-
- endpoint_ = host_->create_service_discovery_endpoint(
- its_configuration->get_sd_multicast(), port_, reliable_);
-
ttl_ = its_configuration->get_sd_ttl();
// generate random initial delay based on initial delay min and max
@@ -135,6 +133,26 @@ void service_discovery_impl::init() {
}
void service_discovery_impl::start() {
+ if (!endpoint_) {
+ endpoint_ = host_->create_service_discovery_endpoint(
+ sd_multicast_, port_, reliable_);
+ if (!endpoint_) {
+ VSOMEIP_ERROR << "Couldn't start service discovery";
+ return;
+ }
+ // Send out pending find services messages if have any
+ bool send_find(false);
+ {
+ std::lock_guard<std::mutex> its_lock(requested_mutex_);
+ if (requested_.size()) {
+ send_find = true;
+ }
+ }
+ if (send_find) {
+ send(false, true);
+ }
+ }
+
is_suspended_ = false;
start_main_phase_timer();
start_offer_debounce_timer(true);
@@ -174,13 +192,14 @@ void service_discovery_impl::request_service(service_t _service,
> (_major, _minor, _ttl);
}
}
- if (is_new_request) {
+ if (is_new_request && !is_suspended_) {
send(false, true);
}
}
void service_discovery_impl::release_service(service_t _service,
instance_t _instance) {
+ std::lock_guard<std::mutex> its_lock(requested_mutex_);
auto find_service = requested_.find(_service);
if (find_service != requested_.end()) {
find_service->second.erase(_instance);
@@ -189,6 +208,7 @@ void service_discovery_impl::release_service(service_t _service,
std::shared_ptr<request>
service_discovery_impl::find_request(service_t _service, instance_t _instance) {
+ std::lock_guard<std::mutex> its_lock(requested_mutex_);
auto find_service = requested_.find(_service);
if (find_service != requested_.end()) {
auto find_instance = find_service->second.find(_instance);
@@ -309,23 +329,44 @@ void service_discovery_impl::get_subscription_endpoints(
_unreliable = host_->find_or_create_remote_client(_service,
_instance, false, _client);
if (_unreliable) {
- *_has_address = _unreliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(_unreliable);
+ if (its_client_endpoint) {
+ *_has_address = its_client_endpoint->get_remote_address(
+ *_address);
+ }
}
if (_reliable) {
- *_has_address = *_has_address
- || _reliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(_reliable);
+ if (its_client_endpoint) {
+ *_has_address = *_has_address
+ || its_client_endpoint->get_remote_address(
+ *_address);
+ }
}
break;
case subscription_type_e::SU_PREFER_UNRELIABLE:
_unreliable = host_->find_or_create_remote_client(_service,
_instance, false, _client);
if (_unreliable) {
- *_has_address = _unreliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(_unreliable);
+ if (its_client_endpoint) {
+ *_has_address = its_client_endpoint->get_remote_address(
+ *_address);
+ }
} else {
_reliable = host_->find_or_create_remote_client(_service,
_instance, true, _client);
if (_reliable) {
- *_has_address = _reliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(
+ _reliable);
+ if (its_client_endpoint) {
+ *_has_address = its_client_endpoint->get_remote_address(
+ *_address);
+ }
}
}
break;
@@ -333,12 +374,23 @@ void service_discovery_impl::get_subscription_endpoints(
_reliable = host_->find_or_create_remote_client(_service,
_instance, true, _client);
if (_reliable) {
- *_has_address = _reliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(_reliable);
+ if (its_client_endpoint) {
+ *_has_address = its_client_endpoint->get_remote_address(
+ *_address);
+ }
} else {
- _unreliable = host_->find_or_create_remote_client(_service,
- _instance, false, _client);
+ _unreliable = host_->find_or_create_remote_client(_service,
+ _instance, false, _client);
if (_unreliable) {
- *_has_address = _unreliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(
+ _unreliable);
+ if (its_client_endpoint) {
+ *_has_address = its_client_endpoint->get_remote_address(
+ *_address);
+ }
}
}
break;
@@ -347,14 +399,24 @@ void service_discovery_impl::get_subscription_endpoints(
_instance,
false, _client);
if (_unreliable) {
- *_has_address = _unreliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(_unreliable);
+ if (its_client_endpoint) {
+ *_has_address = its_client_endpoint->get_remote_address(
+ *_address);
+ }
}
break;
case subscription_type_e::SU_RELIABLE:
_reliable = host_->find_or_create_remote_client(_service, _instance,
- true, _client);
+ true, _client);
if (_reliable) {
- *_has_address = _reliable->get_remote_address(*_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(_reliable);
+ if (its_client_endpoint) {
+ *_has_address = its_client_endpoint->get_remote_address(
+ *_address);
+ }
}
}
}
@@ -384,11 +446,25 @@ void service_discovery_impl::unsubscribe(service_t _service,
found_eventgroup->second.erase(_client);
auto endpoint = its_subscription->get_endpoint(false);
if (endpoint) {
- has_address = endpoint->get_remote_address(its_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<client_endpoint>(
+ endpoint);
+ if (its_client_endpoint) {
+ has_address =
+ its_client_endpoint->get_remote_address(
+ its_address);
+ }
} else {
endpoint = its_subscription->get_endpoint(true);
if (endpoint) {
- has_address = endpoint->get_remote_address(its_address);
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<
+ client_endpoint>(endpoint);
+ if (its_client_endpoint) {
+ has_address =
+ its_client_endpoint->get_remote_address(
+ its_address);
+ }
} else {
return;
}
@@ -422,6 +498,70 @@ void service_discovery_impl::unsubscribe_all(service_t _service, instance_t _ins
}
}
+void service_discovery_impl::unsubscribe_client(service_t _service,
+ instance_t _instance,
+ client_t _client) {
+ std::shared_ptr<runtime> its_runtime = runtime_.lock();
+ if (!its_runtime) {
+ return;
+ }
+ std::shared_ptr < message_impl > its_message = its_runtime->create_message();
+ boost::asio::ip::address its_address;
+ bool has_address(false);
+ {
+ std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
+ std::shared_ptr < subscription > its_subscription;
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ for (auto &found_eventgroup : found_instance->second) {
+ auto found_client = found_eventgroup.second.find(_client);
+ if (found_client != found_eventgroup.second.end()) {
+ its_subscription = found_client->second;
+ its_subscription->set_ttl(0);
+ found_eventgroup.second.erase(_client);
+ if (!has_address) {
+ auto endpoint = its_subscription->get_endpoint(
+ false);
+ if (endpoint) {
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<
+ client_endpoint>(endpoint);
+ if (its_client_endpoint) {
+ has_address =
+ its_client_endpoint->get_remote_address(
+ its_address);
+ }
+ } else {
+ endpoint = its_subscription->get_endpoint(true);
+ if (endpoint) {
+ std::shared_ptr<client_endpoint> its_client_endpoint =
+ std::dynamic_pointer_cast<
+ client_endpoint>(endpoint);
+ if (its_client_endpoint) {
+ has_address =
+ its_client_endpoint->get_remote_address(
+ its_address);
+ }
+ } else {
+ return;
+ }
+ }
+ }
+ insert_subscription(its_message, _service, _instance,
+ found_eventgroup.first, its_subscription, true,
+ true);
+ }
+ }
+ }
+ }
+ }
+ if (has_address && 0 < its_message->get_entries().size()) {
+ serialize_and_send(its_message, its_address);
+ }
+}
+
std::pair<session_t, bool> service_discovery_impl::get_session(
const boost::asio::ip::address &_address) {
std::pair<session_t, bool> its_session;
@@ -628,14 +768,14 @@ void service_discovery_impl::insert_option(
}
void service_discovery_impl::insert_find_entries(
- std::shared_ptr<message_impl> &_message, requests_t &_requests,
+ std::shared_ptr<message_impl> &_message,
uint32_t _start, uint32_t &_size, bool &_done) {
std::lock_guard<std::mutex> its_lock(requested_mutex_);
uint32_t its_size(0);
uint32_t i = 0;
_done = true;
- for (auto its_service : _requests) {
+ for (auto its_service : requested_) {
for (auto its_instance : its_service.second) {
auto its_request = its_instance.second;
uint8_t its_sent_counter = its_request->get_sent_counter();
@@ -838,7 +978,7 @@ bool service_discovery_impl::send(bool _is_announcing, bool _is_find) {
its_message = its_runtime->create_message();
its_messages.push_back(its_message);
- insert_find_entries(its_message, requested_, its_start, its_size, is_done);
+ insert_find_entries(its_message, its_start, its_size, is_done);
its_start += its_size / VSOMEIP_SOMEIP_SD_ENTRY_SIZE;
};
its_remaining -= its_size;
@@ -868,14 +1008,16 @@ void service_discovery_impl::on_message(const byte_t *_data, length_t _length,
msg << "sdi::on_message: ";
for (length_t i = 0; i < _length; ++i)
msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ VSOMEIP_INFO << msg.str();
#endif
if(is_suspended_) {
return;
}
+ current_remote_address_ = _sender;
deserializer_->set_data(_data, _length);
std::shared_ptr < message_impl
> its_message(deserializer_->deserialize_sd_message());
+ deserializer_->reset();
if (its_message) {
// ignore all SD messages with source address equal to node's unicast address
if (!check_source_address(_sender)) {
@@ -1195,13 +1337,12 @@ void service_discovery_impl::send_unicast_offer_service(
uint32_t its_size(max_message_size_);
insert_offer_service(its_message, _service, _instance, _info,
its_size);
- const boost::asio::ip::address its_address(get_current_remote_address());
- if (its_address.is_unspecified()) {
+ if (current_remote_address_.is_unspecified()) {
VSOMEIP_ERROR << "service_discovery_impl::"
"send_unicast_offer_service current remote address "
"is unspecified, won't send offer.";
} else {
- serialize_and_send(its_message, its_address);
+ serialize_and_send(its_message, current_remote_address_);
}
}
}
@@ -1891,14 +2032,13 @@ bool service_discovery_impl::is_tcp_connected(service_t _service,
std::shared_ptr<serviceinfo> its_info = found_instance->second;
if(its_info) {
//get reliable server endpoint
- auto its_reliable_endpoint = its_info->get_endpoint(true);
- if(its_reliable_endpoint) {
- std::shared_ptr<tcp_server_endpoint_impl> its_ptr(std::static_pointer_cast<tcp_server_endpoint_impl>(its_reliable_endpoint));
- if( !its_ptr->is_established(its_endpoint)) {
- }
- else {
- is_connected = true;
- }
+ auto its_reliable_server_endpoint =
+ std::dynamic_pointer_cast<tcp_server_endpoint_impl>(
+ its_info->get_endpoint(true));
+ if (its_reliable_server_endpoint
+ && its_reliable_server_endpoint->is_established(
+ its_endpoint)) {
+ is_connected = true;
}
}
}
@@ -1947,24 +2087,6 @@ void service_discovery_impl::check_ttl(const boost::system::error_code &_error)
}
}
-boost::asio::ip::address service_discovery_impl::get_current_remote_address() const {
- boost::asio::ip::address its_address;
- if (reliable_) {
- auto endpoint = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint_);
- if (endpoint && !endpoint->get_remote_address(its_address)) {
- VSOMEIP_ERROR << "service_discovery_impl::get_current_remote_address: "
- "couldn't determine remote address (reliable)";
- }
- } else {
- auto endpoint = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint_);
- if (endpoint && !endpoint->get_remote_address(its_address)) {
- VSOMEIP_ERROR << "service_discovery_impl::get_current_remote_address: "
- "couldn't determine remote address (unreliable)";
- }
- }
- return its_address;
-}
-
bool service_discovery_impl::check_static_header_fields(
const std::shared_ptr<const message> &_message) const {
if(_message->get_protocol_version() != protocol_version) {
@@ -2031,7 +2153,14 @@ void service_discovery_impl::send_subscriptions(service_t _service, instance_t _
found_client->second->set_endpoint(its_unreliable, false);
}
if (endpoint) {
- endpoint->get_remote_address(its_address);
+ if (!has_address) {
+ VSOMEIP_WARNING << "service_discovery_impl::"
+ "send_subscriptions couldn't determine "
+ "address for service.instance: "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << _service << "." << _instance;
+ continue;
+ }
std::shared_ptr<message_impl> its_message
= its_runtime->create_message();
@@ -2119,7 +2248,7 @@ bool service_discovery_impl::check_ipv4_address(
} else {
#if 0
- VSOMEIP_DEBUG << "First 3 triples of subscribers endpoint IP address are valid!";
+ VSOMEIP_INFO << "First 3 triples of subscribers endpoint IP address are valid!";
#endif
}
}
@@ -2418,16 +2547,18 @@ bool service_discovery_impl::send_stop_offer(
std::shared_ptr<serviceinfo> _info) {
std::shared_ptr < runtime > its_runtime = runtime_.lock();
if (its_runtime) {
- std::vector<std::shared_ptr<message_impl>> its_messages;
- std::shared_ptr<message_impl> its_message;
- its_message = its_runtime->create_message();
- its_messages.push_back(its_message);
+ if (_info->get_endpoint(false) || _info->get_endpoint(true)) {
+ std::vector<std::shared_ptr<message_impl>> its_messages;
+ std::shared_ptr<message_impl> its_message;
+ its_message = its_runtime->create_message();
+ its_messages.push_back(its_message);
- uint32_t its_size(max_message_size_);
- insert_offer_service(its_message, _service, _instance, _info, its_size);
+ uint32_t its_size(max_message_size_);
+ insert_offer_service(its_message, _service, _instance, _info, its_size);
- // Serialize and send
- return serialize_and_send_messages(its_messages);
+ // Serialize and send
+ return serialize_and_send_messages(its_messages);
+ }
}
return false;
}
diff --git a/implementation/tracing/include/trace_header.hpp b/implementation/tracing/include/trace_header.hpp
index 9e86d84..47b2e22 100644
--- a/implementation/tracing/include/trace_header.hpp
+++ b/implementation/tracing/include/trace_header.hpp
@@ -10,6 +10,8 @@
#include <vsomeip/primitive_types.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+
#define VSOMEIP_TRACE_HEADER_SIZE 8
namespace vsomeip {
@@ -28,6 +30,8 @@ enum class protocol_e : uint8_t {
struct trace_header {
bool prepare(const std::shared_ptr<endpoint> &_endpoint, bool _is_sending);
bool prepare(const endpoint* _endpoint, bool _is_sending);
+ void prepare(const boost::asio::ip::address_v4 &_address,
+ std::uint16_t _port, protocol_e _protocol, bool _is_sending);
byte_t data_[VSOMEIP_TRACE_HEADER_SIZE];
};
diff --git a/implementation/tracing/src/trace_header.cpp b/implementation/tracing/src/trace_header.cpp
index 2f293ee..7e4c700 100644
--- a/implementation/tracing/src/trace_header.cpp
+++ b/implementation/tracing/src/trace_header.cpp
@@ -7,6 +7,7 @@
#include "../include/trace_header.hpp"
#include "../../endpoints/include/endpoint.hpp"
+#include "../../endpoints/include/client_endpoint.hpp"
#include "../../utility/include/byteorder.hpp"
namespace vsomeip {
@@ -17,39 +18,49 @@ bool trace_header::prepare(const std::shared_ptr<endpoint> &_endpoint, bool _is_
}
bool trace_header::prepare(const endpoint *_endpoint, bool _is_sending) {
- boost::asio::ip::address its_address;
- if (_endpoint && _endpoint->get_remote_address(its_address)) {
- if (its_address.is_v6())
- return false;
-
- unsigned long its_address_as_long = its_address.to_v4().to_ulong();
-
- data_[0] = VSOMEIP_LONG_BYTE0(its_address_as_long);
- data_[1] = VSOMEIP_LONG_BYTE1(its_address_as_long);
- data_[2] = VSOMEIP_LONG_BYTE2(its_address_as_long);
- data_[3] = VSOMEIP_LONG_BYTE3(its_address_as_long);
-
- unsigned short its_port = _endpoint->get_remote_port();
- data_[4] = VSOMEIP_WORD_BYTE0(its_port);
- data_[5] = VSOMEIP_WORD_BYTE1(its_port);
-
- if (_endpoint->is_local()) {
- data_[6] = static_cast<byte_t>(protocol_e::local);
- } else {
- if (_endpoint->is_reliable()) {
- data_[6] = static_cast<byte_t>(protocol_e::tcp);
+ if (_endpoint) {
+ const client_endpoint* its_client_endpoint =
+ dynamic_cast<const client_endpoint*>(_endpoint);
+ if (its_client_endpoint) {
+
+ boost::asio::ip::address its_address;
+ its_client_endpoint->get_remote_address(its_address);
+ if (its_address.is_v6()) {
+ return false;
+ }
+
+ unsigned short its_port = its_client_endpoint->get_remote_port();
+ protocol_e its_protocol(protocol_e::unknown);
+ if (_endpoint->is_local()) {
+ its_protocol = protocol_e::local;
} else {
- data_[6] = static_cast<byte_t>(protocol_e::udp);
+ if (_endpoint->is_reliable()) {
+ its_protocol = protocol_e::tcp;
+ } else {
+ its_protocol = protocol_e::udp;
+ }
}
+ prepare(its_address.to_v4(), its_port, its_protocol, _is_sending);
+ return true;
}
-
- data_[7] = static_cast<byte_t>(_is_sending);
-
- } else {
- std::memset(data_, 0, VSOMEIP_TRACE_HEADER_SIZE);
}
+ std::memset(data_, 0, VSOMEIP_TRACE_HEADER_SIZE);
return true;
}
+void trace_header::prepare(const boost::asio::ip::address_v4 &_address,
+ std::uint16_t _port, protocol_e _protocol,
+ bool _is_sending) {
+ unsigned long its_address_as_long = _address.to_ulong();
+ data_[0] = VSOMEIP_LONG_BYTE0(its_address_as_long);
+ data_[1] = VSOMEIP_LONG_BYTE1(its_address_as_long);
+ data_[2] = VSOMEIP_LONG_BYTE2(its_address_as_long);
+ data_[3] = VSOMEIP_LONG_BYTE3(its_address_as_long);
+ data_[4] = VSOMEIP_WORD_BYTE0(_port);
+ data_[5] = VSOMEIP_WORD_BYTE1(_port);
+ data_[6] = static_cast<byte_t>(_protocol);
+ data_[7] = static_cast<byte_t>(_is_sending);
+}
+
} // namespace tc
} // namespace vsomeip
diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp
index 7e69401..2f8fc0f 100644
--- a/implementation/utility/include/utility.hpp
+++ b/implementation/utility/include/utility.hpp
@@ -104,6 +104,10 @@ public:
}
static uint16_t its_configuration_refs__;
+
+private:
+ static bool is_bigger_last_assigned_client_id(client_t _client);
+ static void set_client_id_lowbyte(client_t _client);
};
} // namespace vsomeip
diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp
index d91dd56..51785ff 100644
--- a/implementation/utility/src/utility.cpp
+++ b/implementation/utility/src/utility.cpp
@@ -148,7 +148,7 @@ bool utility::auto_configuration_init(const std::shared_ptr<configuration> &_con
if (configuration_data_mutex) {
if (GetLastError() == ERROR_ALREADY_EXISTS) {
- VSOMEIP_DEBUG << "utility::auto_configuration_init: use existing shared memory";
+ VSOMEIP_INFO << "utility::auto_configuration_init: use existing shared memory";
// mapping already exists, wait for mutex release and map in
DWORD waitResult = WaitForSingleObject(configuration_data_mutex, INFINITE);
@@ -190,7 +190,7 @@ bool utility::auto_configuration_init(const std::shared_ptr<configuration> &_con
}
} else {
- VSOMEIP_DEBUG << "utility::auto_configuration_init: create new shared memory";
+ VSOMEIP_INFO << "utility::auto_configuration_init: create new shared memory";
// create and init new mapping
its_descriptor = CreateFileMapping(
@@ -360,11 +360,11 @@ bool utility::auto_configuration_init(const std::shared_ptr<configuration> &_con
pthread_mutex_lock(&the_configuration_data__->mutex_);
its_configuration_refs__++;
pthread_mutex_unlock(&the_configuration_data__->mutex_);
+ }
- if (-1 == ::close(its_descriptor)) {
- VSOMEIP_ERROR << "utility::auto_configuration_init: "
- "close failed: " << std::strerror(errno);
- }
+ if (-1 == ::close(its_descriptor)) {
+ VSOMEIP_ERROR << "utility::auto_configuration_init: "
+ "close failed: " << std::strerror(errno);
}
}
}
@@ -413,7 +413,7 @@ void utility::auto_configuration_exit(client_t _client) {
VSOMEIP_ERROR << "utility::auto_configuration_exit: "
"munmap failed: " << std::strerror(errno);
} else {
- VSOMEIP_DEBUG << "utility::auto_configuration_exit: "
+ VSOMEIP_INFO << "utility::auto_configuration_exit: "
"munmap succeeded.";
the_configuration_data__ = nullptr;
if (unlink_shm) {
@@ -430,10 +430,7 @@ bool utility::is_used_client_id(client_t _client) {
for (int i = 0;
i < the_configuration_data__->max_used_client_ids_index_;
i++) {
- if (the_configuration_data__->used_client_ids_[i] == _client
- || _client
- < (the_configuration_data__->client_base_
- + the_configuration_data__->max_assigned_client_id_low_byte_)) {
+ if (the_configuration_data__->used_client_ids_[i] == _client) {
return true;
}
}
@@ -477,7 +474,7 @@ client_t utility::request_client_id(const std::shared_ptr<configuration> &_confi
#else
pthread_mutex_unlock(&the_configuration_data__->mutex_);
#endif
- return VSOMEIP_DIAGNOSIS_ADDRESS;
+ return ILLEGAL_CLIENT;
}
} else if (its_name == "" && the_configuration_data__->routing_manager_host_ == 0x0000) {
set_client_as_manager_host = true;
@@ -497,27 +494,63 @@ client_t utility::request_client_id(const std::shared_ptr<configuration> &_confi
return ILLEGAL_CLIENT;
}
- bool configured_and_not_used(false);
- if (_client != ILLEGAL_CLIENT && !is_used_client_id(_client)) {
- configured_and_not_used = true;
- }
-
- if (_client == ILLEGAL_CLIENT || is_used_client_id(_client)) {
- _client = the_configuration_data__->client_base_;
+ bool use_autoconfig = true;
+ if (_name != "" && _client != ILLEGAL_CLIENT) { // preconfigured client id
+ // check if application name has preconfigured client id in json
+ const client_t its_preconfigured_client_id = _config->get_id(_name);
+ if (its_preconfigured_client_id) {
+ // preconfigured client id for application name present in json
+ if (its_preconfigured_client_id == _client) {
+ // preconfigured client id for application name present in json
+ // and requested
+ if (!is_used_client_id(_client)) {
+ use_autoconfig = false;
+ }
+ } else {
+ // preconfigured client id for application name present in
+ // json, but different client id requested
+ if (!is_used_client_id(its_preconfigured_client_id)) {
+ // assign preconfigured client id if not already used
+ _client = its_preconfigured_client_id;
+ use_autoconfig = false;
+ } else if (!is_used_client_id(_client)) {
+ // if preconfigured client id is already used and
+ // requested is unused assign requested
+ use_autoconfig = false;
+ }
+ }
+ }
}
- while (is_used_client_id(_client)) {
- if ((_client & 0x00FF) + 1 > VSOMEIP_MAX_CLIENTS) {
+ if (use_autoconfig) {
+ if (_client == ILLEGAL_CLIENT || is_used_client_id(_client)) {
_client = the_configuration_data__->client_base_;
- the_configuration_data__->max_assigned_client_id_low_byte_ = 0;
- } else {
- _client++;
}
- }
- if (!configured_and_not_used) {
- the_configuration_data__->max_assigned_client_id_low_byte_ =
- static_cast<unsigned char>((_client & 0x00FF)
- % VSOMEIP_MAX_CLIENTS);
+ int increase_count = 0;
+ while (is_used_client_id(_client)
+ || !is_bigger_last_assigned_client_id(_client)
+ || _config->is_configured_client_id(_client)) {
+ if ((_client & 0xFF) + 1 > VSOMEIP_MAX_CLIENTS) {
+ _client = the_configuration_data__->client_base_;
+ the_configuration_data__->max_assigned_client_id_low_byte_ = 0;
+ } else {
+ _client++;
+ increase_count++;
+ if (increase_count > VSOMEIP_MAX_CLIENTS) {
+ VSOMEIP_ERROR << "Max amount of possible concurrent active"
+ << " vsomeip applications reached.";
+#ifdef WIN32
+ BOOL releaseResult = ReleaseMutex(configuration_data_mutex);
+ assert(releaseResult);
+ (void)releaseResult;
+#else
+ pthread_mutex_unlock(&the_configuration_data__->mutex_);
+#endif
+ return ILLEGAL_CLIENT;
+ }
+ }
+ }
+ set_client_id_lowbyte(_client);
}
if (set_client_as_manager_host) {
@@ -538,7 +571,7 @@ client_t utility::request_client_id(const std::shared_ptr<configuration> &_confi
#endif
return _client;
}
- return VSOMEIP_DIAGNOSIS_ADDRESS;
+ return ILLEGAL_CLIENT;
}
void utility::release_client_id(client_t _client) {
@@ -550,12 +583,13 @@ void utility::release_client_id(client_t _client) {
pthread_mutex_lock(&the_configuration_data__->mutex_);
#endif
int i = 0;
- while (the_configuration_data__->used_client_ids_[i] != _client &&
- i < the_configuration_data__->max_used_client_ids_index_) {
- i++;
+ for (; i < the_configuration_data__->max_used_client_ids_index_; i++) {
+ if (the_configuration_data__->used_client_ids_[i] == _client) {
+ break;
+ }
}
- if (i <= the_configuration_data__->max_used_client_ids_index_) {
+ if (i < the_configuration_data__->max_used_client_ids_index_) {
the_configuration_data__->max_used_client_ids_index_--;
for (; i < the_configuration_data__->max_used_client_ids_index_; i++) {
the_configuration_data__->used_client_ids_[i]
@@ -614,4 +648,17 @@ void utility::set_routing_manager_host(client_t _client) {
#endif
}
+bool utility::is_bigger_last_assigned_client_id(client_t _client) {
+ return _client
+ > ((the_configuration_data__->client_base_ & 0xFF00)
+ + the_configuration_data__->max_assigned_client_id_low_byte_);
+}
+
+void utility::set_client_id_lowbyte(client_t _client) {
+ const unsigned char its_low_byte =
+ static_cast<unsigned char>(_client & 0xFF);
+ the_configuration_data__->max_assigned_client_id_low_byte_ = its_low_byte
+ % VSOMEIP_MAX_CLIENTS;
+}
+
} // namespace vsomeip
diff --git a/interface/vsomeip/defines.hpp b/interface/vsomeip/defines.hpp
index 2323c19..d75b028 100644
--- a/interface/vsomeip/defines.hpp
+++ b/interface/vsomeip/defines.hpp
@@ -8,8 +8,10 @@
#define VSOMEIP_PROTOCOL_VERSION 0x1
-#define VSOMEIP_MAX_LOCAL_MESSAGE_SIZE 32768
-#define VSOMEIP_MAX_TCP_MESSAGE_SIZE 4095
+// 0 = unlimited, if not specified otherwise via configuration file
+#define VSOMEIP_MAX_LOCAL_MESSAGE_SIZE 0
+// 0 = unlimited, if not specified otherwise via configuration file
+#define VSOMEIP_MAX_TCP_MESSAGE_SIZE 0
#define VSOMEIP_MAX_UDP_MESSAGE_SIZE 1416
#define VSOMEIP_PACKET_SIZE VSOMEIP_MAX_UDP_MESSAGE_SIZE
diff --git a/interface/vsomeip/runtime.hpp b/interface/vsomeip/runtime.hpp
index 14ecb60..00dd069 100644
--- a/interface/vsomeip/runtime.hpp
+++ b/interface/vsomeip/runtime.hpp
@@ -50,6 +50,8 @@ public:
virtual std::shared_ptr<application> get_application(
const std::string &_name) const = 0;
+
+ virtual void remove_application( const std::string &_name) = 0;
};
} // namespace vsomeip
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index e84e1a4..ed4e983 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -186,6 +186,7 @@ if(NOT ${TESTS_BAT})
${Boost_LIBRARIES}
${DL_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
+ ${TEST_LINK_LIBRARIES}
)
set(TEST_MAGIC_COOKIES_SERVICE ${TEST_MAGIC_COOKIES_NAME}_service)
@@ -195,6 +196,7 @@ if(NOT ${TESTS_BAT})
${Boost_LIBRARIES}
${DL_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
+ ${TEST_LINK_LIBRARIES}
)
# Copy config file for client into $BUILDDIR/test
@@ -665,6 +667,15 @@ if(NOT ${TESTS_BAT})
${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER}
${TEST_PAYLOAD_CLIENT}
)
+
+ ##############################################################################
+ set(TEST_LOCAL_PAYLOAD_HUGE_NAME local_payload_test_huge_payload)
+ # Copy bashscript to start client and server $BUILDDIR/test
+ set(TEST_LOCAL_PAYLOAD_HUGE_STARTER ${TEST_LOCAL_PAYLOAD_HUGE_NAME}_starter.sh)
+ copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_HUGE_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_HUGE_STARTER}
+ ${TEST_PAYLOAD_CLIENT}
+ )
endif()
##############################################################################
@@ -700,6 +711,22 @@ if(NOT ${TESTS_BAT})
)
# Copy config file for client and service into $BUILDDIR/test
+ set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_random.json)
+ copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM}
+ ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM}
+ ${TEST_BIG_PAYLOAD_SERVICE}
+ )
+
+ # Copy config file for client and service into $BUILDDIR/test
+ set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_limited.json)
+ copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED}
+ ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED}
+ ${TEST_BIG_PAYLOAD_SERVICE}
+ )
+
+ # Copy config file for client and service into $BUILDDIR/test
set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_client.json)
configure_file(
${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in
@@ -723,6 +750,30 @@ if(NOT ${TESTS_BAT})
${TEST_BIG_PAYLOAD_SERVICE}
)
+ # Copy config file for client and service into $BUILDDIR/test
+ set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_client_random.json)
+ configure_file(
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}
+ @ONLY)
+ copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}
+ ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}
+ ${TEST_BIG_PAYLOAD_CLIENT}
+ )
+
+ # Copy config file for client and service into $BUILDDIR/test
+ set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_service_random.json)
+ configure_file(
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}
+ @ONLY)
+ copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}
+ ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}
+ ${TEST_BIG_PAYLOAD_SERVICE}
+ )
+
# Copy bashscript to start client local to $BUILDDIR/test
set(TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_local_start.sh)
copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT}
@@ -739,6 +790,8 @@ if(NOT ${TESTS_BAT})
# Copy bashscript to start client and server $BUILDDIR/test
set(TEST_LOCAL_BIG_PAYLOAD_NAME big_payload_test_local)
+ set(TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_random)
+ set(TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_limited)
set(TEST_LOCAL_BIG_PAYLOAD_STARTER ${TEST_LOCAL_BIG_PAYLOAD_NAME}_starter.sh)
copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_STARTER}
${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER}
@@ -747,6 +800,8 @@ if(NOT ${TESTS_BAT})
# Copy bashscript to start client for external test into $BUILDDIR/test
set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external)
+ set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_external_random)
+ set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_external_limited)
set(TEST_EXTERNAL_BIG_PAYLOAD_STARTER ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_starter.sh)
copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER}
${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER}
@@ -783,6 +838,18 @@ if(NOT ${TESTS_BAT})
${TEST_LINK_LIBRARIES}
)
+ set(TEST_CLIENT_ID_UTILITY ${TEST_CLIENT_ID_NAME}_utility)
+ add_executable(${TEST_CLIENT_ID_UTILITY}
+ client_id_tests/${TEST_CLIENT_ID_UTILITY}.cpp
+ ${PROJECT_SOURCE_DIR}/implementation/utility/src/utility.cpp)
+ target_link_libraries(${TEST_CLIENT_ID_UTILITY}
+ vsomeip
+ vsomeip-cfg
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${TEST_LINK_LIBRARIES}
+ )
+
# Copy config files for test into $BUILDDIR/test
set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE
${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_master.json)
@@ -904,6 +971,13 @@ if(NOT ${TESTS_BAT})
${TEST_CLIENT_ID_SERVICE}
)
+ set(TEST_CLIENT_ID_UTILITY_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility.json)
+ copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}
+ ${TEST_CLIENT_ID_UTILITY}
+ )
+
# copy starter scripts into builddir
set(TEST_CLIENT_ID_MASTER_STARTER ${TEST_CLIENT_ID_NAME}_master_starter.sh)
copy_to_builddir(${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_MASTER_STARTER}
@@ -1569,6 +1643,7 @@ if(NOT ${TESTS_BAT})
add_dependencies(${TEST_BIG_PAYLOAD_SERVICE} gtest)
add_dependencies(${TEST_BIG_PAYLOAD_CLIENT} gtest)
add_dependencies(${TEST_CLIENT_ID_SERVICE} gtest)
+ add_dependencies(${TEST_CLIENT_ID_UTILITY} gtest)
add_dependencies(${TEST_SUBSCRIBE_NOTIFY_SERVICE} gtest)
add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} gtest)
add_dependencies(${TEST_CPU_LOAD_SERVICE} gtest)
@@ -1607,6 +1682,7 @@ if(NOT ${TESTS_BAT})
add_dependencies(build_tests ${TEST_BIG_PAYLOAD_SERVICE})
add_dependencies(build_tests ${TEST_BIG_PAYLOAD_CLIENT})
add_dependencies(build_tests ${TEST_CLIENT_ID_SERVICE})
+ add_dependencies(build_tests ${TEST_CLIENT_ID_UTILITY})
add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_SERVICE})
add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE})
add_dependencies(build_tests ${TEST_CPU_LOAD_SERVICE})
@@ -1674,6 +1750,10 @@ if(NOT ${TESTS_BAT})
add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME}
COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_STARTER}
)
+ add_test(NAME ${TEST_LOCAL_PAYLOAD_HUGE_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_HUGE_STARTER}
+ )
+ set_tests_properties(${TEST_LOCAL_PAYLOAD_HUGE_NAME} PROPERTIES TIMEOUT 240)
add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME}
COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER}
)
@@ -1691,11 +1771,32 @@ if(NOT ${TESTS_BAT})
COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER}
)
set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 60)
+
+ add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} RANDOM
+ )
+ set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 60)
+
+ add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} LIMITED
+ )
+ set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 60)
+
add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}
COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER}
)
set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 60)
+ add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} RANDOM
+ )
+ set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 60)
+
+ add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITED
+ )
+ set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 60)
+
# client id tests
add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports
COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE})
@@ -1709,6 +1810,13 @@ if(NOT ${TESTS_BAT})
COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE})
set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports PROPERTIES TIMEOUT 60)
+ add_test(NAME ${TEST_CLIENT_ID_UTILITY}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY})
+ set_property(TEST ${TEST_CLIENT_ID_UTILITY}
+ APPEND PROPERTY ENVIRONMENT
+ "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}")
+ set_tests_properties(${TEST_CLIENT_ID_UTILITY} PROPERTIES TIMEOUT 60)
+
# subscribe notify tests
add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp
COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE})
diff --git a/test/application_tests/application_test.cpp b/test/application_tests/application_test.cpp
index 6832c1f..c6c1b03 100644
--- a/test/application_tests/application_test.cpp
+++ b/test/application_tests/application_test.cpp
@@ -6,6 +6,7 @@
#include <thread>
#include <mutex>
#include <condition_variable>
+#include <future>
#include <gtest/gtest.h>
@@ -25,8 +26,8 @@ protected:
void SetUp() {
app_ = runtime::get()->create_application("application_test");
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
@@ -47,9 +48,12 @@ protected:
*/
TEST_F(someip_application_test, start_stop_application)
{
+ std::promise<bool> its_promise;
std::thread t([&](){
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
app_->stop();
t.join();
@@ -61,9 +65,12 @@ TEST_F(someip_application_test, start_stop_application)
TEST_F(someip_application_test, start_stop_application_multiple)
{
for (int i = 0; i < 10; ++i) {
+ std::promise<bool> its_promise;
std::thread t([&]() {
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
app_->stop();
t.join();
@@ -76,9 +83,12 @@ TEST_F(someip_application_test, start_stop_application_multiple)
TEST_F(someip_application_test, start_stop_application_multiple_offer_service)
{
for (int i = 0; i < 10; ++i) {
+ std::promise<bool> its_promise;
std::thread t([&]() {
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
@@ -94,10 +104,13 @@ TEST_F(someip_application_test, start_stop_application_multiple_offer_service)
*/
TEST_F(someip_application_test, restart_without_stopping)
{
+ std::promise<bool> its_promise;
std::thread t([&]() {
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
VSOMEIP_WARNING << "An error message should appear now";
// should print error
@@ -111,10 +124,13 @@ TEST_F(someip_application_test, restart_without_stopping)
*/
TEST_F(someip_application_test, stop_application_twice)
{
+ std::promise<bool> its_promise;
std::thread t([&]() {
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
std::this_thread::sleep_for(std::chrono::milliseconds(100));
app_->stop();
@@ -131,8 +147,8 @@ protected:
app_ = runtime::get()->create_application("application_test");
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
diff --git a/test/application_tests/application_test_client.cpp b/test/application_tests/application_test_client.cpp
index a227799..ba39417 100644
--- a/test/application_tests/application_test_client.cpp
+++ b/test/application_tests/application_test_client.cpp
@@ -11,6 +11,7 @@
#include <thread>
#include <map>
#include <algorithm>
+#include <future>
#include <gtest/gtest.h>
@@ -33,7 +34,10 @@ public:
received_responses_(0),
sent_requests_(0),
stop_called_(false) {
- app_->init();
+ if (!app_->init()) {
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
+ }
app_->register_state_handler(
std::bind(&application_test_client::on_state, this,
std::placeholders::_1));
@@ -51,9 +55,13 @@ public:
std::placeholders::_3));
app_->request_service(service_info_.service_id,
service_info_.instance_id);
+ std::promise<bool> its_promise;
application_thread_ = std::thread([&](){
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
~application_test_client() {
@@ -155,9 +163,6 @@ public:
<< " responses. Delta: " << sent_requests_ - received_responses_;
std::uint32_t counter(0);
if (check) {
- if (sent_requests_ == 0 || received_responses_ == 0) {
- EXPECT_EQ(0, 1);
- }
while(sent_requests_ < received_responses_) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if(++counter > 50) {
diff --git a/test/application_tests/application_test_daemon.cpp b/test/application_tests/application_test_daemon.cpp
index 6e2c7cb..c244e5a 100644
--- a/test/application_tests/application_test_daemon.cpp
+++ b/test/application_tests/application_test_daemon.cpp
@@ -4,6 +4,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <gtest/gtest.h>
+#include <future>
#include <vsomeip/vsomeip.hpp>
#include "../../implementation/logging/include/logger.hpp"
@@ -12,10 +13,17 @@ class application_test_daemon {
public:
application_test_daemon() :
app_(vsomeip::runtime::get()->create_application("daemon")) {
- app_->init();
+ if (!app_->init()) {
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
+ }
+ std::promise<bool> its_promise;
application_thread_ = std::thread([&](){
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
VSOMEIP_INFO << "Daemon starting";
}
diff --git a/test/application_tests/application_test_service.cpp b/test/application_tests/application_test_service.cpp
index a1c654e..d21ca68 100644
--- a/test/application_tests/application_test_service.cpp
+++ b/test/application_tests/application_test_service.cpp
@@ -11,6 +11,7 @@
#include <thread>
#include <map>
#include <algorithm>
+#include <future>
#include <gtest/gtest.h>
@@ -31,7 +32,10 @@ public:
wait_until_registered_(true),
offer_thread_(std::bind(&application_test_service::run, this)),
stop_called_(false) {
- app_->init();
+ if (!app_->init()) {
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
+ }
app_->register_state_handler(
std::bind(&application_test_service::on_state, this,
std::placeholders::_1));
@@ -45,9 +49,13 @@ public:
service_info_.instance_id, service_info_.shutdown_method_id,
std::bind(&application_test_service::on_shutdown_method_called, this,
std::placeholders::_1));
+ std::promise<bool> its_promise;
application_thread_ = std::thread([&](){
+ its_promise.set_value(true);
app_->start();
});
+ EXPECT_TRUE(its_promise.get_future().get());
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
~application_test_service() {
diff --git a/test/big_payload_tests/big_payload_test_client.cpp b/test/big_payload_tests/big_payload_test_client.cpp
index a18dd0c..bc472df 100644
--- a/test/big_payload_tests/big_payload_test_client.cpp
+++ b/test/big_payload_tests/big_payload_test_client.cpp
@@ -6,24 +6,39 @@
#include "big_payload_test_client.hpp"
#include "big_payload_test_globals.hpp"
-big_payload_test_client::big_payload_test_client(bool _use_tcp) :
- app_(vsomeip::runtime::get()->create_application()),
- request_(vsomeip::runtime::get()->create_request(_use_tcp)),
- running_(true),
- blocked_(false),
- is_available_(false),
- number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND),
- number_of_sent_messages_(0),
- number_of_acknowledged_messages_(0),
- sender_(std::bind(&big_payload_test_client::run, this))
-{
+big_payload_test_client::big_payload_test_client(
+ bool _use_tcp, big_payload_test::test_mode _test_mode) :
+ app_(vsomeip::runtime::get()->create_application("big_payload_test_client")),
+ request_(vsomeip::runtime::get()->create_request(_use_tcp)),
+ running_(true),
+ blocked_(false),
+ is_available_(false),
+ test_mode_(_test_mode),
+ number_of_messages_to_send_(
+ test_mode_ == big_payload_test::test_mode::RANDOM ?
+ big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM :
+ big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES),
+ number_of_sent_messages_(0),
+ number_of_acknowledged_messages_(0),
+ sender_(std::bind(&big_payload_test_client::run, this)) {
+ switch (test_mode_) {
+ case big_payload_test::test_mode::RANDOM:
+ service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_RANDOM;
+ break;
+ case big_payload_test::test_mode::LIMITED:
+ service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED;
+ break;
+ default:
+ service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID;
+ break;
+ }
}
-void big_payload_test_client::init()
+bool big_payload_test_client::init()
{
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_state_handler(
@@ -31,15 +46,16 @@ void big_payload_test_client::init()
std::placeholders::_1));
app_->register_message_handler(vsomeip::ANY_SERVICE,
- vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD,
+ vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD,
std::bind(&big_payload_test_client::on_message, this,
std::placeholders::_1));
- app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
- vsomeip_test::TEST_SERVICE_INSTANCE_ID,
+ app_->register_availability_handler(service_id_,
+ big_payload_test::TEST_SERVICE_INSTANCE_ID,
std::bind(&big_payload_test_client::on_availability, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
+ return true;
}
void big_payload_test_client::start()
@@ -51,27 +67,28 @@ void big_payload_test_client::start()
void big_payload_test_client::stop()
{
VSOMEIP_INFO << "Stopping...";
- app_->unregister_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
- vsomeip_test::TEST_SERVICE_INSTANCE_ID);
- app_->unregister_state_handler();
- app_->unregister_message_handler(vsomeip::ANY_SERVICE,
- vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD);
+ if (test_mode_ == big_payload_test::test_mode::LIMITED) {
+ std::this_thread::sleep_for(std::chrono::milliseconds(3000));
+ ASSERT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_ / 4);
+ }
app_->clear_all_handler();
app_->stop();
}
void big_payload_test_client::join_sender_thread(){
sender_.join();
-
- ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_);
+ if (test_mode_ == big_payload_test::test_mode::LIMITED) {
+ ASSERT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_ / 4);
+ } else {
+ ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_);
+ }
}
void big_payload_test_client::on_state(vsomeip::state_type_e _state)
{
- if(_state == vsomeip::state_type_e::ST_REGISTERED)
- {
- app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID,
- vsomeip_test::TEST_SERVICE_INSTANCE_ID, false);
+ if (_state == vsomeip::state_type_e::ST_REGISTERED) {
+ app_->request_service(service_id_,
+ big_payload_test::TEST_SERVICE_INSTANCE_ID, false);
}
}
@@ -82,8 +99,8 @@ void big_payload_test_client::on_availability(vsomeip::service_t _service,
<< _service << "." << _instance << "] is "
<< (_is_available ? "available." : "NOT available.");
- if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service
- && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance)
+ if(service_id_ == _service
+ && big_payload_test::TEST_SERVICE_INSTANCE_ID == _instance)
{
if(is_available_ && !_is_available)
{
@@ -107,8 +124,15 @@ void big_payload_test_client::on_message(const std::shared_ptr<vsomeip::message>
<< _response->get_client() << "/" << std::setw(4)
<< std::setfill('0') << std::hex << _response->get_session()
<< "] size: " << std::dec << _response->get_payload()->get_length();
-
- ASSERT_EQ(_response->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE);
+ static vsomeip::session_t last_session(0);
+ ASSERT_GT(_response->get_session(), last_session);
+ last_session = _response->get_session();
+
+ if(test_mode_ == big_payload_test::test_mode::RANDOM) {
+ ASSERT_LT(_response->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE_RANDOM);
+ } else {
+ ASSERT_EQ(_response->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE);
+ }
bool check(true);
vsomeip::length_t len = _response->get_payload()->get_length();
@@ -120,7 +144,13 @@ void big_payload_test_client::on_message(const std::shared_ptr<vsomeip::message>
GTEST_FATAL_FAILURE_("wrong data transmitted");
}
number_of_acknowledged_messages_++;
- send();
+ if (test_mode_ == big_payload_test::test_mode::LIMITED) {
+ if (number_of_acknowledged_messages_ == number_of_messages_to_send_ / 4) {
+ send();
+ }
+ } else if ( number_of_acknowledged_messages_ == number_of_messages_to_send_) {
+ send();
+ }
}
void big_payload_test_client::send()
@@ -138,20 +168,37 @@ void big_payload_test_client::run()
condition_.wait(its_lock);
}
blocked_ = false;
- request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID);
- request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID);
- request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID);
-
- std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload();
- std::vector< vsomeip::byte_t > its_payload_data;
- for (unsigned int i = 0; i < big_payload_test::BIG_PAYLOAD_SIZE; ++i) {
- its_payload_data.push_back(big_payload_test::DATA_CLIENT_TO_SERVICE);
- }
- its_payload->set_data(its_payload_data);
- request_->set_payload(its_payload);
+
+ request_->set_service(service_id_);
+ request_->set_instance(big_payload_test::TEST_SERVICE_INSTANCE_ID);
+ request_->set_method(big_payload_test::TEST_SERVICE_METHOD_ID);
+
+ std::srand(static_cast<unsigned int>(std::time(0)));
+
+ std::shared_ptr<vsomeip::payload> its_payload =
+ vsomeip::runtime::get()->create_payload();
+ std::vector<vsomeip::byte_t> its_payload_data;
for (unsigned int i = 0; i < number_of_messages_to_send_; i++)
{
+ if (test_mode_ == big_payload_test::test_mode::RANDOM) {
+ unsigned int datasize(std::rand() % big_payload_test::BIG_PAYLOAD_SIZE_RANDOM);
+ its_payload_data.assign(datasize, big_payload_test::DATA_CLIENT_TO_SERVICE);
+ } else if (test_mode_ == big_payload_test::test_mode::LIMITED) {
+ if (i % 2) {
+ // try to sent a too big payload for half of the messages
+ its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE + 3,
+ big_payload_test::DATA_CLIENT_TO_SERVICE);
+ } else {
+ its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE,
+ big_payload_test::DATA_CLIENT_TO_SERVICE);
+ }
+ } else {
+ its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE,
+ big_payload_test::DATA_CLIENT_TO_SERVICE);
+ }
+ its_payload->set_data(its_payload_data);
+ request_->set_payload(its_payload);
app_->send(request_, true);
VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0')
<< std::hex << request_->get_client() << "/" << std::setw(4)
@@ -159,30 +206,50 @@ void big_payload_test_client::run()
<< "] sent a request to Service [" << std::setw(4)
<< std::setfill('0') << std::hex << request_->get_service()
<< "." << std::setw(4) << std::setfill('0') << std::hex
- << request_->get_instance() << "]";
+ << request_->get_instance() << "] size: " << std::dec <<
+ request_->get_payload()->get_length();
number_of_sent_messages_++;
- while(!blocked_) {
- condition_.wait(its_lock);
+ }
+ while(!blocked_) {
+ if (std::cv_status::timeout
+ == condition_.wait_for(its_lock, std::chrono::seconds(120))) {
+ GTEST_FATAL_FAILURE_("Didn't receive all replies within time");
+ } else {
+ if (test_mode_ == big_payload_test::LIMITED) {
+ ASSERT_EQ(number_of_messages_to_send_ / 4,
+ number_of_acknowledged_messages_);
+ } else {
+ ASSERT_EQ(number_of_sent_messages_,
+ number_of_acknowledged_messages_);
+ }
}
- blocked_ = false;
}
- ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_);
stop();
}
+static big_payload_test::test_mode test_mode(big_payload_test::test_mode::UNKNOWN);
+
TEST(someip_big_payload_test, send_ten_messages_to_service)
{
bool use_tcp = true;
- big_payload_test_client test_client_(use_tcp);
- test_client_.init();
- test_client_.start();
- test_client_.join_sender_thread();
+ big_payload_test_client test_client_(use_tcp, test_mode);
+ if (test_client_.init()) {
+ test_client_.start();
+ test_client_.join_sender_thread();
+ }
}
#ifndef WIN32
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
+ if (argc > 1) {
+ if (std::string("RANDOM") == std::string(argv[1])) {
+ test_mode = big_payload_test::test_mode::RANDOM;
+ } else if (std::string("LIMITED") == std::string(argv[1])) {
+ test_mode = big_payload_test::test_mode::LIMITED;
+ }
+ }
return RUN_ALL_TESTS();
}
#endif
diff --git a/test/big_payload_tests/big_payload_test_client.hpp b/test/big_payload_tests/big_payload_test_client.hpp
index 3524123..30bf8c7 100644
--- a/test/big_payload_tests/big_payload_test_client.hpp
+++ b/test/big_payload_tests/big_payload_test_client.hpp
@@ -14,14 +14,16 @@
#include <mutex>
#include <condition_variable>
#include <functional>
+#include <atomic>
-#include "../someip_test_globals.hpp"
+#include "big_payload_test_globals.hpp"
+#include "../../implementation/logging/include/logger.hpp"
class big_payload_test_client
{
public:
- big_payload_test_client(bool _use_tcp);
- void init();
+ big_payload_test_client(bool _use_tcp, big_payload_test::test_mode _random_mode);
+ bool init();
void start();
void stop();
void join_sender_thread();
@@ -40,10 +42,12 @@ private:
bool running_;
bool blocked_;
bool is_available_;
+ big_payload_test::test_mode test_mode_;
std::uint32_t number_of_messages_to_send_;
std::uint32_t number_of_sent_messages_;
- std::uint32_t number_of_acknowledged_messages_;
+ std::atomic<std::uint32_t> number_of_acknowledged_messages_;
std::thread sender_;
+ vsomeip::service_t service_id_;
};
#endif /* BIGPAYLOADTESTCLIENT_HPP_ */
diff --git a/test/big_payload_tests/big_payload_test_external_starter.sh b/test/big_payload_tests/big_payload_test_external_starter.sh
index 6550adc..7de3342 100755
--- a/test/big_payload_tests/big_payload_test_external_starter.sh
+++ b/test/big_payload_tests/big_payload_test_external_starter.sh
@@ -10,18 +10,38 @@
# the testcase simply executes this script. This script then runs client
# and service and checks that both exit successfully.
+if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" ]]
+then
+ echo "The only allowed parameter to this script is RANDOM or LIMITED."
+ echo "Like $0 RANDOM"
+ exit 1
+fi
+
FAIL=0
# Start the client
-export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client.json
-export VSOMEIP_APPLICATION_NAME=big_payload_test_client
-./big_payload_test_client &
+if [[ $# -gt 0 && $1 == "RANDOM" ]]
+then
+ export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_random.json
+else
+ export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client.json
+fi
+./big_payload_test_client $1 &
+BIG_PAYLOAD_TEST_PID=$!
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting big payload test on slave LXC"
+ if [[ $# -gt 0 ]]; then
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./big_payload_test_service_external_start.sh $1\"" &
+ else
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./big_payload_test_service_external_start.sh"' &
+ fi
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
** Please now run:
-** big_payload_test_service_external_start.sh
+** big_payload_test_service_external_start.sh $1
** from an external host to successfully complete this test.
**
** You probably will need to adapt the 'unicast' settings in
@@ -30,6 +50,7 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# Wait until client and service are finished
for job in $(jobs -p)
diff --git a/test/big_payload_tests/big_payload_test_globals.hpp b/test/big_payload_tests/big_payload_test_globals.hpp
index 28a6205..01fe949 100644
--- a/test/big_payload_tests/big_payload_test_globals.hpp
+++ b/test/big_payload_tests/big_payload_test_globals.hpp
@@ -10,8 +10,25 @@
namespace big_payload_test {
constexpr std::uint32_t BIG_PAYLOAD_SIZE = 1024*600;
+ constexpr std::uint32_t BIG_PAYLOAD_SIZE_RANDOM = 1024*1024*10;
constexpr vsomeip::byte_t DATA_SERVICE_TO_CLIENT = 0xAA;
constexpr vsomeip::byte_t DATA_CLIENT_TO_SERVICE = 0xFF;
+
+ constexpr std::uint32_t BIG_PAYLOAD_TEST_NUMBER_MESSAGES = 10;
+ constexpr std::uint32_t BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM = 50;
+
+ constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID = 0x1234;
+ constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_LIMITED = 0x1235;
+ constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_RANDOM = 0x1236;
+
+ constexpr vsomeip::service_t TEST_SERVICE_INSTANCE_ID = 0x1;
+ constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID = 0x8421;
+
+ enum test_mode {
+ RANDOM,
+ LIMITED,
+ UNKNOWN
+ };
}
#endif /* BIG_PAYLOAD_TEST_GLOBALS_HPP_ */
diff --git a/test/big_payload_tests/big_payload_test_local_limited.json b/test/big_payload_tests/big_payload_test_local_limited.json
new file mode 100644
index 0000000..a711df1
--- /dev/null
+++ b/test/big_payload_tests/big_payload_test_local_limited.json
@@ -0,0 +1,42 @@
+{
+ "unicast":"127.0.0.1",
+ "logging":
+ {
+ "level":"error",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+ "dlt":"false"
+ },
+ "applications":
+ [
+ {
+ "name":"big_payload_test_service",
+ "id":"0x1277"
+ },
+ {
+ "name":"big_payload_test_client",
+ "id":"0x1344"
+ }
+ ],
+ "services":
+ [
+ {
+ "service":"0x1234",
+ "instance":"0x5678"
+ }
+ ],
+ "max-payload-size-local" : "614400",
+ "routing":"big_payload_test_service",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.244.224.245",
+ "port":"30490",
+ "protocol":"udp"
+ }
+}
+
diff --git a/test/big_payload_tests/big_payload_test_local_random.json b/test/big_payload_tests/big_payload_test_local_random.json
new file mode 100644
index 0000000..b49683e
--- /dev/null
+++ b/test/big_payload_tests/big_payload_test_local_random.json
@@ -0,0 +1,44 @@
+{
+ "unicast":"127.0.0.1",
+ "logging":
+ {
+ "level":"debug",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+ "dlt":"false"
+ },
+ "applications":
+ [
+ {
+ "name":"big_payload_test_service",
+ "id":"0x1277",
+ "max_dispatch_time" : "5000"
+ },
+ {
+ "name":"big_payload_test_client",
+ "id":"0x1344",
+ "max_dispatch_time" : "5000"
+ }
+ ],
+ "services":
+ [
+ {
+ "service":"0x1234",
+ "instance":"0x5678"
+ }
+ ],
+ "buffer-shrink-threshold" : "2",
+ "routing":"big_payload_test_service",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.244.224.245",
+ "port":"30490",
+ "protocol":"udp"
+ }
+}
+
diff --git a/test/big_payload_tests/big_payload_test_local_starter.sh b/test/big_payload_tests/big_payload_test_local_starter.sh
index d32b6a0..792e840 100755
--- a/test/big_payload_tests/big_payload_test_local_starter.sh
+++ b/test/big_payload_tests/big_payload_test_local_starter.sh
@@ -10,16 +10,28 @@
# the testcase simply executes this script. This script then runs client
# and service and checks that both exit successfully.
+if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" ]]
+then
+ echo "The only allowed parameter to this script is RANDOM or LIMITED."
+ echo "Like $0 RANDOM"
+ exit 1
+fi
+
+
FAIL=0
# Start the service
-export VSOMEIP_APPLICATION_NAME=big_payload_test_service
-export VSOMEIP_CONFIGURATION=big_payload_test_local.json
-./big_payload_test_service &
+if [[ $# -gt 0 && $1 == "RANDOM" ]]; then
+ export VSOMEIP_CONFIGURATION=big_payload_test_local_random.json
+elif [[ $# -gt 0 && $1 == "LIMITED" ]]; then
+ export VSOMEIP_CONFIGURATION=big_payload_test_local_limited.json
+else
+ export VSOMEIP_CONFIGURATION=big_payload_test_local.json
+fi
+./big_payload_test_service $1 &
# Start the client
-export VSOMEIP_APPLICATION_NAME=big_payload_test_client
-./big_payload_test_client &
+./big_payload_test_client $1 &
# Wait until client and service are finished
for job in $(jobs -p)
diff --git a/test/big_payload_tests/big_payload_test_service.cpp b/test/big_payload_tests/big_payload_test_service.cpp
index 37f3d7f..6f0e056 100644
--- a/test/big_payload_tests/big_payload_test_service.cpp
+++ b/test/big_payload_tests/big_payload_test_service.cpp
@@ -7,31 +7,48 @@
#include "big_payload_test_globals.hpp"
-big_payload_test_service::big_payload_test_service() :
- app_(vsomeip::runtime::get()->create_application()),
+big_payload_test_service::big_payload_test_service(big_payload_test::test_mode _test_mode) :
+ app_(vsomeip::runtime::get()->create_application("big_payload_test_service")),
is_registered_(false),
blocked_(false),
+ test_mode_(_test_mode),
number_of_received_messages_(0),
offer_thread_(std::bind(&big_payload_test_service::run, this))
{
+ switch (test_mode_) {
+ case big_payload_test::test_mode::RANDOM:
+ expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM;
+ service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_RANDOM;
+ break;
+ case big_payload_test::test_mode::LIMITED:
+ expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2;
+ service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED;
+ break;
+ default:
+ expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES;
+ service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID;
+ break;
+ }
}
-void big_payload_test_service::init()
+bool big_payload_test_service::init()
{
std::lock_guard<std::mutex> its_lock(mutex_);
-
+ std::srand(static_cast<unsigned int>(std::time(0)));
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
- app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
- vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
+ app_->register_message_handler(vsomeip::ANY_SERVICE,
+ big_payload_test::TEST_SERVICE_INSTANCE_ID,
+ big_payload_test::TEST_SERVICE_METHOD_ID,
std::bind(&big_payload_test_service::on_message, this,
std::placeholders::_1));
app_->register_state_handler(
std::bind(&big_payload_test_service::on_state, this,
std::placeholders::_1));
+ return true;
}
void big_payload_test_service::start()
@@ -43,6 +60,7 @@ void big_payload_test_service::start()
void big_payload_test_service::stop()
{
VSOMEIP_INFO << "Stopping...";
+ stop_offer();
app_->clear_all_handler();
app_->stop();
}
@@ -52,14 +70,14 @@ void big_payload_test_service::join_offer_thread()
offer_thread_.join();
}
-void big_payload_test_service::offer()
-{
- app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+void big_payload_test_service::offer() {
+ app_->offer_service(service_id_,
+ big_payload_test::TEST_SERVICE_INSTANCE_ID);
}
-void big_payload_test_service::stop_offer()
-{
- app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+void big_payload_test_service::stop_offer() {
+ app_->stop_offer_service(service_id_,
+ big_payload_test::TEST_SERVICE_INSTANCE_ID);
}
void big_payload_test_service::on_state(vsomeip::state_type_e _state)
@@ -93,7 +111,14 @@ void big_payload_test_service::on_message(const std::shared_ptr<vsomeip::message
<< _request->get_session() << "] size: " << std::dec
<< _request->get_payload()->get_length();
- ASSERT_EQ(_request->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE);
+ static vsomeip::session_t last_session(0);
+ ASSERT_GT(_request->get_session(), last_session);
+ last_session = _request->get_session();
+ if (test_mode_ == big_payload_test::test_mode::RANDOM) {
+ ASSERT_LT(_request->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE_RANDOM);
+ } else {
+ ASSERT_EQ(_request->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE);
+ }
bool check(true);
vsomeip::length_t len = _request->get_payload()->get_length();
vsomeip::byte_t* datap = _request->get_payload()->get_data();
@@ -113,16 +138,33 @@ void big_payload_test_service::on_message(const std::shared_ptr<vsomeip::message
std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get()
->create_payload();
std::vector<vsomeip::byte_t> its_payload_data;
- for (unsigned int i = 0; i < big_payload_test::BIG_PAYLOAD_SIZE; ++i) {
- its_payload_data.push_back(big_payload_test::DATA_SERVICE_TO_CLIENT);
+ if (test_mode_ == big_payload_test::test_mode::RANDOM) {
+ its_payload_data.assign(std::rand() % big_payload_test::BIG_PAYLOAD_SIZE_RANDOM,
+ big_payload_test::DATA_SERVICE_TO_CLIENT);
+ } else if (test_mode_ == big_payload_test::test_mode::LIMITED) {
+ if (number_of_received_messages_ % 2) {
+ // try to send to big response for half of the received messsages.
+ // this way the client will only get replies for a fourth of his sent
+ // requests as he tries to sent to big data for every second request
+ // as well
+ its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE + 3,
+ big_payload_test::DATA_SERVICE_TO_CLIENT);
+ } else {
+ its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE,
+ big_payload_test::DATA_SERVICE_TO_CLIENT);
+ }
+ } else {
+ its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE,
+ big_payload_test::DATA_SERVICE_TO_CLIENT);
}
+
its_payload->set_data(its_payload_data);
its_response->set_payload(its_payload);
app_->send(its_response, true);
- if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND) {
- ASSERT_EQ(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND, number_of_received_messages_);
+ if(number_of_received_messages_ == expected_messages_) {
+ ASSERT_EQ(expected_messages_, number_of_received_messages_);
std::lock_guard<std::mutex> its_lock(mutex_);
blocked_ = true;
condition_.notify_one();
@@ -131,34 +173,50 @@ void big_payload_test_service::on_message(const std::shared_ptr<vsomeip::message
void big_payload_test_service::run()
{
- std::unique_lock<std::mutex> its_lock(mutex_);
- while (!blocked_) {
- condition_.wait(its_lock);
- }
+ {
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_) {
+ condition_.wait(its_lock);
+ }
- offer();
+ offer();
- // wait for shutdown
- blocked_ = false;
- while (!blocked_) {
- condition_.wait(its_lock);
+ // wait for shutdown
+ blocked_ = false;
+ while (!blocked_) {
+ condition_.wait(its_lock);
+ }
}
std::this_thread::sleep_for(std::chrono::seconds(3));
- app_->stop();
+ if (test_mode_ == big_payload_test::test_mode::LIMITED) {
+ ASSERT_EQ(number_of_received_messages_, expected_messages_);
+ }
+ stop();
}
+static big_payload_test::test_mode test_mode(big_payload_test::test_mode::UNKNOWN);
+
+
TEST(someip_big_payload_test, receive_ten_messages_and_send_reply)
{
- big_payload_test_service test_service;
- test_service.init();
- test_service.start();
- test_service.join_offer_thread();
+ big_payload_test_service test_service(test_mode);
+ if (test_service.init()) {
+ test_service.start();
+ test_service.join_offer_thread();
+ }
}
#ifndef WIN32
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
+ if (argc > 1) {
+ if (std::string("RANDOM") == std::string(argv[1])) {
+ test_mode = big_payload_test::test_mode::RANDOM;
+ } else if (std::string("LIMITED") == std::string(argv[1])) {
+ test_mode = big_payload_test::test_mode::LIMITED;
+ }
+ }
return RUN_ALL_TESTS();
}
#endif
diff --git a/test/big_payload_tests/big_payload_test_service.hpp b/test/big_payload_tests/big_payload_test_service.hpp
index 58d070d..0862370 100644
--- a/test/big_payload_tests/big_payload_test_service.hpp
+++ b/test/big_payload_tests/big_payload_test_service.hpp
@@ -14,13 +14,15 @@
#include <condition_variable>
#include <functional>
-#include "../someip_test_globals.hpp"
+#include "big_payload_test_globals.hpp"
+#include "../../implementation/logging/include/logger.hpp"
+
class big_payload_test_service
{
public:
- big_payload_test_service();
- void init();
+ big_payload_test_service(big_payload_test::test_mode _test_mode);
+ bool init();
void start();
void stop();
void offer();
@@ -36,8 +38,11 @@ private:
std::mutex mutex_;
std::condition_variable condition_;
bool blocked_;
+ big_payload_test::test_mode test_mode_;
std::uint32_t number_of_received_messages_;
std::thread offer_thread_;
+ std::uint32_t expected_messages_;
+ vsomeip::service_t service_id_;
};
#endif /* BIGPAYLOADTESTSERVICE_HPP_ */
diff --git a/test/big_payload_tests/big_payload_test_service_external_start.sh b/test/big_payload_tests/big_payload_test_service_external_start.sh
index 361f106..8fd7120 100755
--- a/test/big_payload_tests/big_payload_test_service_external_start.sh
+++ b/test/big_payload_tests/big_payload_test_service_external_start.sh
@@ -4,7 +4,18 @@
# 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/.
+if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" ]]
+then
+ echo "The only allowed parameter to this script is RANDOM or LIMITED."
+ echo "Like $0 RANDOM"
+ exit 1
+fi
+
# Start the service
-export VSOMEIP_APPLICATION_NAME=big_payload_test_service
-export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service.json
-./big_payload_test_service
+if [[ $# -gt 0 && $1 == "RANDOM" ]]
+then
+ export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_random.json
+else
+ export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service.json
+fi
+./big_payload_test_service $1
diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in
new file mode 100644
index 0000000..cc93b48
--- /dev/null
+++ b/test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in
@@ -0,0 +1,31 @@
+{
+ "unicast":"@TEST_IP_MASTER@",
+ "netmask":"255.255.255.0",
+ "logging":
+ {
+ "level":"info",
+ "console":"true",
+ "file":
+ {
+ "enable":"true",
+ "path":"/var/log/vsomeip.log"
+ },
+ "dlt":"true"
+ },
+ "applications":
+ [
+ {
+ "name":"big_payload_test_client",
+ "id":"0x1343"
+ }
+ ],
+ "buffer-shrink-threshold" : "2",
+ "routing":"big_payload_test_client",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.244.224.245",
+ "port":"30490",
+ "protocol":"udp"
+ }
+}
diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_service.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_service.json.in
index a932d82..c17c688 100644
--- a/test/big_payload_tests/conf/big_payload_test_tcp_service.json.in
+++ b/test/big_payload_tests/conf/big_payload_test_tcp_service.json.in
@@ -22,7 +22,25 @@
[
{
"service":"0x1234",
- "instance":"0x5678",
+ "instance":"0x01",
+ "reliable":
+ {
+ "port":"30509",
+ "enable-magic-cookies":"false"
+ }
+ },
+ {
+ "service":"0x1235",
+ "instance":"0x01",
+ "reliable":
+ {
+ "port":"30509",
+ "enable-magic-cookies":"false"
+ }
+ },
+ {
+ "service":"0x1236",
+ "instance":"0x01",
"reliable":
{
"port":"30509",
diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in
new file mode 100644
index 0000000..e607018
--- /dev/null
+++ b/test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in
@@ -0,0 +1,60 @@
+{
+ "unicast":"@TEST_IP_SLAVE@",
+ "logging":
+ {
+ "level":"debug",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+ "dlt":"false"
+ },
+ "applications":
+ [
+ {
+ "name":"big_payload_test_service",
+ "id":"0x1277"
+ }
+ ],
+ "services":
+ [
+ {
+ "service":"0x1234",
+ "instance":"0x01",
+ "reliable":
+ {
+ "port":"30509",
+ "enable-magic-cookies":"false"
+ }
+ },
+ {
+ "service":"0x1235",
+ "instance":"0x01",
+ "reliable":
+ {
+ "port":"30509",
+ "enable-magic-cookies":"false"
+ }
+ },
+ {
+ "service":"0x1236",
+ "instance":"0x01",
+ "reliable":
+ {
+ "port":"30509",
+ "enable-magic-cookies":"false"
+ }
+ }
+ ],
+ "buffer-shrink-threshold" : "2",
+ "routing":"big_payload_test_service",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.244.224.245",
+ "port":"30490",
+ "protocol":"udp"
+ }
+}
diff --git a/test/client_id_tests/client_id_test_master_starter.sh b/test/client_id_tests/client_id_test_master_starter.sh
index 6b4e53b..ef74c72 100755
--- a/test/client_id_tests/client_id_test_master_starter.sh
+++ b/test/client_id_tests/client_id_test_master_starter.sh
@@ -26,17 +26,24 @@ FAIL=0
export VSOMEIP_APPLICATION_NAME=client_id_test_service_one
export VSOMEIP_CONFIGURATION=$1
./client_id_test_service 1 &
+CLIENT_ID_PIDS[1]=$!
export VSOMEIP_APPLICATION_NAME=client_id_test_service_two
export VSOMEIP_CONFIGURATION=$1
./client_id_test_service 2 &
+CLIENT_ID_PIDS[2]=$!
export VSOMEIP_APPLICATION_NAME=client_id_test_service_three
export VSOMEIP_CONFIGURATION=$1
./client_id_test_service 3 &
+CLIENT_ID_PIDS[3]=$!
sleep 1
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting client id test on slave LXC"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE\"" &
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -50,13 +57,16 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# Wait until client and service are finished
-for job in $(jobs -p)
+for client_pid in "${CLIENT_ID_PIDS[@]}"
do
- # Fail gets incremented if either client or service exit
- # with a non-zero exit code
- wait $job || ((FAIL+=1))
+ if [ -n "$client_pid" ]; then
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ wait "$client_pid" || ((FAIL+=1))
+ fi
done
# Check if both exited successfully
diff --git a/test/client_id_tests/client_id_test_service.cpp b/test/client_id_tests/client_id_test_service.cpp
index 6572d74..7e1d66d 100644
--- a/test/client_id_tests/client_id_test_service.cpp
+++ b/test/client_id_tests/client_id_test_service.cpp
@@ -30,8 +30,8 @@ public:
stopped_(false),
stop_thread_(std::bind(&client_id_test_service::wait_for_stop, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&client_id_test_service::on_state, this,
diff --git a/test/client_id_tests/client_id_test_utility.cpp b/test/client_id_tests/client_id_test_utility.cpp
new file mode 100644
index 0000000..610a087
--- /dev/null
+++ b/test/client_id_tests/client_id_test_utility.cpp
@@ -0,0 +1,447 @@
+// Copyright (C) 2014-2016 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 <gtest/gtest.h>
+
+#include <unistd.h> // for access()
+#include <sstream>
+
+#include "../../implementation/utility/include/utility.hpp"
+#include "../../implementation/configuration/include/configuration.hpp"
+#include <vsomeip/constants.hpp>
+
+
+using namespace vsomeip;
+
+static const std::string APPLICATION_NAME_ROUTING_MANAGER = "vsomeipd";
+
+static const std::string APPLICATION_NAME_NOT_PREDEFINED = "test-application-name";
+
+static const std::string APPLICATION_IN_NAME = "client_id_test_utility_service_in";
+static const vsomeip::client_t APPLICATION_IN_CLIENT_ID = 0x6311;
+
+static const std::string APPLICATION_IN_NAME_TWO = "client_id_test_utility_service_in_two";
+static const vsomeip::client_t APPLICATION_IN_CLIENT_ID_TWO = 0x6312;
+
+static const std::string APPLICATION_OUT_LOW_NAME = "client_id_test_utility_service_out_low";
+static const vsomeip::client_t APPLICATION_OUT_LOW_CLIENT_ID = 0x6011;
+
+static const std::string APPLICATION_OUT_HIGH_NAME = "client_id_test_utility_service_out_high";
+static const vsomeip::client_t APPLICATION_OUT_HIGH_CLIENT_ID = 0x6411;
+
+
+
+class client_id_utility_test: public ::testing::Test {
+public:
+ client_id_utility_test() :
+ configuration_(vsomeip::configuration::get()),
+ client_id_routing_manager_(0x0) {
+ }
+protected:
+ virtual void SetUp() {
+ ASSERT_FALSE(file_exist(std::string("/dev/shm").append(VSOMEIP_SHM_NAME)));
+ ASSERT_TRUE(static_cast<bool>(configuration_));
+ configuration_->load(APPLICATION_NAME_ROUTING_MANAGER);
+
+ utility::auto_configuration_init(configuration_);
+ EXPECT_TRUE(file_exist(std::string("/dev/shm").append(VSOMEIP_SHM_NAME)));
+
+ client_id_routing_manager_ = utility::request_client_id(
+ configuration_, APPLICATION_NAME_ROUTING_MANAGER, 0x0);
+ EXPECT_EQ(0x6301, client_id_routing_manager_);
+ EXPECT_TRUE(utility::is_routing_manager_host(client_id_routing_manager_));
+ }
+
+ virtual void TearDown() {
+ utility::auto_configuration_exit(client_id_routing_manager_);
+ EXPECT_FALSE(file_exist(std::string("/dev/shm").append(VSOMEIP_SHM_NAME)));
+ }
+
+ bool file_exist(const std::string &_path) {
+ const int ret = ::access(_path.c_str(), F_OK);
+ if (ret == -1 && errno == ENOENT) {
+ return false;
+ } else if (ret == -1) {
+ std::stringstream its_stream;
+ its_stream << "file_exists (" << _path << "): ";
+ std::perror(its_stream.str().c_str());
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+protected:
+ std::shared_ptr<configuration> configuration_;
+ vsomeip::client_t client_id_routing_manager_;
+};
+
+TEST_F(client_id_utility_test, request_release_client_id) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6302, its_client_id);
+
+ utility::release_client_id(its_client_id);
+}
+
+TEST_F(client_id_utility_test, request_client_id_twice) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6302, its_client_id);
+
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6303, its_client_id_2);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id_2);
+}
+
+TEST_F(client_id_utility_test, release_unknown_client_id) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6302, its_client_id);
+
+ utility::release_client_id(0x4711);
+ utility::release_client_id(its_client_id);
+
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6303, its_client_id_2);
+ utility::release_client_id(its_client_id_2);
+}
+
+TEST_F(client_id_utility_test, release_client_id_twice)
+{
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6302, its_client_id);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id);
+
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6303, its_client_id_2);
+ utility::release_client_id(its_client_id_2);
+}
+
+TEST_F(client_id_utility_test, ensure_preconfigured_client_ids_not_used_for_autoconfig)
+{
+ const std::uint8_t limit = APPLICATION_IN_CLIENT_ID & 0xFF;
+ std::vector<client_t> its_client_ids;
+ for (int i = 0; i < limit + 10; i++ ) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_NE(ILLEGAL_CLIENT, its_client_id);
+ if (its_client_id != ILLEGAL_CLIENT) {
+ its_client_ids.push_back(its_client_id);
+ EXPECT_NE(APPLICATION_IN_CLIENT_ID, its_client_id);
+ } else {
+ ADD_FAILURE() << "Received ILLEGAL_CLIENT "
+ << static_cast<std::uint32_t>(i);
+ }
+ }
+
+ // release all
+ for (const client_t c : its_client_ids) {
+ utility::release_client_id(c);
+ }
+}
+
+TEST_F(client_id_utility_test,
+ ensure_preconfigured_client_ids_in_diagnosis_range_dont_influence_autoconfig_client_ids)
+{
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6302, its_client_id);
+
+ client_t its_client_id2 = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME, APPLICATION_IN_CLIENT_ID);
+ EXPECT_EQ(APPLICATION_IN_CLIENT_ID, its_client_id2);
+
+ client_t its_client_id3 = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME_TWO, APPLICATION_IN_CLIENT_ID_TWO);
+ EXPECT_EQ(APPLICATION_IN_CLIENT_ID_TWO, its_client_id3);
+
+
+ client_t its_client_id4 = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6303, its_client_id4);
+
+ client_t its_client_id5 = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(0x6304, its_client_id5);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id2);
+ utility::release_client_id(its_client_id3);
+ utility::release_client_id(its_client_id4);
+ utility::release_client_id(its_client_id5);
+}
+
+TEST_F(client_id_utility_test,
+ request_predefined_client_id_in_diagnosis_range) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME, APPLICATION_IN_CLIENT_ID);
+ EXPECT_EQ(APPLICATION_IN_CLIENT_ID, its_client_id);
+
+ utility::release_client_id(its_client_id);
+}
+
+TEST_F(client_id_utility_test,
+ request_predefined_client_id_in_diagnosis_range_twice) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME, APPLICATION_IN_CLIENT_ID);
+ EXPECT_EQ(APPLICATION_IN_CLIENT_ID, its_client_id);
+
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME, APPLICATION_IN_CLIENT_ID);
+ EXPECT_EQ(0x6302, its_client_id_2);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id_2);
+}
+
+TEST_F(client_id_utility_test,
+ request_different_client_id_with_predefined_app_name_in_diagnosis_range) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME, APPLICATION_IN_CLIENT_ID + 1u);
+ // has to get predefined client id although other was requested
+ EXPECT_EQ(APPLICATION_IN_CLIENT_ID, its_client_id);
+
+ // predefined in json is now already used and requested should be assigned
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME, APPLICATION_IN_CLIENT_ID + 1u);
+ EXPECT_EQ(APPLICATION_IN_CLIENT_ID + 1u, its_client_id_2);
+
+ client_t its_client_id_3 = utility::request_client_id(configuration_,
+ APPLICATION_IN_NAME, APPLICATION_IN_CLIENT_ID);
+ EXPECT_EQ(0x6302, its_client_id_3);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id_2);
+ utility::release_client_id(its_client_id_3);
+}
+
+TEST_F(client_id_utility_test,
+ request_predefined_client_id_outside_diagnosis_range_low) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_OUT_LOW_NAME, APPLICATION_OUT_LOW_CLIENT_ID);
+ EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID, its_client_id);
+
+ utility::release_client_id(its_client_id);
+}
+
+TEST_F(client_id_utility_test,
+ request_predefined_client_id_outside_diagnosis_range_low_twice) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_OUT_LOW_NAME, APPLICATION_OUT_LOW_CLIENT_ID);
+ EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID, its_client_id);
+
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_OUT_LOW_NAME, APPLICATION_OUT_LOW_CLIENT_ID);
+ EXPECT_EQ(0x6302, its_client_id_2);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id_2);
+}
+
+TEST_F(client_id_utility_test,
+ request_different_client_id_with_predefined_app_name_outside_diagnosis_range_low) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_OUT_LOW_NAME, APPLICATION_OUT_LOW_CLIENT_ID + 1u);
+ // has to get predefined client id although other was requested
+ EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID, its_client_id);
+
+ // predefined in json is now already used and requested should be assigned
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_OUT_LOW_NAME, APPLICATION_OUT_LOW_CLIENT_ID + 1u);
+ EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID + 1u, its_client_id_2);
+
+ client_t its_client_id_3 = utility::request_client_id(configuration_,
+ APPLICATION_OUT_LOW_NAME, APPLICATION_OUT_LOW_CLIENT_ID);
+ EXPECT_EQ(0x6302, its_client_id_3);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id_2);
+ utility::release_client_id(its_client_id_3);
+}
+
+TEST_F(client_id_utility_test,
+ request_predefined_client_id_outside_diagnosis_range_high) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_OUT_HIGH_NAME, APPLICATION_OUT_HIGH_CLIENT_ID);
+ EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID, its_client_id);
+
+ utility::release_client_id(its_client_id);
+}
+
+TEST_F(client_id_utility_test,
+ request_predefined_client_id_outside_diagnosis_range_high_twice) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_OUT_HIGH_NAME, APPLICATION_OUT_HIGH_CLIENT_ID);
+ EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID, its_client_id);
+
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_OUT_HIGH_NAME, APPLICATION_OUT_HIGH_CLIENT_ID);
+ EXPECT_EQ(0x6302, its_client_id_2);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id_2);
+}
+
+TEST_F(client_id_utility_test,
+ request_different_client_id_with_predefined_app_name_outside_diagnosis_range_high) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_OUT_HIGH_NAME, APPLICATION_OUT_HIGH_CLIENT_ID + 1u);
+ // has to get predefined client id although other was requested
+ EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID, its_client_id);
+
+ // predefined in json is now already used and requested should be assigned
+ client_t its_client_id_2 = utility::request_client_id(configuration_,
+ APPLICATION_OUT_HIGH_NAME, APPLICATION_OUT_HIGH_CLIENT_ID + 1u);
+ EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID + 1u, its_client_id_2);
+
+ client_t its_client_id_3 = utility::request_client_id(configuration_,
+ APPLICATION_OUT_HIGH_NAME, APPLICATION_OUT_HIGH_CLIENT_ID);
+ EXPECT_EQ(0x6302, its_client_id_3);
+
+ utility::release_client_id(its_client_id);
+ utility::release_client_id(its_client_id_2);
+ utility::release_client_id(its_client_id_3);
+}
+
+
+TEST_F(client_id_utility_test, exhaust_client_id_range_sequential) {
+ std::vector<client_t> its_client_ids;
+
+ // -1 for the routing manager, -2 as two predefined client IDs are present
+ // in the json file which aren't assigned via autoconfiguration
+ std::uint8_t max_allowed_clients = 0xFF - 3;
+ // acquire maximum amount of client IDs
+ for (std::uint8_t i = 0; i < max_allowed_clients; i++) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_NE(ILLEGAL_CLIENT, its_client_id);
+ if (its_client_id != ILLEGAL_CLIENT) {
+ its_client_ids.push_back(its_client_id);
+ } else {
+ ADD_FAILURE() << "Received ILLEGAL_CLIENT "
+ << static_cast<std::uint32_t>(i);
+ }
+ }
+
+ // check limit is reached
+ client_t its_illegal_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(ILLEGAL_CLIENT, its_illegal_client_id);
+
+ // release all
+ for (const client_t c : its_client_ids) {
+ utility::release_client_id(c);
+ }
+ its_client_ids.clear();
+ its_illegal_client_id = 0xFFFF;
+
+ // One more time!
+
+ // acquire maximum amount of client IDs
+ for (std::uint8_t i = 0; i < max_allowed_clients; i++) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_NE(ILLEGAL_CLIENT, its_client_id);
+ if (its_client_id != ILLEGAL_CLIENT) {
+ its_client_ids.push_back(its_client_id);
+ } else {
+ ADD_FAILURE() << "Received ILLEGAL_CLIENT "
+ << static_cast<std::uint32_t>(i);
+ }
+ }
+
+ // check limit is reached
+ its_illegal_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(ILLEGAL_CLIENT, its_illegal_client_id);
+
+ // release all
+ for (const client_t c : its_client_ids) {
+ utility::release_client_id(c);
+ }
+ }
+
+TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented) {
+ std::vector<client_t> its_client_ids;
+
+ // -1 for the routing manager, -2 as two predefined client IDs are present
+ // in the json file which aren't assigned via autoconfiguration
+ std::uint8_t max_allowed_clients = 0xFF - 3;
+ // acquire maximum amount of client IDs
+ for (std::uint8_t i = 0; i < max_allowed_clients; i++) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_NE(ILLEGAL_CLIENT, its_client_id);
+ if (its_client_id != ILLEGAL_CLIENT) {
+ its_client_ids.push_back(its_client_id);
+ } else {
+ ADD_FAILURE() << "Received ILLEGAL_CLIENT "
+ << static_cast<std::uint32_t>(i);
+ }
+ }
+
+ // check limit is reached
+ client_t its_illegal_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(ILLEGAL_CLIENT, its_illegal_client_id);
+
+ // release every second requested client ID
+ std::vector<client_t> its_released_client_ids;
+ for (size_t i = 0; i < its_client_ids.size(); i++ ) {
+ if (i % 2) {
+ its_released_client_ids.push_back(its_client_ids[i]);
+ utility::release_client_id(its_client_ids[i]);
+ }
+ }
+ for (const client_t c : its_released_client_ids) {
+ for (auto it = its_client_ids.begin(); it != its_client_ids.end(); ) {
+ if (*it == c) {
+ it = its_client_ids.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ // acquire client IDs up to the maximum allowed amount again
+ for (std::uint8_t i = 0; i < its_released_client_ids.size(); i++) {
+ client_t its_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_NE(ILLEGAL_CLIENT, its_client_id);
+ if (its_client_id != ILLEGAL_CLIENT) {
+ its_client_ids.push_back(its_client_id);
+ } else {
+ ADD_FAILURE() << "Received ILLEGAL_CLIENT "
+ << static_cast<std::uint32_t>(i);
+ }
+ }
+
+ // check limit is reached
+ its_illegal_client_id = 0xFFFF;
+ its_illegal_client_id = utility::request_client_id(configuration_,
+ APPLICATION_NAME_NOT_PREDEFINED, 0x0);
+ EXPECT_EQ(ILLEGAL_CLIENT, its_illegal_client_id);
+
+ // release all
+ for (const client_t c : its_client_ids) {
+ utility::release_client_id(c);
+ }
+}
+
+#ifndef WIN32
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/client_id_tests/client_id_test_utility.json b/test/client_id_tests/client_id_test_utility.json
new file mode 100644
index 0000000..ea0aaa0
--- /dev/null
+++ b/test/client_id_tests/client_id_test_utility.json
@@ -0,0 +1,38 @@
+{
+ "unicast":"127.0.0.1",
+ "logging":
+ {
+ "level":"warning",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+
+ "dlt":"false"
+ },
+ "diagnosis" : "0x63",
+ "applications":
+ [
+ {
+ "name":"client_id_test_utility_service_in",
+ "id":"0x6311"
+ },
+ {
+ "name":"client_id_test_utility_service_in_two",
+ "id":"0x6312"
+ },
+ {
+ "name":"client_id_test_utility_service_out_low",
+ "id":"0x6011"
+ },
+
+ {
+ "name":"client_id_test_utility_service_out_high",
+ "id":"0x6411"
+ }
+ ],
+
+ "routing":"vsomeipd"
+} \ No newline at end of file
diff --git a/test/cpu_load_tests/cpu_load_test_client.cpp b/test/cpu_load_tests/cpu_load_test_client.cpp
index dd732e3..5935774 100644
--- a/test/cpu_load_tests/cpu_load_test_client.cpp
+++ b/test/cpu_load_tests/cpu_load_test_client.cpp
@@ -53,8 +53,8 @@ public:
wait_for_all_msg_acknowledged_(true),
sender_(std::bind(&cpu_load_test_client::run, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
diff --git a/test/cpu_load_tests/cpu_load_test_master_starter.sh b/test/cpu_load_tests/cpu_load_test_master_starter.sh
index bc135fc..ddcfa3d 100755
--- a/test/cpu_load_tests/cpu_load_test_master_starter.sh
+++ b/test/cpu_load_tests/cpu_load_test_master_starter.sh
@@ -14,9 +14,13 @@ FAIL=0
export VSOMEIP_CONFIGURATION=cpu_load_test_client_master.json
./cpu_load_test_client --protocol UDP --calls 1000 &
-
+TEST_CLIENT_PID=$!
sleep 1
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting cpu load test on slave LXC"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./cpu_load_test_slave_starter.sh"' &
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -32,19 +36,18 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
+
+# Fail gets incremented if either client or service exit
+# with a non-zero exit code
+wait $TEST_CLIENT_PID || FAIL=$(($FAIL+1))
-for job in $(jobs -p)
-do
- # Fail gets incremented if either client or service exit
- # with a non-zero exit code
- wait $job || FAIL=$(($FAIL+1))
-done
sleep 4
cat <<End-of-message
*******************************************************************************
*******************************************************************************
-** Now switching roles and running service on this host
+** Now switching roles and running service on this host (master)
*******************************************************************************
*******************************************************************************
End-of-message
@@ -53,6 +56,7 @@ export VSOMEIP_CONFIGURATION=cpu_load_test_service_master.json
./cpu_load_test_service &
sleep 1
+# now we can wait to all jobs to finish
for job in $(jobs -p)
do
# Fail gets incremented if either client or service exit
diff --git a/test/cpu_load_tests/cpu_load_test_service.cpp b/test/cpu_load_tests/cpu_load_test_service.cpp
index 67b4ef9..f8fbde3 100644
--- a/test/cpu_load_tests/cpu_load_test_service.cpp
+++ b/test/cpu_load_tests/cpu_load_test_service.cpp
@@ -36,13 +36,13 @@ public:
{
}
- void init()
+ bool init()
{
std::lock_guard<std::mutex> its_lock(mutex_);
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_message_handler(cpu_load_test::service_id,
cpu_load_test::instance_id, cpu_load_test::method_id,
@@ -64,6 +64,7 @@ public:
app_->register_state_handler(
std::bind(&cpu_load_test_service::on_state, this,
std::placeholders::_1));
+ return true;
}
void start()
@@ -189,9 +190,10 @@ private:
TEST(someip_payload_test, send_response_for_every_request)
{
cpu_load_test_service test_service;
- test_service.init();
- test_service.start();
- test_service.join_offer_thread();
+ if (test_service.init()) {
+ test_service.start();
+ test_service.join_offer_thread();
+ }
}
#ifndef WIN32
diff --git a/test/cpu_load_tests/cpu_load_test_slave_starter.sh b/test/cpu_load_tests/cpu_load_test_slave_starter.sh
index e6731b7..9c68c48 100755
--- a/test/cpu_load_tests/cpu_load_test_slave_starter.sh
+++ b/test/cpu_load_tests/cpu_load_test_slave_starter.sh
@@ -26,7 +26,7 @@ done
cat <<End-of-message
*******************************************************************************
*******************************************************************************
-** Now switching roles and running client on this host
+** Now switching roles and running client on this host (slave)
*******************************************************************************
*******************************************************************************
End-of-message
diff --git a/test/header_factory_tests/header_factory_test_client.cpp b/test/header_factory_tests/header_factory_test_client.cpp
index 2e08cbc..3870c17 100644
--- a/test/header_factory_tests/header_factory_test_client.cpp
+++ b/test/header_factory_tests/header_factory_test_client.cpp
@@ -18,11 +18,11 @@ header_factory_test_client::header_factory_test_client(bool _use_tcp) :
{
}
-void header_factory_test_client::init()
+bool header_factory_test_client::init()
{
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_state_handler(
@@ -39,6 +39,7 @@ void header_factory_test_client::init()
std::bind(&header_factory_test_client::on_availability, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
+ return true;
}
void header_factory_test_client::start()
@@ -155,9 +156,10 @@ TEST(someip_header_factory_test, send_message_ten_times_test)
{
bool use_tcp = false;
header_factory_test_client test_client_(use_tcp);
- test_client_.init();
- test_client_.start();
- test_client_.join_sender_thread();
+ if (test_client_.init()) {
+ test_client_.start();
+ test_client_.join_sender_thread();
+ }
}
#ifndef WIN32
diff --git a/test/header_factory_tests/header_factory_test_client.hpp b/test/header_factory_tests/header_factory_test_client.hpp
index 1b96edd..911c754 100644
--- a/test/header_factory_tests/header_factory_test_client.hpp
+++ b/test/header_factory_tests/header_factory_test_client.hpp
@@ -21,7 +21,7 @@ class header_factory_test_client
{
public:
header_factory_test_client(bool _use_tcp);
- void init();
+ bool init();
void start();
void stop();
void join_sender_thread();
diff --git a/test/header_factory_tests/header_factory_test_service.cpp b/test/header_factory_tests/header_factory_test_service.cpp
index 0ff516f..9a06762 100644
--- a/test/header_factory_tests/header_factory_test_service.cpp
+++ b/test/header_factory_tests/header_factory_test_service.cpp
@@ -17,13 +17,13 @@ header_factory_test_service::header_factory_test_service(bool _use_static_routin
{
}
-void header_factory_test_service::init()
+bool header_factory_test_service::init()
{
std::lock_guard<std::mutex> its_lock(mutex_);
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
@@ -35,6 +35,7 @@ void header_factory_test_service::init()
std::placeholders::_1));
VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF");
+ return true;
}
void header_factory_test_service::start()
@@ -153,9 +154,10 @@ TEST(someip_header_factory_test, reveice_message_ten_times_test)
{
bool use_static_routing = true;
header_factory_test_service test_service(use_static_routing);
- test_service.init();
- test_service.start();
- test_service.join_offer_thread();
+ if (test_service.init()) {
+ test_service.start();
+ test_service.join_offer_thread();
+ }
}
#ifndef WIN32
diff --git a/test/header_factory_tests/header_factory_test_service.hpp b/test/header_factory_tests/header_factory_test_service.hpp
index b58a29b..a28d040 100644
--- a/test/header_factory_tests/header_factory_test_service.hpp
+++ b/test/header_factory_tests/header_factory_test_service.hpp
@@ -20,7 +20,7 @@ class header_factory_test_service
{
public:
header_factory_test_service(bool _use_static_routing);
- void init();
+ bool init();
void start();
void stop();
void offer();
diff --git a/test/initial_event_tests/initial_event_test_availability_checker.cpp b/test/initial_event_tests/initial_event_test_availability_checker.cpp
index 34c20c1..69ae6ee 100644
--- a/test/initial_event_tests/initial_event_test_availability_checker.cpp
+++ b/test/initial_event_tests/initial_event_test_availability_checker.cpp
@@ -32,8 +32,8 @@ public:
wait_for_stop_(true),
stop_thread_(std::bind(&initial_event_test_availability_checker::wait_for_stop, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&initial_event_test_availability_checker::on_state, this,
diff --git a/test/initial_event_tests/initial_event_test_client.cpp b/test/initial_event_tests/initial_event_test_client.cpp
index d525632..caa79cb 100644
--- a/test/initial_event_tests/initial_event_test_client.cpp
+++ b/test/initial_event_tests/initial_event_test_client.cpp
@@ -34,8 +34,8 @@ public:
wait_for_stop_(true),
stop_thread_(std::bind(&initial_event_test_client::wait_for_stop, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&initial_event_test_client::on_state, this,
diff --git a/test/initial_event_tests/initial_event_test_master_starter.sh b/test/initial_event_tests/initial_event_test_master_starter.sh
index 3273817..471b973 100755
--- a/test/initial_event_tests/initial_event_test_master_starter.sh
+++ b/test/initial_event_tests/initial_event_test_master_starter.sh
@@ -46,6 +46,11 @@ then
fi
print_starter_message () {
+
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting initial event test on slave LXC with params $PASSED_SUBSCRIPTION_TYPE $CLIENT_JSON_FILE $PASSED_SAME_SERVICE_ID_FLAG"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./initial_event_test_slave_starter.sh $PASSED_SUBSCRIPTION_TYPE $CLIENT_JSON_FILE $PASSED_SAME_SERVICE_ID_FLAG\"" &
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -59,6 +64,7 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
}
# replace master with slave to be able display the correct json file to be used
diff --git a/test/initial_event_tests/initial_event_test_service.cpp b/test/initial_event_tests/initial_event_test_service.cpp
index f02a493..5823a09 100644
--- a/test/initial_event_tests/initial_event_test_service.cpp
+++ b/test/initial_event_tests/initial_event_test_service.cpp
@@ -28,8 +28,8 @@ public:
wait_until_registered_(true),
offer_thread_(std::bind(&initial_event_test_service::run, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&initial_event_test_service::on_state, this,
diff --git a/test/initial_event_tests/initial_event_test_stop_service.cpp b/test/initial_event_tests/initial_event_test_stop_service.cpp
index cd8a34a..a17e0d8 100644
--- a/test/initial_event_tests/initial_event_test_stop_service.cpp
+++ b/test/initial_event_tests/initial_event_test_stop_service.cpp
@@ -34,8 +34,8 @@ public:
stop_thread_(std::bind(&initial_event_test_stop_service::wait_for_stop, this)),
called_other_node_(false) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&initial_event_test_stop_service::on_state, this,
diff --git a/test/magic_cookies_tests/magic_cookies_test_client.cpp b/test/magic_cookies_tests/magic_cookies_test_client.cpp
index 35eba2e..8be1eaf 100644
--- a/test/magic_cookies_tests/magic_cookies_test_client.cpp
+++ b/test/magic_cookies_tests/magic_cookies_test_client.cpp
@@ -9,6 +9,8 @@
#include <memory>
#include <thread>
+#include <gtest/gtest.h>
+
#include <vsomeip/vsomeip.hpp>
#include "../someip_test_globals.hpp"
@@ -21,13 +23,18 @@ public:
: app_(new vsomeip::application_impl("")),
is_available_(false),
is_blocked_(false),
+ sent_messages_good_(8),
+ sent_messages_bad_(7),
+ received_responses_(0),
+ received_errors_(0),
+ wait_for_replies_(true),
runner_(std::bind(&magic_cookies_test_client::run, this)) {
}
void init() {
VSOMEIP_INFO << "Initializing...";
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
+ ADD_FAILURE() << "Couldn't initialize application";
exit(EXIT_FAILURE);
}
@@ -99,6 +106,7 @@ public:
<< "/"
<< std::setw(4) << std::setfill('0') << std::hex << _response->get_session()
<< "]";
+ received_responses_++;
} else if (_response->get_return_code() == vsomeip::return_code_e::E_MALFORMED_MESSAGE) {
VSOMEIP_INFO << "Received an error message from Service ["
<< std::setw(4) << std::setfill('0') << std::hex << _response->get_service()
@@ -109,6 +117,13 @@ public:
<< "/"
<< std::setw(4) << std::setfill('0') << std::hex << _response->get_session()
<< "]";
+ received_errors_++;
+ }
+ if (received_errors_ == sent_messages_bad_
+ && received_responses_ == sent_messages_good_) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_for_replies_ = false;
+ condition_.notify_one();
}
}
@@ -118,7 +133,13 @@ public:
void run() {
std::unique_lock< std::mutex > its_lock(mutex_);
- while (!is_blocked_) condition_.wait(its_lock);
+ while (!is_blocked_) {
+ if (std::cv_status::timeout ==
+ condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) {
+ GTEST_NONFATAL_FAILURE_("Service didn't become available within 5s.");
+ break;
+ }
+ }
VSOMEIP_INFO << "Running...";
vsomeip::routing_manager *its_routing = app_->get_routing_manager();
@@ -171,7 +192,15 @@ public:
its_good_payload_data[11] = 0x0F;
its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true, true);
- std::this_thread::sleep_for(std::chrono::milliseconds(2000));
+ while (wait_for_replies_) {
+ if(std::cv_status::timeout ==
+ condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) {
+ GTEST_NONFATAL_FAILURE_("Didn't receive all replies/errors in time");
+ break;
+ }
+ }
+ EXPECT_EQ(sent_messages_good_, received_responses_);
+ EXPECT_EQ(sent_messages_bad_, received_errors_);
stop();
}
@@ -181,16 +210,25 @@ private:
std::condition_variable condition_;
bool is_available_;
bool is_blocked_;
+ const std::uint32_t sent_messages_good_;
+ const std::uint32_t sent_messages_bad_;
+ std::atomic<std::uint32_t> received_responses_;
+ std::atomic<std::uint32_t> received_errors_;
+ bool wait_for_replies_;
std::thread runner_;
};
-
-int main() {
+TEST(someip_magic_cookies_test, send_good_and_bad_messages)
+{
magic_cookies_test_client its_client;
its_client.init();
its_client.start();
its_client.join();
- return 0;
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
}
diff --git a/test/magic_cookies_tests/magic_cookies_test_service.cpp b/test/magic_cookies_tests/magic_cookies_test_service.cpp
index 1a186b0..a69084d 100644
--- a/test/magic_cookies_tests/magic_cookies_test_service.cpp
+++ b/test/magic_cookies_tests/magic_cookies_test_service.cpp
@@ -10,6 +10,8 @@
#include <sstream>
#include <thread>
+#include <gtest/gtest.h>
+
#include <vsomeip/vsomeip.hpp>
#include "../someip_test_globals.hpp"
@@ -31,7 +33,7 @@ public:
std::lock_guard<std::mutex> its_lock(mutex_);
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
+ ADD_FAILURE() << "Couldn't initialize application";
exit(EXIT_FAILURE);
}
app_->register_message_handler(
@@ -112,7 +114,11 @@ public:
if (use_static_routing_) {
offer();
while (!blocked_) {
- condition_.wait(its_lock);
+ if(std::cv_status::timeout ==
+ condition_.wait_for(its_lock, std::chrono::seconds(55))) {
+ GTEST_NONFATAL_FAILURE_("Didn't receive all requests within time");
+ break;
+ }
}
std::this_thread::sleep_for(std::chrono::milliseconds(5));
app_->clear_all_handler();
@@ -140,20 +146,22 @@ private:
std::thread offer_thread_;
};
-int main(int argc, char **argv) {
- bool use_static_routing(false);
+static bool use_static_routing = false;
- std::string static_routing_enable("--static-routing");
+TEST(someip_magic_cookies_test, reply_to_good_messages)
+{
+ magic_cookies_test_service its_sample(use_static_routing);
+ its_sample.init();
+ its_sample.start();
+}
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ std::string static_routing_enable("--static-routing");
for (int i = 1; i < argc; i++) {
if (static_routing_enable == argv[i]) {
use_static_routing = true;
}
}
-
- magic_cookies_test_service its_sample(use_static_routing);
- its_sample.init();
- its_sample.start();
-
- return 0;
+ return RUN_ALL_TESTS();
}
diff --git a/test/magic_cookies_tests/magic_cookies_test_starter.sh b/test/magic_cookies_tests/magic_cookies_test_starter.sh
index 57efc67..aba3b0b 100755
--- a/test/magic_cookies_tests/magic_cookies_test_starter.sh
+++ b/test/magic_cookies_tests/magic_cookies_test_starter.sh
@@ -12,6 +12,13 @@
# Display a message to show the user that he must now call the external service
# to finish the test successfully
+
+FAIL=0
+
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting magic cookies test on slave LXC"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./magic_cookies_test_client_start.sh\"" &
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -26,10 +33,25 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# Start the client for magic-cookies test
export VSOMEIP_APPLICATION_NAME=magic_cookies_test_service
export VSOMEIP_CONFIGURATION=magic_cookies_test_service.json
-./magic_cookies_test_service --tcp --static-routing
+./magic_cookies_test_service --tcp --static-routing &
+
+# Wait until client and service are finished
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ wait $job || ((FAIL+=1))
+done
-exit $?
+# Check if client and server both exited successfully
+if [ $FAIL -eq 0 ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/test/offer_tests/conf/offer_test_external_master_starter.sh.in b/test/offer_tests/conf/offer_test_external_master_starter.sh.in
index 9ff40e8..6c9f72b 100755
--- a/test/offer_tests/conf/offer_test_external_master_starter.sh.in
+++ b/test/offer_tests/conf/offer_test_external_master_starter.sh.in
@@ -28,12 +28,21 @@ PID_VSOMEIPD=$!
# Start the services
./offer_test_service 2 &
PID_SERVICE_TWO=$!
+echo "SERVICE_TWO pid $PID_SERVICE_TWO"
./offer_test_client SUBSCRIBE &
CLIENT_PIDS+=($!)
+echo "client pid ${CLIENT_PIDS[0]}"
sleep 1
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "Waiting for 5s"
+ sleep 5
+ echo "starting offer test on slave LXC offer_test_external_slave_starter.sh"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./offer_test_external_slave_starter.sh\"" &
+ echo "remote ssh pid: $!"
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -47,12 +56,13 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
-
+fi
# Wait until all clients and services are finished
for job in ${CLIENT_PIDS[*]} $PID_SERVICE_TWO
do
# Fail gets incremented if a client exits with a non-zero exit code
+ echo "waiting for $job"
wait $job || FAIL=$(($FAIL+1))
done
@@ -60,6 +70,14 @@ done
kill $PID_VSOMEIPD
sleep 1
+# wait for slave to finish
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ echo "[Master] waiting for job $job"
+ wait $job || ((FAIL+=1))
+done
# Rejecting remote offer for which there is already a local offer
# * start application which offers service
@@ -78,9 +96,17 @@ PID_SERVICE_TWO=$!
./offer_test_client SUBSCRIBE &
CLIENT_PIDS+=($!)
+echo "client pid ${CLIENT_PIDS[0]}"
sleep 1
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "Waiting for 5s"
+ sleep 5
+ echo "starting offer test on slave LXC offer_test_external_sd_msg_sender"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./offer_test_external_sd_msg_sender $LXC_TEST_MASTER_IP\"" &
+ echo "remote ssh job id: $!"
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -92,11 +118,13 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# Wait until all clients and services are finished
for job in ${CLIENT_PIDS[*]} $PID_SERVICE_TWO
do
# Fail gets incremented if a client exits with a non-zero exit code
+ echo "waiting for $job"
wait $job || FAIL=$(($FAIL+1))
done
@@ -104,6 +132,14 @@ done
kill $PID_VSOMEIPD
sleep 1
+# wait for slave to finish
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ echo "[Master] waiting for job $job"
+ wait $job || ((FAIL+=1))
+done
# Check if everything went well
if [ $FAIL -eq 0 ]
diff --git a/test/offer_tests/offer_test_client.cpp b/test/offer_tests/offer_test_client.cpp
index d338f13..493c3fa 100644
--- a/test/offer_tests/offer_test_client.cpp
+++ b/test/offer_tests/offer_test_client.cpp
@@ -41,8 +41,8 @@ public:
last_received_response_(std::chrono::steady_clock::now()),
number_received_responses_(0) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&offer_test_client::on_state, this,
diff --git a/test/offer_tests/offer_test_service.cpp b/test/offer_tests/offer_test_service.cpp
index 2396d1a..f06de9e 100644
--- a/test/offer_tests/offer_test_service.cpp
+++ b/test/offer_tests/offer_test_service.cpp
@@ -36,8 +36,8 @@ public:
offer_thread_(std::bind(&offer_test_service::run, this)),
shutdown_method_called_(false) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&offer_test_service::on_state, this,
diff --git a/test/offer_tests/offer_test_service_external.cpp b/test/offer_tests/offer_test_service_external.cpp
index c031587..2f74271 100644
--- a/test/offer_tests/offer_test_service_external.cpp
+++ b/test/offer_tests/offer_test_service_external.cpp
@@ -35,8 +35,8 @@ public:
wait_until_service_available_(true),
offer_thread_(std::bind(&offer_test_service::run, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&offer_test_service::on_state, this,
diff --git a/test/payload_tests/external_local_payload_test_client_external_starter.sh b/test/payload_tests/external_local_payload_test_client_external_starter.sh
index 87a70a6..b675b0a 100755
--- a/test/payload_tests/external_local_payload_test_client_external_starter.sh
+++ b/test/payload_tests/external_local_payload_test_client_external_starter.sh
@@ -56,6 +56,11 @@ SERIVCE_PID=$!
# Display a message to show the user that he must now call the external client
# to finish the test successfully
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting external local payload on slave LXC"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./external_local_payload_test_client_external_start.sh\"" &
+ echo "remote ssh job id: $!"
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -69,6 +74,7 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# The service should listen on a TCP and UDP socket now
sleep 1
@@ -78,12 +84,11 @@ check_tcp_udp_sockets_are_open $SERIVCE_PID 2
# The client remotely shuts down the service if he has successfully transmitted
# all the packets with different payloads. Therefore we can assume that everything
# went well, even if we can only check the exit code of the service here.
-for job in $(jobs -p)
-do
- # Fail gets incremented if either client or service exit
- # with a non-zero exit code
- wait $job || ((FAIL+=1))
-done
+
+# Fail gets incremented if either client or service exit
+# with a non-zero exit code
+wait $SERIVCE_PID || ((FAIL+=1))
+
# Start the service for payload test with tcp
export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service
@@ -100,12 +105,11 @@ check_tcp_udp_sockets_are_open $SERIVCE_PID 2
# The client remotely shuts down the service if he has successfully transmitted
# all the packets with different payloads. Therefore we can assume that everything
# went well, even if we can only check the exit code of the service here.
-for job in $(jobs -p)
-do
- # Fail gets incremented if either client or service exit
- # with a non-zero exit code
- wait $job || ((FAIL+=1))
-done
+
+# Fail gets incremented if either client or service exit
+# with a non-zero exit code
+wait $SERIVCE_PID || ((FAIL+=1))
+
# Check if server exited sucessfully
if [ $FAIL -eq 0 ]
diff --git a/test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh b/test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh
index 1464bf9..bc4ce89 100755
--- a/test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh
+++ b/test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh
@@ -73,6 +73,11 @@ wait $CLIENT_PID || ((FAIL+=1))
# Display a message to show the user that he must now call the external client
# to finish the test successfully
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting external local payload on slave LXC"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./external_local_payload_test_client_external_start.sh\"" &
+ echo "remote ssh job id: $!"
+else
cat <<End-of-message
*******************************************************************************
*******************************************************************************
@@ -86,6 +91,7 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# The service should still listen on a TCP and UDP socket
sleep 1
@@ -95,12 +101,11 @@ check_tcp_udp_sockets_are_open $SERIVCE_PID 2
# The client remotely shuts down the service if he has successfully transmitted
# all the packets with different payloads. Therefore we can assume that everything
# went well, even if we can only check the exit code of the service here.
-for job in $(jobs -p)
-do
- # Fail gets incremented if either client or service exit
- # with a non-zero exit code
- wait $job || ((FAIL+=1))
-done
+
+# Fail gets incremented if either client or service exit
+# with a non-zero exit code
+wait $SERIVCE_PID || ((FAIL+=1))
+
# Start the service for payload test with tcp
export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service
@@ -117,12 +122,10 @@ check_tcp_udp_sockets_are_open $SERIVCE_PID 2
# The client remotely shuts down the service if he has successfully transmitted
# all the packets with different payloads. Therefore we can assume that everything
# went well, even if we can only check the exit code of the service here.
-for job in $(jobs -p)
-do
- # Fail gets incremented if either client or service exit
- # with a non-zero exit code
- wait $job || ((FAIL+=1))
-done
+
+# Fail gets incremented if either client or service exit
+# with a non-zero exit code
+wait $SERIVCE_PID || ((FAIL+=1))
# Check if client and server both exited sucessfully and the service didnt't
# have any open TCP/UDP sockets
diff --git a/test/payload_tests/local_payload_test_huge_payload_starter.sh b/test/payload_tests/local_payload_test_huge_payload_starter.sh
new file mode 100755
index 0000000..07cc372
--- /dev/null
+++ b/test/payload_tests/local_payload_test_huge_payload_starter.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# Copyright (C) 2015-2016 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/.
+
+# Purpose: This script is needed to start the client and service with
+# one command. This is necessary as ctest - which is used to run the
+# tests - isn't able to start two binaries for one testcase. Therefore
+# the testcase simply executes this script. This script then runs client
+# and service and checks that both exit sucessfully.
+
+FAIL=0
+
+# Start the service
+export VSOMEIP_APPLICATION_NAME=local_payload_test_service
+export VSOMEIP_CONFIGURATION=local_payload_test_service.json
+./payload_test_service &
+SERIVCE_PID=$!
+sleep 1;
+
+# Start the client
+export VSOMEIP_APPLICATION_NAME=local_payload_test_client
+export VSOMEIP_CONFIGURATION=local_payload_test_client.json
+./payload_test_client --number-of-messages 100 --max-payload-size 10485760 &
+CLIENT_PID=$!
+
+# Wait until client and service are finished
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ wait $job || ((FAIL+=1))
+done
+
+# Check if client and server both exited sucessfully and the service didnt't
+# have any open tcp/udp sockets
+if [ $FAIL -eq 0 ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/test/payload_tests/payload_test_client.cpp b/test/payload_tests/payload_test_client.cpp
index 27759b7..11d4511 100644
--- a/test/payload_tests/payload_test_client.cpp
+++ b/test/payload_tests/payload_test_client.cpp
@@ -40,11 +40,11 @@ payload_test_client::payload_test_client(
{
}
-void payload_test_client::init()
+bool payload_test_client::init()
{
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_state_handler(
@@ -61,6 +61,7 @@ void payload_test_client::init()
std::bind(&payload_test_client::on_availability, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
+ return true;
}
void payload_test_client::start()
@@ -185,8 +186,8 @@ void payload_test_client::run()
std::shared_ptr<vsomeip::payload> payload = vsomeip::runtime::get()->create_payload();
std::vector<vsomeip::byte_t> payload_data;
- bool lastrun = false;
- while (current_payload_size_ <= max_allowed_payload)
+ bool reached_peak = false;
+ for(;;)
{
payload_data.assign(current_payload_size_ , vsomeip_test::PAYLOAD_TEST_DATA);
payload->set_data(payload_data);
@@ -201,16 +202,19 @@ void payload_test_client::run()
print_throughput();
// Increase array size for next iteration
- current_payload_size_ *= 2;
+ if(!reached_peak) {
+ current_payload_size_ *= 2;
+ } else {
+ current_payload_size_ /= 2;
+ }
- //special case to test the biggest payload possible as last test
- // 16 Bytes are reserved for the SOME/IP header
- if(current_payload_size_ > max_allowed_payload - 16 && !lastrun)
+ if(!reached_peak && current_payload_size_ > max_allowed_payload)
{
- current_payload_size_ = max_allowed_payload - 16;
- lastrun = true;
+ current_payload_size_ = max_allowed_payload;
+ reached_peak = true;
+ } else if(reached_peak && current_payload_size_ <= 1) {
+ break;
}
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
blocked_ = false;
@@ -229,13 +233,15 @@ std::uint32_t payload_test_client::get_max_allowed_payload()
switch (max_payload_size)
{
case payloadsize::UDS:
- payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
+ // TODO
+ payload = 1024 * 32 - 16;
break;
case payloadsize::TCP:
- payload = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+ // TODO
+ payload = 4095 - 16;
break;
case payloadsize::UDP:
- payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
+ payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE - 16;
break;
case payloadsize::USER_SPECIFIED:
payload = user_defined_max_payload;
@@ -291,24 +297,25 @@ void payload_test_client::print_throughput()
stop_watch::usec_t time_per_message = time_needed / number_of_sent_messages_;
std::double_t calls_per_sec = number_of_sent_messages_
* (usec_per_sec / static_cast<double>(time_needed));
- std::double_t kbyte_per_sec = ((number_of_sent_messages_
+ std::double_t mbyte_per_sec = ((number_of_sent_messages_
* current_payload_size_)
- / (static_cast<double>(time_needed) / usec_per_sec)) / 1024;
+ / (static_cast<double>(time_needed) / usec_per_sec)) / (1024*1024);
VSOMEIP_INFO<< "[ Payload Test ] : :"
- << "Payload size [byte]: " << std::setw(8) << std::setfill('0') << current_payload_size_
- << " Messages sent: " << std::setw(8) << std::setfill('0') << number_of_sent_messages_
- << " Meantime/message [usec]: " << std::setw(8) << std::setfill('0') << time_per_message
- << " Calls/sec: " << std::setw(8) << std::setfill('0') << calls_per_sec
- << " KiB/sec: " << std::setw(8) << std::setfill('0') << kbyte_per_sec;
+ << "Payload size [byte]: " << std::dec << std::setw(8) << std::setfill('0') << current_payload_size_
+ << " Messages sent: " << std::dec << std::setw(8) << std::setfill('0') << number_of_sent_messages_
+ << " Meantime/message [usec]: " << std::dec << std::setw(8) << std::setfill('0') << time_per_message
+ << " Calls/sec: " << std::dec << std::setw(8) << std::setfill('0') << calls_per_sec
+ << " MiB/sec: " << std::dec << std::setw(8) << std::setfill('0') << mbyte_per_sec;
}
TEST(someip_payload_test, send_different_payloads)
{
payload_test_client test_client_(use_tcp, call_service_sync, sliding_window_size);
- test_client_.init();
- test_client_.start();
- test_client_.join_sender_thread();
+ if (test_client_.init()) {
+ test_client_.start();
+ test_client_.join_sender_thread();
+ }
}
diff --git a/test/payload_tests/payload_test_client.hpp b/test/payload_tests/payload_test_client.hpp
index 8af352e..b9da542 100644
--- a/test/payload_tests/payload_test_client.hpp
+++ b/test/payload_tests/payload_test_client.hpp
@@ -24,7 +24,7 @@ class payload_test_client
{
public:
payload_test_client(bool _use_tcp, bool _call_service_sync, std::uint32_t _sliding_window_size);
- void init();
+ bool init();
void start();
void stop();
void join_sender_thread();
diff --git a/test/payload_tests/payload_test_service.cpp b/test/payload_tests/payload_test_service.cpp
index 74191da..05a9cb4 100644
--- a/test/payload_tests/payload_test_service.cpp
+++ b/test/payload_tests/payload_test_service.cpp
@@ -19,13 +19,13 @@ payload_test_service::payload_test_service(bool _use_tcp) :
{
}
-void payload_test_service::init()
+bool payload_test_service::init()
{
std::lock_guard<std::mutex> its_lock(mutex_);
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
@@ -41,6 +41,7 @@ void payload_test_service::init()
app_->register_state_handler(
std::bind(&payload_test_service::on_state, this,
std::placeholders::_1));
+ return true;
}
void payload_test_service::start()
@@ -101,25 +102,26 @@ void payload_test_service::on_message(const std::shared_ptr<vsomeip::message>& _
VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4)
<< std::setfill('0') << std::hex << _request->get_client() << "/"
<< std::setw(4) << std::setfill('0') << std::hex
- << _request->get_session() << "]";
+ << _request->get_session() << "] payload size [byte]:"
+ << std::dec << _request->get_payload()->get_length();
}
- ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID);
- ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID);
+ ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service());
+ ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method());
// Check the protocol version this shall be set to 0x01 according to the spec.
// TR_SOMEIP_00052
- ASSERT_EQ(_request->get_protocol_version(), 0x01);
+ ASSERT_EQ(0x01, _request->get_protocol_version());
// Check the message type this shall be 0xx (REQUEST) according to the spec.
// TR_SOMEIP_00055
- ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST);
+ ASSERT_EQ(vsomeip::message_type_e::MT_REQUEST, _request->get_message_type());
if (check_payload) {
std::shared_ptr<vsomeip::payload> pl = _request->get_payload();
vsomeip::byte_t* pl_ptr = pl->get_data();
for (vsomeip::length_t i = 0; i < pl->get_length(); i++)
{
- ASSERT_EQ(*(pl_ptr+i), vsomeip_test::PAYLOAD_TEST_DATA);
+ ASSERT_EQ(vsomeip_test::PAYLOAD_TEST_DATA, *(pl_ptr+i));
}
}
@@ -150,9 +152,10 @@ void payload_test_service::run()
TEST(someip_payload_test, send_response_for_every_request)
{
payload_test_service test_service(use_tcp);
- test_service.init();
- test_service.start();
- test_service.join_offer_thread();
+ if (test_service.init()) {
+ test_service.start();
+ test_service.join_offer_thread();
+ }
}
#ifndef WIN32
diff --git a/test/payload_tests/payload_test_service.hpp b/test/payload_tests/payload_test_service.hpp
index 098543a..d109146 100644
--- a/test/payload_tests/payload_test_service.hpp
+++ b/test/payload_tests/payload_test_service.hpp
@@ -20,7 +20,7 @@ class payload_test_service
{
public:
payload_test_service(bool _use_tcp);
- void init();
+ bool init();
void start();
void stop();
void offer();
diff --git a/test/readme.txt b/test/readme.txt
index 9e127b4..6b191d5 100644
--- a/test/readme.txt
+++ b/test/readme.txt
@@ -278,13 +278,16 @@ All tests should be marked as "passed".
Big payload tests
-----------------
-This test tests the possibility to increase the maximum allowed payload size for
-local and TCP messages via configuration file.
+This test tests the possibility to sent messages with bigger payloads
+for local and TCP communication.
The test will send a messages with 600k payload from a client to a service.
The service will reply with a response containing 600k payload as well.
This is repeated 10 times.
There is a version for local and for TCP communication available.
+Additionally there are test versions available which sent up to 10MiB big
+messages and a version which tests the limitiation of message sizes configurable
+via json file.
Automatic start from the build directory:
diff --git a/test/routing_tests/external_local_routing_test_service.cpp b/test/routing_tests/external_local_routing_test_service.cpp
index d92f958..cd92508 100644
--- a/test/routing_tests/external_local_routing_test_service.cpp
+++ b/test/routing_tests/external_local_routing_test_service.cpp
@@ -16,13 +16,13 @@ external_local_routing_test_service::external_local_routing_test_service(bool _u
{
}
-void external_local_routing_test_service::init()
+bool external_local_routing_test_service::init()
{
std::lock_guard<std::mutex> its_lock(mutex_);
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
@@ -39,6 +39,7 @@ void external_local_routing_test_service::init()
std::placeholders::_1));
VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF");
+ return true;
}
void external_local_routing_test_service::start()
@@ -169,9 +170,10 @@ TEST(someip_external_local_routing_test, receive_ten_messages_over_local_and_ext
{
bool use_static_routing = true;
external_local_routing_test_service test_service(use_static_routing);
- test_service.init();
- test_service.start();
- test_service.join_offer_thread();
+ if (test_service.init()) {
+ test_service.start();
+ test_service.join_offer_thread();
+ }
}
#ifndef WIN32
diff --git a/test/routing_tests/external_local_routing_test_service.hpp b/test/routing_tests/external_local_routing_test_service.hpp
index f1e73b9..e30a71c 100644
--- a/test/routing_tests/external_local_routing_test_service.hpp
+++ b/test/routing_tests/external_local_routing_test_service.hpp
@@ -20,7 +20,7 @@ class external_local_routing_test_service
{
public:
external_local_routing_test_service(bool _use_static_routing);
- void init();
+ bool init();
void start();
void stop();
void offer();
diff --git a/test/routing_tests/external_local_routing_test_starter.sh b/test/routing_tests/external_local_routing_test_starter.sh
index 36a85e6..f4ba129 100755
--- a/test/routing_tests/external_local_routing_test_starter.sh
+++ b/test/routing_tests/external_local_routing_test_starter.sh
@@ -76,7 +76,12 @@ kill -0 $CLIENT_PID &> /dev/null
CLIENT_STILL_THERE=$?
if [ $CLIENT_STILL_THERE -ne 0 ]
then
-cat <<End-of-message
+ if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting external_local_routing_test_starter.sh on slave LXC"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./external_local_routing_test_client_external_start.sh\"" &
+ echo "remote ssh job id: $!"
+ else
+ cat <<End-of-message
*******************************************************************************
*******************************************************************************
** Please now run:
@@ -89,6 +94,7 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+ fi
fi
# Wait until client and service are finished
diff --git a/test/routing_tests/local_routing_test_client.cpp b/test/routing_tests/local_routing_test_client.cpp
index f280eb2..a9acb44 100644
--- a/test/routing_tests/local_routing_test_client.cpp
+++ b/test/routing_tests/local_routing_test_client.cpp
@@ -18,11 +18,11 @@ local_routing_test_client::local_routing_test_client(bool _use_tcp) :
{
}
-void local_routing_test_client::init()
+bool local_routing_test_client::init()
{
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_state_handler(
@@ -39,6 +39,7 @@ void local_routing_test_client::init()
std::bind(&local_routing_test_client::on_availability, this,
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
+ return true;
}
void local_routing_test_client::start()
@@ -152,9 +153,10 @@ TEST(someip_local_routing_test, send_ten_messages_to_service_and_receive_reply)
{
bool use_tcp = false;
local_routing_test_client test_client_(use_tcp);
- test_client_.init();
- test_client_.start();
- test_client_.join_sender_thread();
+ if (test_client_.init()) {
+ test_client_.start();
+ test_client_.join_sender_thread();
+ }
}
#ifndef WIN32
diff --git a/test/routing_tests/local_routing_test_client.hpp b/test/routing_tests/local_routing_test_client.hpp
index cb30667..2229ae6 100644
--- a/test/routing_tests/local_routing_test_client.hpp
+++ b/test/routing_tests/local_routing_test_client.hpp
@@ -21,7 +21,7 @@ class local_routing_test_client
{
public:
local_routing_test_client(bool _use_tcp);
- void init();
+ bool init();
void start();
void stop();
void join_sender_thread();
diff --git a/test/routing_tests/local_routing_test_service.cpp b/test/routing_tests/local_routing_test_service.cpp
index 3a61ddf..137e8ea 100644
--- a/test/routing_tests/local_routing_test_service.cpp
+++ b/test/routing_tests/local_routing_test_service.cpp
@@ -15,13 +15,13 @@ local_routing_test_service::local_routing_test_service(bool _use_static_routing)
{
}
-void local_routing_test_service::init()
+bool local_routing_test_service::init()
{
std::lock_guard<std::mutex> its_lock(mutex_);
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return false;
}
app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
@@ -33,6 +33,7 @@ void local_routing_test_service::init()
std::placeholders::_1));
VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF");
+ return true;
}
void local_routing_test_service::start()
@@ -148,9 +149,10 @@ TEST(someip_local_routing_test, receive_ten_messages_over_local_uds_socket)
{
bool use_static_routing = true;
local_routing_test_service test_service(use_static_routing);
- test_service.init();
- test_service.start();
- test_service.join_offer_thread();
+ if (test_service.init()) {
+ test_service.start();
+ test_service.join_offer_thread();
+ }
}
#ifndef WIN32
diff --git a/test/routing_tests/local_routing_test_service.hpp b/test/routing_tests/local_routing_test_service.hpp
index f78d5b0..3d575d7 100644
--- a/test/routing_tests/local_routing_test_service.hpp
+++ b/test/routing_tests/local_routing_test_service.hpp
@@ -20,7 +20,7 @@ class local_routing_test_service
{
public:
local_routing_test_service(bool _use_static_routing);
- void init();
+ bool init();
void start();
void stop();
void offer();
diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh b/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh
index f85aa6c..995e66e 100755
--- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh
+++ b/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh
@@ -62,7 +62,12 @@ export VSOMEIP_CONFIGURATION=$2
sleep 1
-cat <<End-of-message
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting subscribe_notify_one_test_slave_starter.sh on slave LXC with parameters $1 $CLIENT_JSON_FILE"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./subscribe_notify_one_test_slave_starter.sh $1 $CLIENT_JSON_FILE\"" &
+ echo "remote ssh job id: $!"
+else
+ cat <<End-of-message
*******************************************************************************
*******************************************************************************
** Please now run:
@@ -75,6 +80,7 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# Wait until client and service are finished
for job in $(jobs -p)
diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp b/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp
index fd3c047..0727b8e 100644
--- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp
+++ b/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp
@@ -37,8 +37,8 @@ public:
wait_for_notify_(true),
notify_thread_(std::bind(&subscribe_notify_one_test_service::notify_one, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&subscribe_notify_one_test_service::on_state, this,
@@ -78,6 +78,8 @@ public:
std::placeholders::_1, std::placeholders::_2,
std::placeholders::_3));
+ app_->request_service(i.service_id, i.instance_id, vsomeip::DEFAULT_MAJOR, vsomeip::DEFAULT_MINOR, true);
+
std::set<vsomeip::eventgroup_t> its_eventgroups;
its_eventgroups.insert(i.eventgroup_id);
app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, false);
@@ -319,7 +321,7 @@ public:
// successfully subscribed as we only receive once subscription per
// remote node no matter how many clients subscribed to this eventgroup
// on the remote node
- std::this_thread::sleep_for(std::chrono::milliseconds(2000));
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex
<< service_info_.service_id << "] Starting to notify";
@@ -341,7 +343,7 @@ public:
app_->notify_one(service_info_.service_id, service_info_.instance_id,
service_info_.event_id, its_payload, client);
}
- std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
@@ -363,8 +365,17 @@ public:
wait_until_notified_from_other_services_ = false;
condition_.notify_one();
}
-
- std::this_thread::sleep_for(std::chrono::seconds(6));
+ for(const auto& i : subscribe_notify_one_test::service_infos) {
+ if ((i.service_id == service_info_.service_id
+ && i.instance_id == service_info_.instance_id)
+ || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) {
+ continue;
+ }
+ app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id);
+ app_->release_event(i.service_id, i.instance_id, i.event_id);
+ app_->release_service(i.service_id, i.instance_id);
+ }
+ std::this_thread::sleep_for(std::chrono::seconds(1));
app_->clear_all_handler();
app_->stop();
}
diff --git a/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh
index bbb48ea..006d2bc 100755
--- a/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh
+++ b/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh
@@ -63,7 +63,12 @@ export VSOMEIP_CONFIGURATION=$2
sleep 1
-cat <<End-of-message
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting subscribe_notify_test_slave_starter.sh on slave LXC with parameters $1 $CLIENT_JSON_FILE $3"
+ ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_ROOT_DIR/ctarget/vsomeip/test; ./subscribe_notify_test_slave_starter.sh $1 $CLIENT_JSON_FILE $3\"" &
+ echo "remote ssh job id: $!"
+else
+ cat <<End-of-message
*******************************************************************************
*******************************************************************************
** Please now run:
@@ -76,6 +81,7 @@ cat <<End-of-message
*******************************************************************************
*******************************************************************************
End-of-message
+fi
# Wait until client and service are finished
for job in $(jobs -p)
diff --git a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp b/test/subscribe_notify_tests/subscribe_notify_test_service.cpp
index 9dd3bbb..bec20c6 100644
--- a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp
+++ b/test/subscribe_notify_tests/subscribe_notify_test_service.cpp
@@ -38,8 +38,8 @@ public:
wait_for_notify_(true),
notify_thread_(std::bind(&subscribe_notify_test_service::notify, this)) {
if (!app_->init()) {
- VSOMEIP_ERROR << "Couldn't initialize application";
- EXPECT_TRUE(false);
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
}
app_->register_state_handler(
std::bind(&subscribe_notify_test_service::on_state, this,
@@ -359,6 +359,16 @@ public:
}
std::this_thread::sleep_for(std::chrono::seconds(1));
+ for(const auto& i : service_infos_) {
+ if ((i.service_id == service_info_.service_id
+ && i.instance_id == service_info_.instance_id)
+ || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) {
+ continue;
+ }
+ app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id);
+ app_->release_event(i.service_id, i.instance_id, i.event_id);
+ app_->release_service(i.service_id, i.instance_id);
+ }
app_->clear_all_handler();
app_->stop();
}
diff --git a/tools/vsomeip_ctrl.cpp b/tools/vsomeip_ctrl.cpp
index 947caf8..362f1b4 100644
--- a/tools/vsomeip_ctrl.cpp
+++ b/tools/vsomeip_ctrl.cpp
@@ -61,7 +61,10 @@ public:
validate_message();
- app_->init();
+ if (!app_->init()) {
+ VSOMEIP_ERROR << "Couldn't initialize application";
+ exit(EXIT_FAILURE);
+ }
app_->register_state_handler(
std::bind(&vsomeip_sender::on_state, this,
std::placeholders::_1));
@@ -77,6 +80,8 @@ public:
};
void stop(int _exit_code) {
+ app_->clear_all_handler();
+ app_->release_service(service_id_, instance_);
app_->stop();
exit(_exit_code);
}