From c78c92307c4908ed286042def6fdae86f9a04b70 Mon Sep 17 00:00:00 2001 From: Lutz Bichler Date: Tue, 2 Jun 2020 10:32:34 +0200 Subject: vsomeip 3.1.14.1 --- Android.bp | 20 +- CHANGES | 48 ++ CMakeLists.txt | 30 +- README.md | 8 +- examples/hello_world/Android.bp | 40 ++ examples/hello_world/hello_world_client.cpp | 3 + examples/hello_world/hello_world_service.cpp | 3 + examples/hello_world/readme | 11 + examples/hello_world/readme_android | 11 + examples/response-sample.cpp | 2 +- examples/routingmanagerd/routingmanagerd.cpp | 2 +- exportmap.gcc | 11 +- implementation/compat/logging/include/logger.hpp | 28 - .../compat/logging/include/logger_impl.hpp | 33 - implementation/compat/logging/src/logger.cpp | 16 - implementation/compat/logging/src/logger_impl.cpp | 30 - implementation/compat/message/src/message_impl.cpp | 5 + implementation/compat/message/src/payload_impl.cpp | 5 + .../compat/runtime/src/application_impl.cpp | 5 + .../configuration/include/configuration.hpp | 48 +- .../configuration/include/configuration_impl.hpp | 39 +- .../configuration/include/internal.hpp.in | 10 + .../configuration/include/internal_android.hpp | 10 +- implementation/configuration/include/service.hpp | 4 + .../configuration/src/configuration_impl.cpp | 412 +++++++++++-- .../endpoints/include/endpoint_manager_impl.hpp | 18 +- .../endpoints/include/tcp_client_endpoint_impl.hpp | 11 +- .../endpoints/include/udp_server_endpoint_impl.hpp | 21 +- .../endpoints/src/endpoint_manager_impl.cpp | 287 ++++----- .../endpoints/src/tcp_client_endpoint_impl.cpp | 70 ++- .../endpoints/src/udp_client_endpoint_impl.cpp | 9 +- .../endpoints/src/udp_server_endpoint_impl.cpp | 186 +++--- .../reactive_socket_recvfrom_op_ext_local.hpp | 2 +- implementation/logger/include/logger_impl.hpp | 53 ++ implementation/logger/src/logger_impl.cpp | 114 ++++ implementation/logger/src/message.cpp | 157 +++++ .../logging/include/android_sink_backend.hpp | 33 - implementation/logging/include/defines.hpp | 12 - .../logging/include/dlt_sink_backend.hpp | 45 -- implementation/logging/include/logger_impl.hpp | 77 --- .../logging/src/android_sink_backend.cpp | 66 -- implementation/logging/src/dlt_sink_backend.cpp | 70 --- implementation/logging/src/logger.cpp | 14 - implementation/logging/src/logger_impl.cpp | 211 ------- implementation/plugin/src/plugin_manager_impl.cpp | 1 + implementation/routing/include/event.hpp | 2 +- implementation/routing/include/eventgroupinfo.hpp | 5 + .../routing/include/remote_subscription.hpp | 4 +- .../routing/include/routing_manager_impl.hpp | 16 +- .../routing/include/routing_manager_proxy.hpp | 4 - implementation/routing/src/event.cpp | 2 +- implementation/routing/src/eventgroupinfo.cpp | 108 +++- implementation/routing/src/remote_subscription.cpp | 3 +- .../routing/src/routing_manager_base.cpp | 12 +- .../routing/src/routing_manager_impl.cpp | 250 +++++--- .../routing/src/routing_manager_proxy.cpp | 102 ++-- .../routing/src/routing_manager_stub.cpp | 4 +- .../runtime/include/application_impl.hpp | 5 +- implementation/runtime/src/application_impl.cpp | 182 ++++-- implementation/security/include/policy.hpp | 12 +- implementation/security/src/security_impl.cpp | 141 +++-- .../include/selective_option_impl.hpp | 1 + .../include/service_discovery.hpp | 4 +- .../include/service_discovery_host.hpp | 10 +- .../include/service_discovery_impl.hpp | 50 +- .../service_discovery/include/subscription.hpp | 6 + .../src/remote_subscription_ack.cpp | 5 +- .../src/selective_option_impl.cpp | 5 + .../src/service_discovery_impl.cpp | 676 +++++++++++++++------ .../service_discovery/src/subscription.cpp | 8 + implementation/utility/src/utility.cpp | 27 +- interface/compat/vsomeip/runtime.hpp | 2 +- interface/vsomeip/application.hpp | 1 - interface/vsomeip/enumeration_types.hpp | 2 +- interface/vsomeip/handler.hpp | 8 +- interface/vsomeip/internal/logger.hpp | 77 ++- test/CMakeLists.txt | 78 +-- .../big_payload_test_udp_client.json | 4 +- .../big_payload_test_udp_service.json | 2 +- test/configuration_tests/configuration-test.cpp | 23 +- test/e2e_tests/e2e_test_client.cpp | 6 +- test/e2e_tests/e2e_test_service.cpp | 4 +- test/event_tests/event_test_client.cpp | 3 +- test/event_tests/event_test_service.cpp | 20 +- test/event_tests/event_test_slave_starter.sh | 2 +- .../initial_event_test_availability_checker.cpp | 11 +- .../initial_event_test_client.cpp | 32 +- ...test_diff_client_ids_diff_ports_master_udp.json | 2 +- ..._test_diff_client_ids_diff_ports_slave_udp.json | 2 +- ...test_diff_client_ids_same_ports_master_udp.json | 2 +- ..._test_diff_client_ids_same_ports_slave_udp.json | 2 +- .../initial_event_test_master_starter.sh | 3 + .../initial_event_test_service.cpp | 25 +- .../initial_event_test_slave_starter.sh | 2 +- .../malicious_data_test_service.cpp | 3 +- test/npdu_tests/npdu_test_client_no_npdu.json | 2 +- test/npdu_tests/npdu_test_client_npdu.json | 10 +- test/npdu_tests/npdu_test_service_no_npdu.json | 2 +- test/npdu_tests/npdu_test_service_npdu.json | 2 +- test/offer_tests/offer_test_big_sd_msg_client.cpp | 3 +- test/offer_tests/offer_test_client.cpp | 3 +- test/offer_tests/offer_test_service.cpp | 2 +- .../pending_subscription_test_service.cpp | 4 +- test/security_tests/security_test_client.cpp | 6 +- test/security_tests/security_test_service.cpp | 4 +- test/someip_tp_tests/someip_tp_test_master.json | 4 +- .../someip_tp_test_master_starter.sh | 6 +- test/someip_tp_tests/someip_tp_test_service.cpp | 5 +- .../subscribe_notify_one_test_master_starter.sh | 21 +- .../subscribe_notify_one_test_service.cpp | 30 +- .../subscribe_notify_one_test_slave_starter.sh | 12 +- ...test_diff_client_ids_diff_ports_master_udp.json | 2 +- ..._ids_diff_ports_same_service_id_master_udp.json | 2 +- ...t_ids_diff_ports_same_service_id_slave_udp.json | 2 +- ..._test_diff_client_ids_diff_ports_slave_udp.json | 2 +- ...test_diff_client_ids_same_ports_master_udp.json | 2 +- ..._test_diff_client_ids_same_ports_slave_udp.json | 2 +- .../subscribe_notify_test_master_starter.sh | 20 +- ...otify_test_one_event_two_eventgroups_client.cpp | 12 +- ...est_one_event_two_eventgroups_master_starter.sh | 7 +- ...tify_test_one_event_two_eventgroups_service.cpp | 39 +- ...test_one_event_two_eventgroups_slave_starter.sh | 12 +- .../subscribe_notify_test_service.cpp | 37 +- .../subscribe_notify_test_slave_starter.sh | 15 +- 124 files changed, 2759 insertions(+), 1762 deletions(-) create mode 100644 examples/hello_world/Android.bp create mode 100644 examples/hello_world/readme_android delete mode 100644 implementation/compat/logging/include/logger.hpp delete mode 100644 implementation/compat/logging/include/logger_impl.hpp delete mode 100644 implementation/compat/logging/src/logger.cpp delete mode 100644 implementation/compat/logging/src/logger_impl.cpp create mode 100644 implementation/logger/include/logger_impl.hpp create mode 100644 implementation/logger/src/logger_impl.cpp create mode 100644 implementation/logger/src/message.cpp delete mode 100644 implementation/logging/include/android_sink_backend.hpp delete mode 100644 implementation/logging/include/defines.hpp delete mode 100644 implementation/logging/include/dlt_sink_backend.hpp delete mode 100644 implementation/logging/include/logger_impl.hpp delete mode 100644 implementation/logging/src/android_sink_backend.cpp delete mode 100644 implementation/logging/src/dlt_sink_backend.cpp delete mode 100644 implementation/logging/src/logger.cpp delete mode 100644 implementation/logging/src/logger_impl.cpp diff --git a/Android.bp b/Android.bp index a297c32..9963703 100644 --- a/Android.bp +++ b/Android.bp @@ -36,7 +36,8 @@ cc_defaults { "-Wno-sign-compare", "-Wno-format", "-Wno-header-guard", - "-Wno-overloaded-virtual" + "-Wno-overloaded-virtual", + "-Wno-implicit-fallthrough" ] } @@ -58,7 +59,7 @@ cc_library_shared { local_include_dirs: [ "interface", - "implementation/helper/1.66" + "implementation/helper/1.70" ], export_include_dirs: [ @@ -66,7 +67,6 @@ cc_library_shared { ], shared_libs: [ - "libboost_log", "libboost_system", "libboost_thread", "libboost_filesystem", @@ -89,12 +89,12 @@ cc_library_shared { local_include_dirs: [ "interface", - "implementation/helper/1.66" + "implementation/helper/1.70" ], shared_libs: [ "libvsomeip", - "libboost_log", + "libboost_system", "libboost_filesystem" ] } @@ -113,12 +113,11 @@ cc_library_shared { local_include_dirs: [ "interface", - "implementation/helper/1.66" + "implementation/helper/1.70" ], shared_libs: [ - "libvsomeip", - "libboost_log" + "libvsomeip" ] } @@ -136,11 +135,10 @@ cc_library_shared { local_include_dirs: [ "interface", - "implementation/helper/1.66" + "implementation/helper/1.70" ], shared_libs: [ - "libvsomeip", - "libboost_log" + "libvsomeip" ] } diff --git a/CHANGES b/CHANGES index 896c0e2..eae9b13 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,54 @@ Changes ======= +v3.1.14.1 +- Merged extended support for static routing (versioning) + (by Jean-Patrice Laude ) +- Merged simplification of build process for hello_world example + (by Nikolay Khilyuk ) +- Updated Android.bp to use boost 1.70.0 or higher +- Merged Android support for hello_world example + (by Nikolay Khilyuk ) +- Align response sample to documentation (do not specify application name) + (by JayHou ) +- Call dlerror before calling dlsym to clear previous error. + (by Oleg Kharitonov ) +- Get base path from environment variable for Android NDK. + (by Nikolay Khilyuk ) +- Fixed wrong library naming + (by Nikolay Khilyuk ) + +v3.1.14 +- Fixed race conditions (application registration, subscription) + +v3.1.13 +- Abort operation when doing a full rejoin +- Protect access when consuming a policy +- Decrease wait time for composite send operations +- Reimplemented logger without using boost::log + +v3.1.12 +- Ensure composite send operations have finished before resetting an endpoint. + Otherwise this may cause a crash within boost.asio. +- Always use the assigned client identifier when sending messages from a proxy. +- Add TTL to initial timestamp to avoid immediate expiration. + +v3.1.11 +- Preparation for new IPsec plugin (3.1.1) + +v3.1.10 +- Reset subscriptions on stop offer service +- Protect access to security policy contents +- Tolerate wrong/incomplete event registrations in compatibility mode +- Avoid buffering of pending subscriptions + +v3.1.9 +- Fix race condition when processing multicast messages + +v3.1.8 +- Fix deadlock when sending messages +- Fix race condition when processing SD messages + v3.1.7 - Fix stop subscribes when a service is released - Improve handling of time stamps when processing subscriptions diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a6023f..7b5eabf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,11 +11,11 @@ set (VSOMEIP_COMPAT_NAME vsomeip) set (VSOMEIP_MAJOR_VERSION 3) set (VSOMEIP_MINOR_VERSION 1) -set (VSOMEIP_PATCH_VERSION 7) +set (VSOMEIP_PATCH_VERSION 14) set (VSOMEIP_HOTFIX_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 (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentation/doxygen.in set (CMAKE_VERBOSE_MAKEFILE off) if (NOT GTEST_ROOT) @@ -96,11 +96,15 @@ if (ENABLE_SIGNAL_HANDLING) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_SIGNAL_HANDLING") endif () -# Thread sanitizer +# Sanitizer if (ENABLE_THREAD_SANITIZER) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") endif () +if (ENABLE_LEAK_SANITIZER) +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak") +endif () + # Configuration overlays if (ENABLE_CONFIGURATION_OVERLAYS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_CONFIGURATION_OVERLAYS") @@ -128,7 +132,7 @@ endif () find_package(Threads REQUIRED) # Boost -find_package( Boost 1.55 COMPONENTS system thread log REQUIRED ) +find_package( Boost 1.55 COMPONENTS system thread filesystem REQUIRED ) include_directories( ${Boost_INCLUDE_DIR} ) if(Boost_FOUND) @@ -152,7 +156,7 @@ else() endif() message( STATUS "Using boost version: ${VSOMEIP_BOOST_VERSION}" ) -if (${VSOMEIP_BOOST_VERSION} GREATER 107200) +if (${VSOMEIP_BOOST_VERSION} GREATER 107300) message( ERROR "boost version ${VSOMEIP_BOOST_VERSION} is not (yet) supported. Latest supported version is 1.72.0" ) elseif(${VSOMEIP_BOOST_VERSION} GREATER 106999) set(VSOMEIP_BOOST_HELPER implementation/helper/1.70) @@ -209,14 +213,14 @@ if (MSVC) message("using MSVC Compiler") # add_definitions(-DVSOMEIP_DLL_COMPILATION) now it is controlled per target SET(BOOST_WINDOWS_VERSION "0x600" CACHE STRING "Set the same Version as the Version with which Boost was built, otherwise there will be errors. (normaly 0x600 is for Windows 7 and 0x501 is for Windows XP)") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_LOG_DYN_LINK -DBOOST_ASIO_DISABLE_IOCP /EHsc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_LOG_DYN_LINK -DBOOST_ASIO_DISABLE_IOCP /EHsc") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc") set(USE_RT "") set(Boost_LIBRARIES "") link_directories(${Boost_LIBRARY_DIR_DEBUG}) ADD_DEFINITIONS( -DBOOST_ALL_DYN_LINK ) else() - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${OS} ${OS_CXX_FLAGS} -DBOOST_LOG_DYN_LINK -g ${OPTIMIZE} -std=c++11 ${NO_DEPRECATED} ${EXPORTSYMBOLS}") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${OS} ${OS_CXX_FLAGS} -g ${OPTIMIZE} -std=c++11 ${NO_DEPRECATED} ${EXPORTSYMBOLS}") set(USE_RT "rt") endif() @@ -242,7 +246,7 @@ endif () ################################################################################ file(GLOB ${VSOMEIP_NAME}_SRC "implementation/endpoints/src/*.cpp" - "implementation/logging/src/*.cpp" + "implementation/logger/src/*.cpp" "implementation/tracing/src/*.cpp" "implementation/message/src/*.cpp" "implementation/plugin/src/*.cpp" @@ -252,7 +256,7 @@ file(GLOB ${VSOMEIP_NAME}_SRC "implementation/utility/src/*.cpp" ) if (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS EQUAL 1) -list(APPEND ${VSOMEIP_NAME}_SRC ${${VSOMEIP_NAME}-cfg_SRC}) +list(APPEND ${VSOMEIP_NAME}_SRC "implementation/configuration/src/configuration_impl.cpp") endif() list(SORT ${VSOMEIP_NAME}_SRC) @@ -553,7 +557,7 @@ else() -a version=${VSOMEIP_VERSION} -b html -o documentation/vsomeipUserGuide.html - ${PROJECT_BINARY_DIR}/../documentation/vsomeipUserGuide) + ${PROJECT_SOURCE_DIR}/documentation/vsomeipUserGuide) endif() ############################################################################## @@ -576,7 +580,9 @@ add_subdirectory( tools ) # build examples add_custom_target( examples ) add_subdirectory( examples EXCLUDE_FROM_ALL ) - +add_custom_target( hello_world ) +add_subdirectory( examples/hello_world EXCLUDE_FROM_ALL ) + ############################################################################## # Test section ############################################################################## diff --git a/README.md b/README.md index 8036a11..6dab129 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ### vsomeip ##### Copyright -Copyright (C) 2015-2017, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +Copyright (C) 2015-2020, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) ##### License @@ -22,9 +22,9 @@ MiddlewarE over IP (SOME/IP)) protocol. The stack consists out of: ###### Dependencies -- A C++11 enabled compiler like gcc >= 4.8 is needed. +- A C++11 enabled compiler like gcc >= 5.4 is needed. - vsomeip uses CMake as buildsystem. -- vsomeip uses Boost >= 1.55: +- vsomeip uses Boost v1.55.0 - v1.73.0 Ubuntu 14.04: @@ -115,4 +115,4 @@ PRODUCT_PACKAGES += \ libvsomeip \ libvsomeip_cfg \ libvsomeip_sd -``` \ No newline at end of file +``` diff --git a/examples/hello_world/Android.bp b/examples/hello_world/Android.bp new file mode 100644 index 0000000..7622f0c --- /dev/null +++ b/examples/hello_world/Android.bp @@ -0,0 +1,40 @@ +cc_defaults { + name: "vsomeip_hello_world_defaults", + vendor: true, + + cppflags: [ + "-std=c++11", + "-Wno-unused-parameter", + ], + + shared_libs: [ + "libvsomeip", + "libvsomeip_cfg", + "libvsomeip_e2e", + "libvsomeip_sd", + ], +} + +cc_binary { + name: "vsomeip_hello_world_service", + defaults: ["vsomeip_hello_world_defaults"], + + srcs: [ + "hello_world_service.cpp", + ], +} + +cc_binary { + name: "vsomeip_hello_world_client", + defaults: ["vsomeip_hello_world_defaults"], + + srcs: [ + "hello_world_client.cpp", + ], +} + +prebuilt_etc { + name: "helloworld-local.json", + sub_dir: "vsomeip", + src: "helloworld-local.json", +} diff --git a/examples/hello_world/hello_world_client.cpp b/examples/hello_world/hello_world_client.cpp index 37bd0d9..03de7d5 100644 --- a/examples/hello_world/hello_world_client.cpp +++ b/examples/hello_world/hello_world_client.cpp @@ -146,6 +146,9 @@ hello_world_client *hw_cl_ptr(nullptr); int main(int argc, char **argv) { + (void)argc; + (void)argv; + hello_world_client hw_cl; #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING hw_cl_ptr = &hw_cl; diff --git a/examples/hello_world/hello_world_service.cpp b/examples/hello_world/hello_world_service.cpp index ce07721..3968581 100644 --- a/examples/hello_world/hello_world_service.cpp +++ b/examples/hello_world/hello_world_service.cpp @@ -140,6 +140,9 @@ hello_world_service *hw_srv_ptr(nullptr); int main(int argc, char **argv) { + (void)argc; + (void)argv; + hello_world_service hw_srv; #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING hw_srv_ptr = &hw_srv; diff --git a/examples/hello_world/readme b/examples/hello_world/readme index 3e1dc62..1cb9d8f 100644 --- a/examples/hello_world/readme +++ b/examples/hello_world/readme @@ -6,10 +6,21 @@ Build instructions for Hello World example ------------------------------------------ +1. Build whole project at first: +________________________________ +cd $: + mkdir build cd build cmake .. make +sudo make install + +2. Build hello_world target +___________________________ +cmake --build . --target hello_world +cd ./examples/hello_world/ +make Running Hello World Example --------------------------- diff --git a/examples/hello_world/readme_android b/examples/hello_world/readme_android new file mode 100644 index 0000000..2eced5b --- /dev/null +++ b/examples/hello_world/readme_android @@ -0,0 +1,11 @@ +To start service and client: + +Shell1: +VSOMEIP_CONFIGURATION=/etc/vsomeip/helloworld-local.json \ +VSOMEIP_APPLICATION_NAME=hello_world_service \ +vsomeip_hello_world_service + +Shell2: +VSOMEIP_CONFIGURATION=/etc/vsomeip/helloworld-local.json \ +VSOMEIP_APPLICATION_NAME=hello_world_client \ +vsomeip_hello_world_client \ No newline at end of file diff --git a/examples/response-sample.cpp b/examples/response-sample.cpp index 064388e..68112d2 100644 --- a/examples/response-sample.cpp +++ b/examples/response-sample.cpp @@ -19,7 +19,7 @@ class service_sample { public: service_sample(bool _use_static_routing) : - app_(vsomeip::runtime::get()->create_application("response-sample")), + app_(vsomeip::runtime::get()->create_application()), is_registered_(false), use_static_routing_(_use_static_routing), blocked_(false), diff --git a/examples/routingmanagerd/routingmanagerd.cpp b/examples/routingmanagerd/routingmanagerd.cpp index 53b4fc1..ff0a280 100644 --- a/examples/routingmanagerd/routingmanagerd.cpp +++ b/examples/routingmanagerd/routingmanagerd.cpp @@ -17,7 +17,7 @@ #ifdef USE_DLT #include -#include "../../implementation/logging/include/defines.hpp" + #endif static std::shared_ptr its_application; diff --git a/exportmap.gcc b/exportmap.gcc index efeaadb..a9a489c 100644 --- a/exportmap.gcc +++ b/exportmap.gcc @@ -17,10 +17,6 @@ global: vsomeip_v3::tcp*; *vsomeip_v3::udp*; vsomeip_v3::udp*; - *vsomeip_v3::logger; - vsomeip_v3::logger::get*; - *vsomeip_v3::logger_impl; - vsomeip_v3::logger_impl::init*; *vsomeip_v3::message_base_impl; *vsomeip_v3::message_base_impl::*; *vsomeip_v3::message_header_impl; @@ -34,6 +30,8 @@ global: vsomeip_v3::runtime::set_property*; *vsomeip_v3::application_impl; vsomeip_v3::application_impl*; + *vsomeip_v3::event; + vsomeip_v3::event::*; *vsomeip_v3::eventgroupinfo; vsomeip_v3::eventgroupinfo::*; *vsomeip_v3::remote_subscription; @@ -54,7 +52,10 @@ global: *vsomeip_v3::plugin_manager; vsomeip_v3::plugin_manager::*; vsomeip_v3::tp::tp_reassembler::*; - + *vsomeip_v3::logger::message; + vsomeip_v3::logger::message::*; + *vsomeip_v3::logger::logger_impl; + vsomeip_v3::logger::logger_impl::*; vsomeip::runtime::*; *vsomeip::runtime; vsomeip::logger::*; diff --git a/implementation/compat/logging/include/logger.hpp b/implementation/compat/logging/include/logger.hpp deleted file mode 100644 index 0f59502..0000000 --- a/implementation/compat/logging/include/logger.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2019 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_COMPAT_LOGGER_HPP_ -#define VSOMEIP_COMPAT_LOGGER_HPP_ - -#include - -#include -#include - -namespace vsomeip { - -class logger { -public: - static std::shared_ptr get(); - - virtual ~logger() {} - - virtual boost::log::sources::severity_logger_mt< - boost::log::trivial::severity_level> & get_internal() = 0; -}; - -} // namespace vsomeip - -#endif // VSOMEIP_COMPAT_LOGGER_HPP_ diff --git a/implementation/compat/logging/include/logger_impl.hpp b/implementation/compat/logging/include/logger_impl.hpp deleted file mode 100644 index 8aed18e..0000000 --- a/implementation/compat/logging/include/logger_impl.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2019 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_COMPAT_LOGGER_IMPL_HPP_ -#define VSOMEIP_COMPAT_LOGGER_IMPL_HPP_ - -#include "logger.hpp" - -namespace vsomeip_v3 { -class logger; -} // namespace vsomeip_v3 - -namespace vsomeip { - -class logger_impl - : public logger { -public: - static std::shared_ptr get(); - - logger_impl(); - - boost::log::sources::severity_logger_mt< - boost::log::trivial::severity_level> & get_internal(); - -private: - std::shared_ptr impl_; -}; - -} // namespace vsomeip - -#endif // VSOMEIP_COMPAT_LOGGER_IMPL_HPP_ diff --git a/implementation/compat/logging/src/logger.cpp b/implementation/compat/logging/src/logger.cpp deleted file mode 100644 index eb11707..0000000 --- a/implementation/compat/logging/src/logger.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2019 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 "../include/logger_impl.hpp" - -namespace vsomeip { - -std::shared_ptr -logger::get() { - - return (logger_impl::get()); -} - -} // namespace vsomeip diff --git a/implementation/compat/logging/src/logger_impl.cpp b/implementation/compat/logging/src/logger_impl.cpp deleted file mode 100644 index 4ceaaa7..0000000 --- a/implementation/compat/logging/src/logger_impl.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2019 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 "../include/logger_impl.hpp" -#include - -namespace vsomeip { - -std::shared_ptr -logger_impl::get() { - - static std::shared_ptr the_logger( - std::make_shared() - ); - return the_logger; -} - -logger_impl::logger_impl() - : impl_(vsomeip_v3::logger::get()) { -} - -boost::log::sources::severity_logger_mt & -logger_impl::get_internal() { - - return impl_->get_internal(); -} - -} // namespace vsomeip diff --git a/implementation/compat/message/src/message_impl.cpp b/implementation/compat/message/src/message_impl.cpp index e7e7af1..3cccc79 100644 --- a/implementation/compat/message/src/message_impl.cpp +++ b/implementation/compat/message/src/message_impl.cpp @@ -7,6 +7,11 @@ #include "../include/message_impl.hpp" #include "../include/payload_impl.hpp" +#ifdef ANDROID +# include "../../../configuration/include/internal_android.hpp" +#else +# include "../../../configuration/include/internal.hpp" +#endif #include "../../../message/include/message_impl.hpp" namespace vsomeip { diff --git a/implementation/compat/message/src/payload_impl.cpp b/implementation/compat/message/src/payload_impl.cpp index 5d78304..e1233c2 100644 --- a/implementation/compat/message/src/payload_impl.cpp +++ b/implementation/compat/message/src/payload_impl.cpp @@ -8,6 +8,11 @@ #include #include "../include/payload_impl.hpp" +#ifdef ANDROID +# include "../../../configuration/include/internal_android.hpp" +#else +# include "../../../configuration/include/internal.hpp" +#endif namespace vsomeip { diff --git a/implementation/compat/runtime/src/application_impl.cpp b/implementation/compat/runtime/src/application_impl.cpp index 559eae3..f1934e4 100644 --- a/implementation/compat/runtime/src/application_impl.cpp +++ b/implementation/compat/runtime/src/application_impl.cpp @@ -10,6 +10,11 @@ #include #include "../include/application_impl.hpp" +#ifdef ANDROID +# include "../../../configuration/include/internal_android.hpp" +#else +# include "../../../configuration/include/internal.hpp" +#endif #include "../../message/include/message_impl.hpp" #include "../../message/include/payload_impl.hpp" diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index aac5422..b1dcf5b 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include @@ -77,7 +77,7 @@ public: virtual bool has_file_log() const = 0; virtual bool has_dlt_log() const = 0; virtual const std::string & get_logfile() const = 0; - virtual boost::log::trivial::severity_level get_loglevel() const = 0; + virtual logger::level_e get_loglevel() const = 0; virtual const std::string & get_routing_host() const = 0; @@ -90,6 +90,13 @@ public: virtual uint16_t get_unreliable_port(service_t _service, instance_t _instance) const = 0; + virtual major_version_t get_major_version(service_t _service, + instance_t _instance) const = 0; + virtual minor_version_t get_minor_version(service_t _service, + instance_t _instance) const = 0; + virtual ttl_t get_ttl(service_t _service, + instance_t _instance) const = 0; + virtual void get_configured_timing_requests( service_t _service, std::string _ip_target, std::uint16_t _port_target, method_t _method, @@ -207,14 +214,37 @@ public: virtual std::uint32_t get_max_tcp_restart_aborts() const = 0; virtual std::uint32_t get_max_tcp_connect_time() const = 0; - // SD acceptance - virtual bool sd_acceptance_required(const boost::asio::ip::address& _address, - std::uint16_t _port) const = 0; - virtual void set_sd_acceptance_required( + // Acceptance handling + virtual bool is_protected_device( + const boost::asio::ip::address& _address) const = 0; + virtual bool is_protected_port( const boost::asio::ip::address& _address, std::uint16_t _port, - const std::string& _path, bool _enable) = 0; - typedef std::map, std::string> sd_acceptance_required_map_t; - virtual sd_acceptance_required_map_t get_sd_acceptance_required() = 0; + bool _reliable) const = 0; + + typedef std::pair port_range_t; + virtual void set_sd_acceptance_rule( + const boost::asio::ip::address &_address, + port_range_t _port_range, port_type_e _type, + const std::string &_path, bool _reliable, bool _enable, bool _default) = 0; + + typedef std::map< + boost::asio::ip::address, + std::pair< + std::string, + std::map< + bool, + std::pair< + boost::icl::interval_set, + boost::icl::interval_set + > + > + > + > sd_acceptance_rules_t; + virtual void set_sd_acceptance_rules(const sd_acceptance_rules_t& _rules, + bool _enable) = 0; + virtual sd_acceptance_rules_t get_sd_acceptance_rules() = 0; + virtual void set_sd_acceptance_rules_active( + const boost::asio::ip::address& _address, bool _enable) = 0; virtual std::uint32_t get_udp_receive_buffer_size() const = 0; diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index f43a97a..e3dc94b 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -72,7 +72,7 @@ public: VSOMEIP_EXPORT bool has_file_log() const; VSOMEIP_EXPORT bool has_dlt_log() const; VSOMEIP_EXPORT const std::string & get_logfile() const; - VSOMEIP_EXPORT boost::log::trivial::severity_level get_loglevel() const; + VSOMEIP_EXPORT vsomeip_v3::logger::level_e get_loglevel() const; VSOMEIP_EXPORT std::string get_unicast_address(service_t _service, instance_t _instance) const; @@ -81,6 +81,13 @@ public: VSOMEIP_EXPORT uint16_t get_unreliable_port(service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT major_version_t get_major_version(service_t _service, + instance_t _instance) const; + VSOMEIP_EXPORT minor_version_t get_minor_version(service_t _service, + instance_t _instance) const; + VSOMEIP_EXPORT ttl_t get_ttl(service_t _service, + instance_t _instance) const; + VSOMEIP_EXPORT void get_configured_timing_requests( service_t _service, std::string _ip_target, std::uint16_t _port_target, method_t _method, @@ -191,13 +198,21 @@ public: VSOMEIP_EXPORT std::uint32_t get_max_tcp_restart_aborts() const; VSOMEIP_EXPORT std::uint32_t get_max_tcp_connect_time() const; - VSOMEIP_EXPORT bool sd_acceptance_required(const boost::asio::ip::address& _address, - std::uint16_t _port) const; - - VSOMEIP_EXPORT void set_sd_acceptance_required( - const boost::asio::ip::address& _address, std::uint16_t _port, - const std::string& _path, bool _enable); - VSOMEIP_EXPORT sd_acceptance_required_map_t get_sd_acceptance_required(); + VSOMEIP_EXPORT bool is_protected_device( + const boost::asio::ip::address& _address) const; + VSOMEIP_EXPORT bool is_protected_port( + const boost::asio::ip::address& _address, + std::uint16_t _port, bool _reliable) const; + + VSOMEIP_EXPORT void set_sd_acceptance_rule( + const boost::asio::ip::address& _address, + port_range_t _port_range, port_type_e _type, + const std::string& _path, bool _reliable, bool _enable, bool _default); + VSOMEIP_EXPORT void set_sd_acceptance_rules( + const sd_acceptance_rules_t& _rules, bool _enable); + VSOMEIP_EXPORT sd_acceptance_rules_t get_sd_acceptance_rules(); + VSOMEIP_EXPORT void set_sd_acceptance_rules_active( + const boost::asio::ip::address& _address, bool _enable); VSOMEIP_EXPORT std::uint32_t get_udp_receive_buffer_size() const; @@ -302,7 +317,8 @@ private: std::map> &_debounces); void load_event_debounce_ignore(const boost::property_tree::ptree &_tree, std::map &_ignore); - void load_sd_acceptance_required(const configuration_element &_element); + void load_acceptances(const configuration_element &_element); + void load_acceptance_data(const boost::property_tree::ptree &_tree); void load_udp_receive_buffer_size(const configuration_element &_element); bool load_npdu_debounce_times_configuration( const std::shared_ptr& _service, @@ -370,7 +386,7 @@ protected: bool has_file_log_; bool has_dlt_log_; std::string logfile_; - boost::log::trivial::severity_level loglevel_; + vsomeip_v3::logger::level_e loglevel_; std::map sd_acceptance_rules_active_; bool has_issued_methods_warning_; bool has_issued_clients_warning_; diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index 36a6355..94a6e66 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -68,6 +68,7 @@ #define VSOMEIP_MAX_TCP_CONNECT_TIME 5000 #define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 +#define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000 #define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5 @@ -84,6 +85,8 @@ #define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 +#define VSOMEIP_MAX_WAIT_SENT 5 + #define VSOMEIP_COMMAND_HEADER_SIZE 7 #define VSOMEIP_COMMAND_TYPE_POS 0 @@ -219,6 +222,13 @@ const std::uint32_t ANY_GID = 0xFFFFFFFF; typedef std::pair credentials_t; +enum class port_type_e { + PT_OPTIONAL, + PT_SECURE, + PT_UNSECURE, + PT_UNKNOWN +}; + } // namespace vsomeip_v3 #endif // VSOMEIP_V3_INTERNAL_HPP_ diff --git a/implementation/configuration/include/internal_android.hpp b/implementation/configuration/include/internal_android.hpp index 9f770ac..ddb4631 100644 --- a/implementation/configuration/include/internal_android.hpp +++ b/implementation/configuration/include/internal_android.hpp @@ -17,6 +17,7 @@ #define VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES "VSOMEIP_MANDATORY_CONFIGURATION_FILES" #define VSOMEIP_ENV_LOAD_PLUGINS "VSOMEIP_LOAD_PLUGINS" #define VSOMEIP_ENV_CLIENTSIDELOGGING "VSOMEIP_CLIENTSIDELOGGING" +#define VSOMEIP_ENV_BASE_PATH "VSOMEIP_BASE_PATH" #define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/etc/vsomeip.json" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" @@ -28,11 +29,11 @@ #define VSOMEIP_BASE_PATH "/storage/" -#define VSOMEIP_CFG_LIBRARY "libvsomeip_cfg.so" +#define VSOMEIP_CFG_LIBRARY "libvsomeip3-cfg.so" -#define VSOMEIP_SD_LIBRARY "libvsomeip_sd.so" +#define VSOMEIP_SD_LIBRARY "libvsomeip3-sd.so" -#define VSOMEIP_E2E_LIBRARY "libvsomeip-e2e.so.3" +#define VSOMEIP_E2E_LIBRARY "libvsomeip3-e2e.so" #define VSOMEIP_ROUTING_CLIENT 0 @@ -51,6 +52,7 @@ #define VSOMEIP_MAX_TCP_CONNECT_TIME 5000 #define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 +#define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000 #define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5 @@ -69,6 +71,8 @@ #define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 +#define VSOMEIP_MAX_WAIT_SENT 5 + #define VSOMEIP_COMMAND_HEADER_SIZE 7 #define VSOMEIP_COMMAND_TYPE_POS 0 diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp index e0e0c72..8077f8e 100644 --- a/implementation/configuration/include/service.hpp +++ b/implementation/configuration/include/service.hpp @@ -25,6 +25,10 @@ struct service { uint16_t reliable_; uint16_t unreliable_; + major_version_t major_; + minor_version_t minor_; + ttl_t ttl_; + std::string multicast_address_; uint16_t multicast_port_; diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 7c0cf6a..eb7b1ea 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #define WIN32_LEAN_AND_MEAN @@ -20,13 +21,14 @@ #include #include #include +#include #include "../include/client.hpp" #include "../include/configuration_impl.hpp" #include "../include/event.hpp" #include "../include/eventgroup.hpp" #include "../include/service.hpp" -#include "../../logging/include/logger_impl.hpp" +#include "../../logger/include/logger_impl.hpp" #include "../../routing/include/event.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../utility/include/utility.hpp" @@ -47,7 +49,7 @@ configuration_impl::configuration_impl() has_file_log_(false), has_dlt_log_(false), logfile_("/tmp/vsomeip.log"), - loglevel_(boost::log::trivial::severity_level::info), + loglevel_(vsomeip_v3::logger::level_e::LL_INFO), is_sd_enabled_(VSOMEIP_SD_DEFAULT_ENABLED), sd_protocol_(VSOMEIP_SD_DEFAULT_PROTOCOL), sd_multicast_(VSOMEIP_SD_DEFAULT_MULTICAST), @@ -184,7 +186,7 @@ configuration_impl::configuration_impl(const configuration_impl &_other) debounces_ = _other.debounces_; endpoint_queue_limits_ = _other.endpoint_queue_limits_; - sd_acceptance_required_ips_ = _other.sd_acceptance_required_ips_; + sd_acceptance_rules_ = _other.sd_acceptance_rules_; has_issued_methods_warning_ = _other.has_issued_methods_warning_; has_issued_clients_warning_ = _other.has_issued_clients_warning_; @@ -258,7 +260,7 @@ bool configuration_impl::load(const std::string &_name) { std::vector its_optional_elements; // Dummy initialization; maybe we'll find no logging configuration - logger_impl::init(shared_from_this()); + logger::logger_impl::init(shared_from_this()); // Look for the standard configuration file read_data(its_input, its_mandatory_elements, its_failed, true); @@ -450,13 +452,14 @@ bool configuration_impl::load_data(const std::vector &_el bool _load_mandatory, bool _load_optional) { // Load logging configuration data std::set its_warnings; + if (!is_logging_loaded_) { for (const auto& e : _elements) is_logging_loaded_ = load_logging(e, its_warnings) || is_logging_loaded_; if (is_logging_loaded_) { - logger_impl::init(shared_from_this()); + logger::logger_impl::init(shared_from_this()); for (auto w : its_warnings) VSOMEIP_WARNING << w; } @@ -496,7 +499,7 @@ bool configuration_impl::load_data(const std::vector &_el load_selective_broadcasts_support(e); load_e2e(e); load_debounce(e); - load_sd_acceptance_required(e); + load_acceptances(e); } } @@ -551,18 +554,18 @@ bool configuration_impl::load_logging( std::string its_value(i->second.data()); loglevel_ = (its_value == "trace" ? - boost::log::trivial::severity_level::trace : + vsomeip_v3::logger::level_e::LL_VERBOSE : (its_value == "debug" ? - boost::log::trivial::severity_level::debug : + vsomeip_v3::logger::level_e::LL_DEBUG : (its_value == "info" ? - boost::log::trivial::severity_level::info : + vsomeip_v3::logger::level_e::LL_INFO : (its_value == "warning" ? - boost::log::trivial::severity_level::warning : + vsomeip_v3::logger::level_e::LL_WARNING : (its_value == "error" ? - boost::log::trivial::severity_level::error : + vsomeip_v3::logger::level_e::LL_ERROR : (its_value == "fatal" ? - boost::log::trivial::severity_level::fatal : - boost::log::trivial::severity_level::info)))))); + vsomeip_v3::logger::level_e::LL_FATAL : + vsomeip_v3::logger::level_e::LL_INFO)))))); is_configured_[ET_LOGGING_LEVEL] = true; } } else if (its_key == "version") { @@ -1416,6 +1419,9 @@ void configuration_impl::load_service( its_service->multicast_address_ = ""; its_service->multicast_port_ = ILLEGAL_PORT; its_service->protocol_ = "someip"; + its_service->major_ = DEFAULT_MAJOR; + its_service->minor_ = DEFAULT_MINOR; + its_service->ttl_ = DEFAULT_TTL; for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -1480,6 +1486,14 @@ void configuration_impl::load_service( its_converter >> its_service->service_; } else if (its_key == "instance") { its_converter >> its_service->instance_; + } else if (its_key == "major") { + unsigned int temp; + its_converter >> temp; + its_service->major_ = static_cast(temp); + } else if (its_key == "minor") { + its_converter >> its_service->minor_; + } else if (its_key == "ttl") { + its_converter >> its_service->ttl_; } } } @@ -1581,10 +1595,10 @@ void configuration_impl::load_event( } else { // If event reliability type was not configured, if (its_reliability == reliability_type_e::RT_UNKNOWN) { - if (_service->reliable_ != ILLEGAL_PORT) { - its_reliability = reliability_type_e::RT_RELIABLE; - } else if (_service->unreliable_ != ILLEGAL_PORT) { + if (_service->unreliable_ != ILLEGAL_PORT) { its_reliability = reliability_type_e::RT_UNRELIABLE; + } else if (_service->reliable_ != ILLEGAL_PORT) { + its_reliability = reliability_type_e::RT_RELIABLE; } VSOMEIP_WARNING << "Reliability type for event [" << std::hex << _service->service_ << "." @@ -2154,7 +2168,7 @@ const std::string & configuration_impl::get_logfile() const { return logfile_; } -boost::log::trivial::severity_level configuration_impl::get_loglevel() const { +vsomeip_v3::logger::level_e configuration_impl::get_loglevel() const { return loglevel_; } @@ -2238,6 +2252,39 @@ void configuration_impl::get_configured_timing_responses( *_max_retention_time = npdu_default_max_retention_resp_; } +major_version_t configuration_impl::get_major_version(service_t _service, + instance_t _instance) const { + std::lock_guard its_lock(services_mutex_); + major_version_t its_major = DEFAULT_MAJOR; + auto its_service = find_service_unlocked(_service, _instance); + if (its_service) + its_major = its_service->major_; + + return its_major; +} + +minor_version_t configuration_impl::get_minor_version(service_t _service, + instance_t _instance) const { + std::lock_guard its_lock(services_mutex_); + minor_version_t its_minor = DEFAULT_MINOR; + auto its_service = find_service_unlocked(_service, _instance); + if (its_service) + its_minor = its_service->minor_; + + return its_minor; +} + +ttl_t configuration_impl::get_ttl(service_t _service, + instance_t _instance) const { + std::lock_guard its_lock(services_mutex_); + ttl_t its_ttl = DEFAULT_TTL; + auto its_service = find_service_unlocked(_service, _instance); + if (its_service) + its_ttl = its_service->ttl_; + + return its_ttl; +} + bool configuration_impl::is_someip(service_t _service, instance_t _instance) const { auto its_service = find_service(_service, _instance); @@ -3206,27 +3253,136 @@ void configuration_impl::load_event_debounce_ignore( } void -configuration_impl::load_sd_acceptance_required( +configuration_impl::load_acceptances( const configuration_element &_element) { - const std::string sar("sd_acceptance_required"); + + std::string its_acceptances_key("acceptances"); + + if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) { + VSOMEIP_WARNING << "Multiple definitions of " << its_acceptances_key + << " Ignoring definition from " << _element.name_; + return; + } + + try { + auto its_acceptances = _element.tree_.get_child(its_acceptances_key); + for (auto i = its_acceptances.begin(); i != its_acceptances.end(); ++i) { + load_acceptance_data(i->second); + } + + is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true; + } catch (...) { + // Intentionally left empty + } +} + +void +configuration_impl::load_acceptance_data( + const boost::property_tree::ptree &_tree) { + + std::stringstream its_converter; try { std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); - if (_element.tree_.get_child_optional(sar)) { - if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) { - VSOMEIP_WARNING << "Multiple definitions of " << sar - << " Ignoring definition from " << _element.name_; - } else { - for (const auto& ipe : _element.tree_.get_child(sar)) { - boost::system::error_code ec; - boost::asio::ip::address its_address = - boost::asio::ip::address::from_string(ipe.first.data(), ec); - if (!its_address.is_unspecified()) { - sd_acceptance_required_ips_[{its_address, ANY_PORT}] = ipe.second.data(); + + boost::asio::ip::address its_address; + std::string its_path; + std::map, + boost::icl::interval_set + > + > its_ports; + bool has_optional, has_secure, is_reliable; + + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + + std::string its_key(i->first); + std::string its_value(i->second.data()); + + if (its_key == "address") { + boost::system::error_code ec; + its_address = boost::asio::ip::address::from_string(its_value); + } else if (its_key == "path") { + its_path = its_value; + } else if (its_key == "reliable" || its_key == "unreliable") { + + is_reliable = (its_key == "reliable"); + has_optional = has_secure = false; + + for (const auto &p : i->second) { + if (p.second.size()) { // range + std::uint16_t its_first(0); + std::uint16_t its_last(0); + port_type_e its_type(port_type_e::PT_OPTIONAL); + + for (const auto& range : p.second) { + const std::string its_key(range.first); + const std::string its_value(range.second.data()); + if (its_key == "first" || its_key == "last" || its_key == "port") { + its_converter << std::dec << its_value; + std::uint16_t its_port_value(0); + its_converter >> its_port_value; + its_converter.str(""); + its_converter.clear(); + if (its_key == "first") { + its_first = its_port_value; + } else if (its_key == "last") { + its_last = its_port_value; + } else if (its_key == "port") { + its_first = its_last = its_port_value; + } + } else if (its_key == "type") { + if (its_value == "secure") { + its_type = port_type_e::PT_SECURE; + } else if (its_value == "optional") { + its_type = port_type_e::PT_OPTIONAL; + } else { + its_type = port_type_e::PT_UNKNOWN; + } + } + } + if (its_type != port_type_e::PT_UNKNOWN) { + if (its_type == port_type_e::PT_OPTIONAL) { + has_optional = true; + if (its_first != 0 && its_last != 0) { + its_ports.operator [](is_reliable).first.insert( + boost::icl::interval::closed(its_first, its_last)); + } + } else { + has_secure = true; + if (its_first != 0 && its_last != 0) { + its_ports.operator [](is_reliable).second.insert( + boost::icl::interval::closed(its_first, its_last)); + } + } + } } } - is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true; + + // If optional was not set, use default! + if (!has_optional) { + const auto its_optional_client = boost::icl::interval::closed(30491, 30499); + const auto its_optional_server = boost::icl::interval::closed(30501, 30599); + + its_ports.operator [](is_reliable).first.insert(its_optional_client); + its_ports.operator [](is_reliable).first.insert(its_optional_server); + } + + // If secure was not set, use default! + if (!has_secure) { + const auto its_secure_client = boost::icl::interval::closed(32491, 32499); + const auto its_secure_server = boost::icl::interval::closed(32501, 32599); + + its_ports.operator [](is_reliable).second.insert(its_secure_client); + its_ports.operator [](is_reliable).second.insert(its_secure_server); + } } } + + if (!its_address.is_unspecified()) { + sd_acceptance_rules_.insert( + std::make_pair(its_address, + std::make_pair(its_path, its_ports))); + } } catch (...) { // intentionally left empty } @@ -3448,37 +3604,189 @@ std::uint32_t configuration_impl::get_max_tcp_connect_time() const { return tcp_connect_time_max_; } -bool configuration_impl::sd_acceptance_required( - const boost::asio::ip::address& _address, std::uint16_t _port) const { +bool configuration_impl::is_protected_device( + const boost::asio::ip::address& _address) const { std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); - return sd_acceptance_required_ips_.find({_address, _port}) - != sd_acceptance_required_ips_.end(); + return (sd_acceptance_rules_active_.find(_address) + != sd_acceptance_rules_active_.end()); } -void configuration_impl::set_sd_acceptance_required( +bool configuration_impl::is_protected_port( const boost::asio::ip::address& _address, std::uint16_t _port, - const std::string& _path, bool _enable) { + bool _reliable) const { + + bool is_required(is_protected_device(_address)); + std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); - if (_enable) { - const auto found_address = sd_acceptance_required_ips_.find({_address, _port}); - if (found_address != sd_acceptance_required_ips_.end()) { - boost::system::error_code ec; - VSOMEIP_WARNING << __func__ << " configuration for: " - << found_address->first.first.to_string(ec) << ":" - << std::dec << _port << " -> " - << found_address->first.second << " already configured." - << " Won't update with: "<< _path; - } else { - sd_acceptance_required_ips_[{_address, _port}] = _path; + const auto found_address = sd_acceptance_rules_.find(_address); + if (found_address != sd_acceptance_rules_.end()) { + const auto found_reliability = found_address->second.second.find(_reliable); + if (found_reliability != found_address->second.second.end()) { + const auto its_range = boost::icl::interval::closed(_port, _port); + + bool is_optional + = (found_reliability->second.first.find(its_range) + != found_reliability->second.first.end()); + + bool is_secure + = (found_reliability->second.second.find(its_range) + != found_reliability->second.second.end()); + + is_required = ((is_required && is_optional) || is_secure); } - } else { - sd_acceptance_required_ips_.erase({_address, _port}); } + + return (is_required); } -configuration::sd_acceptance_required_map_t configuration_impl::get_sd_acceptance_required() { +void configuration_impl::set_sd_acceptance_rule( + const boost::asio::ip::address &_address, + port_range_t _port_range, port_type_e _type, + const std::string &_path, bool _reliable, bool _enable, bool _default) { + + (void)_port_range; + (void)_type; + std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); - return sd_acceptance_required_ips_; + + const auto its_optional_client = boost::icl::interval::closed(30491, 30499); + const auto its_optional_server = boost::icl::interval::closed(30501, 30599); + const auto its_secure_client = boost::icl::interval::closed(32491, 32499); + const auto its_secure_server = boost::icl::interval::closed(32501, 32599); + + const bool rules_active = (sd_acceptance_rules_active_.find(_address) + != sd_acceptance_rules_active_.end()); + + const auto found_address = sd_acceptance_rules_.find(_address); + if (found_address != sd_acceptance_rules_.end()) { + if (found_address->second.first.length() > 0 + && found_address->second.first != _path) { + VSOMEIP_WARNING << __func__ << ": activation path for IP: " + << _address << " differ: " + << found_address->second.first << " vs. " << _path + << " will use: " << found_address->second.first; + } else { + found_address->second.first = _path; + } + const auto found_reliability = found_address->second.second.find(_reliable); + if (found_reliability != found_address->second.second.end()) { + if (_enable) { + // only insert full range interval if there are no other intervals + // configured + if (!_default || + (found_reliability->second.first.empty() + && found_reliability->second.second.empty())) { + found_reliability->second.first.add(its_optional_client); + found_reliability->second.first.add(its_optional_server); + found_reliability->second.second.add(its_secure_client); + found_reliability->second.second.add(its_secure_server); + if (!rules_active) { + sd_acceptance_rules_active_.insert(_address); + } + VSOMEIP_INFO << "ipsec:acceptance:" << _address + << ":" << (_reliable ? "tcp" : "udp") << ": using default ranges " + << found_reliability->second.first << " " + << found_reliability->second.second; + } else { + VSOMEIP_INFO << "ipsec:acceptance:" << _address + << ":" << (_reliable ? "tcp" : "udp") << ": using configured ranges " + << found_reliability->second.first << " " + << found_reliability->second.second; + } + } else { + found_reliability->second.first.erase(its_optional_client); + found_reliability->second.first.erase(its_optional_server); + found_reliability->second.second.erase(its_secure_client); + found_reliability->second.second.erase(its_secure_server); + if (found_reliability->second.first.empty() + && found_reliability->second.second.empty()) { + found_address->second.second.erase(found_reliability); + if (found_address->second.second.empty()) { + sd_acceptance_rules_.erase(found_address); + if (rules_active) {// no more rules for IP present + sd_acceptance_rules_active_.erase(_address); + } + } + } + } + } else if (_enable) { + boost::icl::interval_set its_optional_default; + its_optional_default.add(its_optional_client); + its_optional_default.add(its_optional_server); + boost::icl::interval_set its_secure_default; + its_secure_default.add(its_secure_client); + its_secure_default.add(its_secure_server); + + found_address->second.second.emplace( + std::make_pair(_reliable, + std::make_pair(its_optional_default, its_secure_default))); + if (!rules_active) { + sd_acceptance_rules_active_.insert(_address); + } + + const auto found_reliability = found_address->second.second.find(_reliable); + VSOMEIP_INFO << "ipsec:acceptance:" << _address + << ":" << (_reliable ? "tcp" : "udp") << ": using default ranges " + << found_reliability->second.first << " " + << found_reliability->second.second; + } + } else if (_enable) { + boost::icl::interval_set its_optional_default; + its_optional_default.add(its_optional_client); + its_optional_default.add(its_optional_server); + boost::icl::interval_set its_secure_default; + its_secure_default.add(its_secure_client); + its_secure_default.add(its_secure_server); + + sd_acceptance_rules_.emplace(std::make_pair(_address, + std::make_pair( + _path, + std::map< + bool, + std::pair< + boost::icl::interval_set, + boost::icl::interval_set + > + >({{ + _reliable, + std::make_pair(its_optional_default, its_secure_default) + }})))); + if (!rules_active) { + sd_acceptance_rules_active_.insert(_address); + } + + const auto found_address = sd_acceptance_rules_.find(_address); + if (found_address != sd_acceptance_rules_.end()) { + const auto found_reliability = found_address->second.second.find(_reliable); + if (found_reliability != found_address->second.second.end()) { + VSOMEIP_INFO << "ipsec:acceptance:" << _address + << ":" << (_reliable ? "tcp" : "udp") << ": using default ranges " + << found_reliability->second.first << " " + << found_reliability->second.second; + } + } + } +} + +void configuration_impl::set_sd_acceptance_rules( + const sd_acceptance_rules_t& _rules, bool _enable) { + // Unused, only still available to preserve compatibility + (void)_rules; + (void)_enable; +} + +configuration::sd_acceptance_rules_t configuration_impl::get_sd_acceptance_rules() { + std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); + return sd_acceptance_rules_; +} + +void configuration_impl::set_sd_acceptance_rules_active( + const boost::asio::ip::address& _address, bool _enable) { + if (_enable) { + sd_acceptance_rules_active_.insert(_address); + } else { + sd_acceptance_rules_active_.erase(_address); + } } std::uint32_t configuration_impl::get_udp_receive_buffer_size() const { diff --git a/implementation/endpoints/include/endpoint_manager_impl.hpp b/implementation/endpoints/include/endpoint_manager_impl.hpp index 3f61b7a..cdf41b8 100644 --- a/implementation/endpoints/include/endpoint_manager_impl.hpp +++ b/implementation/endpoints/include/endpoint_manager_impl.hpp @@ -21,11 +21,9 @@ public: std::shared_ptr find_or_create_remote_client(service_t _service, instance_t _instance, - bool _reliable, - client_t _client); + bool _reliable); - void find_or_create_remote_client(service_t _service, instance_t _instance, - client_t _client); + void find_or_create_remote_client(service_t _service, instance_t _instance); void is_remote_service_known( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, @@ -90,15 +88,13 @@ public: private: std::shared_ptr find_remote_client(service_t _service, instance_t _instance, - bool _reliable, - client_t _client); + bool _reliable); std::shared_ptr create_remote_client(service_t _service, instance_t _instance, - bool _reliable, - client_t _client); + bool _reliable); std::shared_ptr create_client_endpoint( const boost::asio::ip::address &_address, uint16_t _local_port, - uint16_t _remote_port, bool _reliable, client_t _client); + uint16_t _remote_port, bool _reliable); private: mutable std::recursive_mutex endpoint_mutex_; @@ -106,8 +102,8 @@ private: std::map>>> remote_service_info_; - typedef std::map>>>> remote_services_t; + typedef std::map>>> remote_services_t; remote_services_t remote_services_; typedef std::map #include +#include +#include + #include #include "client_endpoint_impl.hpp" @@ -79,6 +81,8 @@ private: std::uint32_t get_max_allowed_reconnects() const; void max_allowed_reconnects_reached(); + void wait_until_sent(const boost::system::error_code &_error); + const std::uint32_t recv_buffer_size_initial_; message_buffer_ptr_t recv_buffer_; std::uint32_t shrink_count_; @@ -94,6 +98,11 @@ private: std::uint32_t tcp_connect_time_max_; std::atomic aborted_restart_count_; std::chrono::steady_clock::time_point connect_timepoint_; + + std::mutex sent_mutex_; + bool is_sending_; + boost::asio::steady_timer sent_timer_; + }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index 1a6cef6..db936f3 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -62,9 +62,10 @@ public: bool is_reliable() const; private: + void leave_unlocked(const std::string &_address); void set_broadcast(); void receive_unicast(); - void receive_multicast(); + void receive_multicast(uint8_t _id); bool is_joined(const std::string &_address) const; bool is_joined(const std::string &_address, bool* _received) const; std::string get_remote_information( @@ -80,7 +81,8 @@ private: void on_multicast_received(boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination); + boost::asio::ip::address const &_destination, + uint8_t _multicast_id); void on_message_received(boost::system::error_code const &_error, std::size_t _bytes, @@ -92,19 +94,20 @@ private: socket_type unicast_socket_; endpoint_type unicast_remote_; message_buffer_t unicast_recv_buffer_; - mutable std::mutex unicast_socket_mutex_; + mutable std::mutex unicast_mutex_; std::unique_ptr multicast_socket_; - std::unique_ptr multicast_ep_; + std::unique_ptr multicast_local_; endpoint_type multicast_remote_; - std::unique_ptr multicast_recv_buffer_; - mutable std::mutex multicast_socket_mutex_; + message_buffer_t multicast_recv_buffer_; + mutable std::mutex multicast_mutex_; + uint8_t multicast_id_; + std::map joined_; + std::atomic joined_group_; mutable std::mutex default_targets_mutex_; std::map default_targets_; - mutable std::mutex joined_mutex_; - std::map joined_; - std::atomic joined_group_; + const std::uint16_t local_port_; std::shared_ptr tp_reassembler_; diff --git a/implementation/endpoints/src/endpoint_manager_impl.cpp b/implementation/endpoints/src/endpoint_manager_impl.cpp index 6d37509..d4fedd4 100644 --- a/implementation/endpoints/src/endpoint_manager_impl.cpp +++ b/implementation/endpoints/src/endpoint_manager_impl.cpp @@ -39,14 +39,14 @@ endpoint_manager_impl::endpoint_manager_impl( } std::shared_ptr endpoint_manager_impl::find_or_create_remote_client( - service_t _service, instance_t _instance, bool _reliable, client_t _client) { + service_t _service, instance_t _instance, bool _reliable) { std::shared_ptr its_endpoint; bool start_endpoint(false); { std::lock_guard its_lock(endpoint_mutex_); - its_endpoint = find_remote_client(_service, _instance, _reliable, _client); + its_endpoint = find_remote_client(_service, _instance, _reliable); if (!its_endpoint) { - its_endpoint = create_remote_client(_service, _instance, _reliable, _client); + its_endpoint = create_remote_client(_service, _instance, _reliable); start_endpoint = true; } } @@ -58,22 +58,21 @@ std::shared_ptr endpoint_manager_impl::find_or_create_remote_client( } void endpoint_manager_impl::find_or_create_remote_client( - service_t _service, instance_t _instance, - client_t _client) { + service_t _service, instance_t _instance) { std::shared_ptr its_reliable_endpoint; std::shared_ptr its_unreliable_endpoint; bool start_reliable_endpoint(false); bool start_unreliable_endpoint(false); { std::lock_guard its_lock(endpoint_mutex_); - its_reliable_endpoint = find_remote_client(_service, _instance, true, _client); + its_reliable_endpoint = find_remote_client(_service, _instance, true); if (!its_reliable_endpoint) { - its_reliable_endpoint = create_remote_client(_service, _instance, true, _client); + its_reliable_endpoint = create_remote_client(_service, _instance, true); start_reliable_endpoint = true; } - its_unreliable_endpoint = find_remote_client(_service, _instance, false, _client); + its_unreliable_endpoint = find_remote_client(_service, _instance, false); if (!its_unreliable_endpoint) { - its_unreliable_endpoint = create_remote_client(_service, _instance, false, _client); + its_unreliable_endpoint = create_remote_client(_service, _instance, false); start_unreliable_endpoint = true; } } @@ -285,55 +284,40 @@ void endpoint_manager_impl::clear_client_endpoints(service_t _service, instance_ bool _reliable) { std::shared_ptr endpoint_to_delete; bool other_services_reachable_through_endpoint(false); - std::vector> its_specific_endpoints; { std::lock_guard its_lock(endpoint_mutex_); // Clear client endpoints for remote services (generic and specific ones) - if (remote_services_.find(_service) != remote_services_.end()) { - if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) { - auto endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT][_reliable]; - if (endpoint) { - service_instances_[_service].erase(endpoint.get()); - endpoint_to_delete = endpoint; - } - remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].erase(_reliable); - auto found_endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].find( - !_reliable); - if (found_endpoint == remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].end()) { - remote_services_[_service][_instance].erase(VSOMEIP_ROUTING_CLIENT); - } - } - } - if (remote_services_.find(_service) != remote_services_.end()) { - if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) { - if (!remote_services_[_service][_instance].size()) { - remote_services_[_service].erase(_instance); - if (0 >= remote_services_[_service].size()) { - remote_services_.erase(_service); + const auto found_service = remote_services_.find(_service); + if (found_service != remote_services_.end()) { + const auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + const auto found_reliability = found_instance->second.find(_reliable); + if (found_reliability != found_instance->second.end()) { + service_instances_[_service].erase(found_reliability->second.get()); + endpoint_to_delete = found_reliability->second; + + found_instance->second.erase(found_reliability); + if (found_instance->second.empty()) { + found_service->second.erase(found_instance); + if (found_service->second.empty()) { + remote_services_.erase(found_service); + } } } } } - if (!service_instances_[_service].size()) { - service_instances_.erase(_service); - } - // Only stop and delete the endpoint if none of the services // reachable through it is online anymore. if (endpoint_to_delete) { for (const auto& service : remote_services_) { for (const auto& instance : service.second) { - const auto& client = instance.second.find(VSOMEIP_ROUTING_CLIENT); - if (client != instance.second.end()) { - for (const auto& reliable : client->second) { - if (reliable.second == endpoint_to_delete) { - other_services_reachable_through_endpoint = true; - break; - } - } + const auto found_reliability = instance.second.find(_reliable); + if (found_reliability != instance.second.end() + && found_reliability->second == endpoint_to_delete) { + other_services_reachable_through_endpoint = true; + break; } - if (other_services_reachable_through_endpoint) { break; } } if (other_services_reachable_through_endpoint) { break; } } @@ -381,9 +365,6 @@ void endpoint_manager_impl::clear_client_endpoints(service_t _service, instance_ if (!other_services_reachable_through_endpoint && endpoint_to_delete) { endpoint_to_delete->stop(); } - for (const auto &specific_endpoint : its_specific_endpoints) { - specific_endpoint->stop(); - } } void endpoint_manager_impl::find_or_create_multicast_endpoint( @@ -493,12 +474,10 @@ void endpoint_manager_impl::print_status() const { // udp and tcp client endpoints { client_endpoints_by_ip_t client_endpoints_by_ip; - remote_services_t remote_services; server_endpoints_t server_endpoints; { std::lock_guard its_lock(endpoint_mutex_); client_endpoints_by_ip = client_endpoints_by_ip_; - remote_services = remote_services_; server_endpoints = server_endpoints_; } VSOMEIP_INFO << "status start remote client endpoints:"; @@ -515,24 +494,6 @@ void endpoint_manager_impl::print_status() const { VSOMEIP_INFO << "status end remote client endpoints: " << std::dec << num_remote_client_endpoints; - // selective client endpoints - VSOMEIP_INFO << "status start selective remote client endpoints:"; - std::uint32_t num_remote_selectiv_client_endpoints(0); - for (const auto& s : remote_services) { - for (const auto& i : s.second) { - for (const auto& c : i.second) { - if (c.first != VSOMEIP_ROUTING_CLIENT) { - for (const auto& ur : c.second) { - ur.second->print_status(); - num_remote_selectiv_client_endpoints++; - } - } - } - } - } - VSOMEIP_INFO << "status end selective remote client endpoints: " - << std::dec << num_remote_selectiv_client_endpoints; - VSOMEIP_INFO << "status start server endpoints:"; std::uint32_t num_server_endpoints(1); // local server endpoints @@ -677,36 +638,31 @@ void endpoint_manager_impl::on_connect(std::shared_ptr _endpoint) { std::lock_guard its_lock(endpoint_mutex_); for (auto &its_service : remote_services_) { for (auto &its_instance : its_service.second) { - for (auto &its_client : its_instance.second) { - if (its_client.first == VSOMEIP_ROUTING_CLIENT || - its_client.first == get_client()) { - auto found_endpoint = its_client.second.find(endpoint_is_reliable); - if (found_endpoint != its_client.second.end()) { - if (found_endpoint->second == _endpoint) { - std::shared_ptr its_info( - rm_->find_service(its_service.first, - its_instance.first)); - if (!its_info) { - _endpoint->set_established(true); - return; - } - // only report services offered via TCP+UDP when both - // endpoints are connected - const auto its_other_endpoint = its_info->get_endpoint( - !endpoint_is_reliable); - - if (!its_other_endpoint || (its_other_endpoint - && its_other_endpoint->is_established_or_connected())) { - services_to_report_.push_front( - { its_service.first, - its_instance.first, - its_info->get_major(), - its_info->get_minor(), - _endpoint, - (!endpoint_is_reliable && - !its_other_endpoint)}); - } - } + auto found_endpoint = its_instance.second.find(endpoint_is_reliable); + if (found_endpoint != its_instance.second.end()) { + if (found_endpoint->second == _endpoint) { + std::shared_ptr its_info( + rm_->find_service(its_service.first, + its_instance.first)); + if (!its_info) { + _endpoint->set_established(true); + return; + } + // only report services offered via TCP+UDP when both + // endpoints are connected + const auto its_other_endpoint = its_info->get_endpoint( + !endpoint_is_reliable); + + if (!its_other_endpoint || (its_other_endpoint + && its_other_endpoint->is_established_or_connected())) { + services_to_report_.push_front( + { its_service.first, + its_instance.first, + its_info->get_major(), + its_info->get_minor(), + _endpoint, + (!endpoint_is_reliable && + !its_other_endpoint)}); } } } @@ -728,31 +684,26 @@ void endpoint_manager_impl::on_disconnect(std::shared_ptr _endpoint) { std::lock_guard its_lock(endpoint_mutex_); for (auto &its_service : remote_services_) { for (auto &its_instance : its_service.second) { - for (auto &its_client : its_instance.second) { - if (its_client.first == VSOMEIP_ROUTING_CLIENT || - its_client.first == get_client()) { - const bool is_reliable = _endpoint->is_reliable(); - auto found_endpoint = its_client.second.find(is_reliable); - if (found_endpoint != its_client.second.end()) { - if (found_endpoint->second == _endpoint) { - std::shared_ptr its_info( - rm_->find_service(its_service.first, - its_instance.first)); - if(!its_info){ - return; - } - if (!is_reliable) { - static_cast(rm_)->on_availability( - its_service.first, its_instance.first, - false, its_info->get_major(), - its_info->get_minor()); - } - static_cast(rm_)->service_endpoint_disconnected( - its_service.first, its_instance.first, - its_info->get_major(), - its_info->get_minor(), _endpoint); - } + const bool is_reliable = _endpoint->is_reliable(); + auto found_endpoint = its_instance.second.find(is_reliable); + if (found_endpoint != its_instance.second.end()) { + if (found_endpoint->second == _endpoint) { + std::shared_ptr its_info( + rm_->find_service(its_service.first, + its_instance.first)); + if(!its_info){ + return; + } + if (!is_reliable) { + static_cast(rm_)->on_availability( + its_service.first, its_instance.first, + false, its_info->get_major(), + its_info->get_minor()); } + static_cast(rm_)->service_endpoint_disconnected( + its_service.first, its_instance.first, + its_info->get_major(), + its_info->get_minor(), _endpoint); } } } @@ -780,22 +731,19 @@ void endpoint_manager_impl::release_port(uint16_t _port, bool _reliable) { } std::shared_ptr endpoint_manager_impl::find_remote_client( - service_t _service, instance_t _instance, bool _reliable, client_t _client) { + service_t _service, instance_t _instance, bool _reliable) { std::shared_ptr its_endpoint; auto found_service = remote_services_.find(_service); if (found_service != remote_services_.end()) { auto found_instance = found_service->second.find(_instance); if (found_instance != found_service->second.end()) { - auto found_client = found_instance->second.find(_client); - if (found_client != found_instance->second.end()) { - auto found_reliability = found_client->second.find(_reliable); - if (found_reliability != found_client->second.end()) { - its_endpoint = found_reliability->second; - } + auto found_reliability = found_instance->second.find(_reliable); + if (found_reliability != found_instance->second.end()) { + its_endpoint = found_reliability->second; } } } - if (its_endpoint || _client != VSOMEIP_ROUTING_CLIENT) { + if (its_endpoint) { return its_endpoint; } @@ -821,7 +769,7 @@ std::shared_ptr endpoint_manager_impl::find_remote_client( its_endpoint = found_reliable2->second; // store the endpoint under this service/instance id // as well - needed for later cleanup - remote_services_[_service][_instance][_client][_reliable] = + remote_services_[_service][_instance][_reliable] = its_endpoint; service_instances_[_service][its_endpoint.get()] = _instance; // add endpoint to serviceinfo object @@ -839,7 +787,7 @@ std::shared_ptr endpoint_manager_impl::find_remote_client( } std::shared_ptr endpoint_manager_impl::create_remote_client( - service_t _service, instance_t _instance, bool _reliable, client_t _client) { + service_t _service, instance_t _instance, bool _reliable) { std::shared_ptr its_endpoint; std::shared_ptr its_endpoint_def; uint16_t its_local_port; @@ -868,24 +816,22 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( its_endpoint_def->get_address(), its_local_port, its_endpoint_def->get_port(), - _reliable, _client - ); + _reliable); } if (its_endpoint) { used_client_ports_[_reliable].insert(its_local_port); its_lock.unlock(); service_instances_[_service][its_endpoint.get()] = _instance; - remote_services_[_service][_instance][_client][_reliable] = its_endpoint; - if (_client == VSOMEIP_ROUTING_CLIENT) { - client_endpoints_by_ip_[its_endpoint_def->get_address()] - [its_endpoint_def->get_port()] - [_reliable] = its_endpoint; - // Set the basic route to the service in the service info - auto found_service_info = rm_->find_service(_service, _instance); - if (found_service_info) { - found_service_info->set_endpoint(its_endpoint, _reliable); - } + remote_services_[_service][_instance][_reliable] = its_endpoint; + + client_endpoints_by_ip_[its_endpoint_def->get_address()] + [its_endpoint_def->get_port()] + [_reliable] = its_endpoint; + // Set the basic route to the service in the service info + auto found_service_info = rm_->find_service(_service, _instance); + if (found_service_info) { + found_service_info->set_endpoint(its_endpoint, _reliable); } } } @@ -896,8 +842,7 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( std::shared_ptr endpoint_manager_impl::create_client_endpoint( const boost::asio::ip::address &_address, uint16_t _local_port, uint16_t _remote_port, - bool _reliable, client_t _client) { - (void)_client; + bool _reliable) { std::shared_ptr its_endpoint; boost::asio::ip::address its_unicast = configuration_->get_unicast_address(); @@ -935,6 +880,7 @@ std::shared_ptr endpoint_manager_impl::create_client_endpoint( void endpoint_manager_impl::log_client_states() const { std::stringstream its_log; + client_endpoints_by_ip_t its_client_endpoints; std::vector< std::pair< std::tuple, @@ -944,19 +890,21 @@ endpoint_manager_impl::log_client_states() const { { std::lock_guard its_lock(endpoint_mutex_); - for (const auto its_address : client_endpoints_by_ip_) { - for (const auto its_port : its_address.second) { - for (const auto its_reliability : its_port.second) { - size_t its_queue_size = its_reliability.second->get_queue_size(); - if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE) - its_client_queue_sizes.push_back( - std::make_pair( - std::make_tuple( - its_address.first, - its_port.first, - its_reliability.first), - its_queue_size)); - } + its_client_endpoints = client_endpoints_by_ip_; + } + + for (const auto its_address : its_client_endpoints) { + for (const auto its_port : its_address.second) { + for (const auto its_reliability : its_port.second) { + size_t its_queue_size = its_reliability.second->get_queue_size(); + if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE) + its_client_queue_sizes.push_back( + std::make_pair( + std::make_tuple( + its_address.first, + its_port.first, + its_reliability.first), + its_queue_size)); } } } @@ -989,6 +937,7 @@ endpoint_manager_impl::log_client_states() const { void endpoint_manager_impl::log_server_states() const { std::stringstream its_log; + server_endpoints_t its_server_endpoints; std::vector< std::pair< std::pair, @@ -998,17 +947,19 @@ endpoint_manager_impl::log_server_states() const { { std::lock_guard its_lock(endpoint_mutex_); - for (const auto its_port : server_endpoints_) { - for (const auto its_reliability : its_port.second) { - size_t its_queue_size = its_reliability.second->get_queue_size(); - if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE) - its_client_queue_sizes.push_back( + its_server_endpoints = server_endpoints_; + } + + for (const auto its_port : its_server_endpoints) { + for (const auto its_reliability : its_port.second) { + size_t its_queue_size = its_reliability.second->get_queue_size(); + if (its_queue_size > VSOMEIP_DEFAULT_QUEUE_WARN_SIZE) + its_client_queue_sizes.push_back( + std::make_pair( std::make_pair( - std::make_pair( - its_port.first, - its_reliability.first), - its_queue_size)); - } + its_port.first, + its_reliability.first), + its_queue_size)); } } diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index 2c56521..2a86244 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -49,7 +49,9 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl( send_timeout_warning_(send_timeout_ / 2), tcp_restart_aborts_max_(configuration_->get_max_tcp_restart_aborts()), tcp_connect_time_max_(configuration_->get_max_tcp_connect_time()), - aborted_restart_count_(0) { + aborted_restart_count_(0), + sent_timer_(_io) { + is_supporting_magic_cookies_ = true; } @@ -320,6 +322,10 @@ void tcp_client_endpoint_impl::send_queued() { { std::lock_guard its_lock(socket_mutex_); if (socket_->is_open()) { + { + std::lock_guard its_sent_lock(sent_mutex_); + is_sending_ = true; + } boost::asio::async_write( *socket_, boost::asio::buffer(*its_buffer), @@ -584,9 +590,10 @@ void tcp_client_endpoint_impl::receive_cbk( state_ = cei_state_e::CONNECTING; shutdown_and_close_socket_unlocked(false); its_lock.unlock(); - std::shared_ptr its_ep_host = endpoint_host_.lock(); - its_ep_host->on_disconnect(shared_from_this()); - restart(true); + + // wait_until_sent interprets "no error" as timeout. + // Therefore call it with an error. + wait_until_sent(boost::asio::error::operation_aborted); return; } else if (max_message_size_ != MESSAGE_SIZE_UNLIMITED && current_message_size > max_message_size_) { @@ -612,9 +619,10 @@ void tcp_client_endpoint_impl::receive_cbk( state_ = cei_state_e::CONNECTING; shutdown_and_close_socket_unlocked(false); its_lock.unlock(); - std::shared_ptr its_ep_host = endpoint_host_.lock(); - its_ep_host->on_disconnect(shared_from_this()); - restart(true); + + // wait_until_sent interprets "no error" as timeout. + // Therefore call it with an error. + wait_until_sent(boost::asio::error::operation_aborted); return; } } else if (current_message_size > _recv_buffer_size) { @@ -649,9 +657,10 @@ void tcp_client_endpoint_impl::receive_cbk( state_ = cei_state_e::CONNECTING; shutdown_and_close_socket_unlocked(false); its_lock.unlock(); - std::shared_ptr its_ep_host = endpoint_host_.lock(); - its_ep_host->on_disconnect(shared_from_this()); - restart(true); + + // wait_until_sent interprets "no error" as timeout. + // Therefore call it with an error. + wait_until_sent(boost::asio::error::operation_aborted); return; } } @@ -686,9 +695,10 @@ void tcp_client_endpoint_impl::receive_cbk( state_ = cei_state_e::CONNECTING; shutdown_and_close_socket_unlocked(false); its_lock.unlock(); - std::shared_ptr its_ep_host = endpoint_host_.lock(); - its_ep_host->on_disconnect(shared_from_this()); - restart(true); + + // wait_until_sent interprets "no error" as timeout. + // Therefore call it with an error. + wait_until_sent(boost::asio::error::operation_aborted); } } else { its_lock.unlock(); @@ -813,6 +823,18 @@ void tcp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg) { (void)_bytes; + + { + // Signal that the current send operation has finished. + // Note: Waiting is always done after having closed the socket. + // Therefore, no new send operation will be scheduled. + std::lock_guard its_sent_lock(sent_mutex_); + is_sending_ = false; + + boost::system::error_code ec; + sent_timer_.cancel(ec); + } + if (!_error) { std::lock_guard its_lock(mutex_); if (queue_.size() > 0) { @@ -886,4 +908,26 @@ void tcp_client_endpoint_impl::max_allowed_reconnects_reached() { return; } +void tcp_client_endpoint_impl::wait_until_sent(const boost::system::error_code &_error) { + + std::unique_lock its_sent_lock(sent_mutex_); + if (!is_sending_ || !_error) { + its_sent_lock.unlock(); + if (!_error) + VSOMEIP_WARNING << __func__ + << ": Maximum wait time for send operation exceeded."; + + std::shared_ptr its_ep_host = endpoint_host_.lock(); + its_ep_host->on_disconnect(shared_from_this()); + restart(true); + } else { + std::chrono::milliseconds its_timeout(VSOMEIP_MAX_TCP_SENT_WAIT_TIME); + boost::system::error_code ec; + sent_timer_.expires_from_now(its_timeout, ec); + sent_timer_.async_wait(std::bind(&tcp_client_endpoint_impl::wait_until_sent, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + } +} + } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index ec8c991..6bbd337 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -84,12 +84,17 @@ void udp_client_endpoint_impl::connect() { } } + if (local_.port() == ILLEGAL_PORT) { + // Let the OS assign the port + local_.port(0); + } + #ifndef _WIN32 // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { - if (setsockopt(socket_->native_handle(), - SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (int)its_device.size()) == -1) { + if (!setsockopt(socket_->native_handle(), + SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (int)its_device.size())) { VSOMEIP_WARNING << "UDP Client: Could not bind to device \"" << its_device << "\""; } } diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index 0a65b2e..9d22d51 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -37,6 +37,7 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( _configuration), unicast_socket_(_io, _local.protocol()), unicast_recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0), + multicast_id_(0), joined_group_(false), local_port_(_local.port()), tp_reassembler_(std::make_shared(_configuration->get_max_message_size_unreliable(), _io)), @@ -77,6 +78,7 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( boost::asio::socket_base::broadcast option(true); unicast_socket_.set_option(option, ec); boost::asio::detail::throw_error(ec, "broadcast option"); + const std::uint32_t its_udp_recv_buffer_size = configuration_->get_udp_receive_buffer_size(); unicast_socket_.set_option(boost::asio::socket_base::receive_buffer_size( @@ -124,9 +126,8 @@ void udp_server_endpoint_impl::start() { void udp_server_endpoint_impl::stop() { server_endpoint_impl::stop(); - { - std::lock_guard its_lock(unicast_socket_mutex_); + std::lock_guard its_lock(unicast_mutex_); if (unicast_socket_.is_open()) { boost::system::error_code its_error; @@ -136,7 +137,7 @@ void udp_server_endpoint_impl::stop() { } { - std::lock_guard its_lock(multicast_socket_mutex_); + std::lock_guard its_lock(multicast_mutex_); if (multicast_socket_ && multicast_socket_->is_open()) { boost::system::error_code its_error; @@ -150,11 +151,11 @@ void udp_server_endpoint_impl::stop() { void udp_server_endpoint_impl::receive() { receive_unicast(); - receive_multicast(); } void udp_server_endpoint_impl::receive_unicast() { - std::lock_guard its_lock(unicast_socket_mutex_); + + std::lock_guard its_lock(unicast_mutex_); if(unicast_socket_.is_open()) { unicast_socket_.async_receive_from( @@ -172,12 +173,14 @@ void udp_server_endpoint_impl::receive_unicast() { } } -void udp_server_endpoint_impl::receive_multicast() { - std::lock_guard its_lock(multicast_socket_mutex_); +// +// receive_multicast is called with multicast_mutex_ being hold +// +void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) { - if (multicast_socket_ && multicast_socket_->is_open()) { + if (_multicast_id == multicast_id_ && multicast_socket_ && multicast_socket_->is_open()) { multicast_socket_->async_receive_from( - boost::asio::buffer(&(*multicast_recv_buffer_)[0], max_message_size_), + boost::asio::buffer(&multicast_recv_buffer_[0], max_message_size_), multicast_remote_, std::bind( &udp_server_endpoint_impl::on_multicast_received, @@ -185,7 +188,8 @@ void udp_server_endpoint_impl::receive_multicast() { udp_server_endpoint_impl >(shared_from_this()), std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3 + std::placeholders::_3, + _multicast_id ) ); } @@ -194,6 +198,7 @@ void udp_server_endpoint_impl::receive_multicast() { bool udp_server_endpoint_impl::send_to( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + std::lock_guard its_lock(mutex_); endpoint_type its_target(_target->get_address(), _target->get_port()); return send_intern(its_target, _data, _size); @@ -202,6 +207,7 @@ bool udp_server_endpoint_impl::send_to( bool udp_server_endpoint_impl::send_error( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + bool ret(false); std::lock_guard its_lock(mutex_); const endpoint_type its_target(_target->get_address(), _target->get_port()); @@ -236,64 +242,72 @@ void udp_server_endpoint_impl::send_queued( << (int)(*its_buffer)[i] << " "; VSOMEIP_INFO << msg.str(); #endif - std::lock_guard its_lock(unicast_socket_mutex_); + std::lock_guard its_lock(unicast_mutex_); unicast_socket_.async_send_to( - boost::asio::buffer(*its_buffer), - _queue_iterator->first, - std::bind( - &udp_server_endpoint_base_impl::send_cbk, - shared_from_this(), - _queue_iterator, - std::placeholders::_1, - std::placeholders::_2 - ) - ); + boost::asio::buffer(*its_buffer), + _queue_iterator->first, + std::bind( + &udp_server_endpoint_base_impl::send_cbk, + shared_from_this(), + _queue_iterator, + std::placeholders::_1, + std::placeholders::_2 + ) + ); } void udp_server_endpoint_impl::get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, std::chrono::nanoseconds *_maximum_retention) const { + configuration_->get_configured_timing_responses(_service, udp_server_endpoint_base_impl::local_.address().to_string(), udp_server_endpoint_base_impl::local_.port(), _method, _debouncing, _maximum_retention); } +// +// Both is_joined - methods must be called with multicast_mutex_ being hold! +// bool udp_server_endpoint_impl::is_joined(const std::string &_address) const { - std::lock_guard its_lock(joined_mutex_); + return (joined_.find(_address) != joined_.end()); } bool udp_server_endpoint_impl::is_joined( const std::string &_address, bool* _received) const { - *_received = false; - std::lock_guard its_lock(joined_mutex_); + const auto found_address = joined_.find(_address); if (found_address != joined_.end()) { *_received = found_address->second; + } else { + *_received = false; } + return (found_address != joined_.end()); } void udp_server_endpoint_impl::join(const std::string &_address) { + bool has_received(false); + // + // join_func must be called with multicast_mutex_ being hold! + // auto join_func = [this](const std::string &_address) { try { - VSOMEIP_TRACE << "Joining to multicast group " << _address + VSOMEIP_DEBUG << "Joining to multicast group " << _address << " from " << local_.address().to_string(); boost::system::error_code ec; - if (!multicast_recv_buffer_) { - multicast_recv_buffer_ = std::unique_ptr( - new message_buffer_t(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0)); - } + if (multicast_recv_buffer_.empty()) + multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0); - if (!multicast_ep_) { - multicast_ep_ = std::unique_ptr( + if (!multicast_local_) { + multicast_local_ = std::unique_ptr( new endpoint_type(boost::asio::ip::address_v4::any(), local_port_)); } @@ -305,7 +319,7 @@ void udp_server_endpoint_impl::join(const std::string &_address) { multicast_socket_->set_option(optionReuseAddress, ec); boost::asio::detail::throw_error(ec, "reuse address in multicast"); - multicast_socket_->bind(*multicast_ep_, ec); + multicast_socket_->bind(*multicast_local_, ec); boost::asio::detail::throw_error(ec, "bind multicast"); const std::uint32_t its_udp_recv_buffer_size = @@ -342,8 +356,8 @@ void udp_server_endpoint_impl::join(const std::string &_address) { ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IP, IP_PKTINFO, &optval, sizeof(optval)); #endif - - receive_multicast(); + multicast_id_++; + receive_multicast(multicast_id_); } bool is_v4(false); @@ -355,55 +369,50 @@ void udp_server_endpoint_impl::join(const std::string &_address) { } if (is_v4) { - std::lock_guard its_lock(multicast_socket_mutex_); multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true)); multicast_socket_->set_option( boost::asio::ip::multicast::enable_loopback(false)); -#ifdef _WIN32 multicast_socket_->set_option(boost::asio::ip::multicast::join_group( boost::asio::ip::address::from_string(_address).to_v4(), local_.address().to_v4())); -#else - multicast_socket_->set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string(_address).to_v4())); -#endif } else if (is_v6) { - std::lock_guard its_lock(multicast_socket_mutex_); multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true)); multicast_socket_->set_option( boost::asio::ip::multicast::enable_loopback(false)); -#ifdef _WIN32 multicast_socket_->set_option(boost::asio::ip::multicast::join_group( boost::asio::ip::address::from_string(_address).to_v6(), local_.address().to_v6().scope_id())); -#else - multicast_socket_->set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string(_address).to_v6())); -#endif - } - { - std::lock_guard its_lock(joined_mutex_); - joined_[_address] = false; } + + joined_[_address] = false; joined_group_ = true; + } catch (const std::exception &e) { VSOMEIP_ERROR << "udp_server_endpoint_impl::join" << ":" << e.what(); } }; + std::lock_guard its_lock(multicast_mutex_); if (!is_joined(_address, &has_received)) { join_func(_address); } else if (!has_received) { // joined the multicast group but didn't receive a event yet -> rejoin - leave(_address); + leave_unlocked(_address); join_func(_address); } } void udp_server_endpoint_impl::leave(const std::string &_address) { + + std::lock_guard its_lock(multicast_mutex_); + leave_unlocked(_address); +} + +void udp_server_endpoint_impl::leave_unlocked(const std::string &_address) { + try { if (is_joined(_address)) { - VSOMEIP_TRACE << "Leaving the multicast group " << _address + VSOMEIP_DEBUG << "Leaving the multicast group " << _address << " from " << local_.address().to_string(); bool is_v4(false); @@ -414,24 +423,22 @@ void udp_server_endpoint_impl::leave(const std::string &_address) { is_v6 = local_.address().is_v6(); } if (is_v4) { - std::lock_guard its_lock(multicast_socket_mutex_); multicast_socket_->set_option(boost::asio::ip::multicast::leave_group( boost::asio::ip::address::from_string(_address))); } else if (is_v6) { - std::lock_guard its_lock(multicast_socket_mutex_); multicast_socket_->set_option(boost::asio::ip::multicast::leave_group( boost::asio::ip::address::from_string(_address))); } - { - std::lock_guard its_lock(joined_mutex_); - joined_.erase(_address); - if (!joined_.size()) { - joined_group_ = false; - - multicast_socket_.reset(nullptr); - multicast_ep_.reset(nullptr); - multicast_recv_buffer_.reset(nullptr); - } + + joined_.erase(_address); + if (0 == joined_.size()) { + joined_group_ = false; + + boost::system::error_code ec; + multicast_socket_->cancel(ec); + + multicast_socket_.reset(nullptr); + multicast_local_.reset(nullptr); } } } @@ -473,21 +480,36 @@ void udp_server_endpoint_impl::on_unicast_received( boost::system::error_code const &_error, std::size_t _bytes, boost::asio::ip::address const &_destination) { - on_message_received(_error, _bytes, _destination, unicast_remote_, unicast_recv_buffer_); - receive_unicast(); + + if (_error != boost::asio::error::operation_aborted) { + { + // By locking the multicast mutex here it is ensured that unicast + // & multicast messages are not processed in parallel. This aligns + // the behavior of endpoints with one and two active sockets. + std::lock_guard its_lock(multicast_mutex_); + on_message_received(_error, _bytes, _destination, + unicast_remote_, unicast_recv_buffer_); + } + receive_unicast(); + } } void udp_server_endpoint_impl::on_multicast_received( boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination) { + boost::asio::ip::address const &_destination, + uint8_t _multicast_id) { + + std::lock_guard its_lock(multicast_mutex_); + if (_error != boost::asio::error::operation_aborted) { + // Filter messages sent from the same source address + if (multicast_remote_.address() != local_.address()) { + on_message_received(_error, _bytes, _destination, + multicast_remote_, multicast_recv_buffer_); + } - // Filter messages sent from the same source address - if (multicast_remote_.address() != local_.address()) { - on_message_received(_error, _bytes, _destination, multicast_remote_, *multicast_recv_buffer_); + receive_multicast(_multicast_id); } - - receive_multicast(); } void udp_server_endpoint_impl::on_message_received( @@ -579,7 +601,6 @@ void udp_server_endpoint_impl::on_message_received( } else if (its_service != VSOMEIP_SD_SERVICE && utility::is_notification(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS]) && joined_group_) { - std::lock_guard its_lock(joined_mutex_); boost::system::error_code ec; const auto found_address = joined_.find(_destination.to_string(ec)); if (found_address != joined_.end()) { @@ -599,14 +620,12 @@ void udp_server_endpoint_impl::on_message_received( const session_t its_session = VSOMEIP_BYTES_TO_WORD( res.second[VSOMEIP_SESSION_POS_MIN], res.second[VSOMEIP_SESSION_POS_MAX]); - clients_mutex_.lock(); + std::lock_guard its_client_lock(clients_mutex_); clients_[its_client][its_session] = _remote; - clients_mutex_.unlock(); } } else if (its_service != VSOMEIP_SD_SERVICE && utility::is_notification(res.second[VSOMEIP_MESSAGE_TYPE_POS]) && joined_group_) { - std::lock_guard its_lock(joined_mutex_); boost::system::error_code ec; const auto found_address = joined_.find(_destination.to_string(ec)); if (found_address != joined_.end()) { @@ -668,9 +687,10 @@ void udp_server_endpoint_impl::print_status() { VSOMEIP_INFO << "status use: " << std::dec << local_port_ << " number queues: " << std::dec << queues_.size() - << " recv_buffer: " << std::dec << unicast_recv_buffer_.capacity() - << " multicast_recv_buffer: " << std::dec - << (multicast_recv_buffer_ ? multicast_recv_buffer_->capacity() : 0); + << " recv_buffer: " + << std::dec << unicast_recv_buffer_.capacity() + << " multicast_recv_buffer: " + << std::dec << multicast_recv_buffer_.capacity(); for (const auto &c : queues_) { std::size_t its_data_size(0); @@ -706,7 +726,8 @@ bool udp_server_endpoint_impl::is_reliable() const { } const std::string udp_server_endpoint_impl::get_address_port_local() const { - std::lock_guard its_lock(unicast_socket_mutex_); + + std::lock_guard its_lock(unicast_mutex_); std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -721,8 +742,9 @@ const std::string udp_server_endpoint_impl::get_address_port_local() const { return its_address_port; } -bool udp_server_endpoint_impl::tp_segmentation_enabled(service_t _service, - method_t _method) const { +bool udp_server_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + return configuration_->tp_segment_messages_service_to_client(_service, local_.address().to_string(), local_.port(), _method); diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp index fcf04c1..81485ff 100644 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp @@ -37,7 +37,7 @@ public: reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, const MutableBufferSequence& buffers, Endpoint& endpoint, socket_base::message_flags flags, func_type complete_func) - : reactor_op(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), + : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), socket_(socket), protocol_type_(protocol_type), buffers_(buffers), diff --git a/implementation/logger/include/logger_impl.hpp b/implementation/logger/include/logger_impl.hpp new file mode 100644 index 0000000..bb83363 --- /dev/null +++ b/implementation/logger/include/logger_impl.hpp @@ -0,0 +1,53 @@ +// Copyright (C) 2014-2017 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_V3_LOGGER_CONFIGURATION_HPP_ +#define VSOMEIP_V3_LOGGER_CONFIGURATION_HPP_ + +#include +#include + +#ifdef USE_DLT +#include +#endif + +#include + +namespace vsomeip_v3 { + +class configuration; + +namespace logger { + +class logger_impl { +public: + VSOMEIP_IMPORT_EXPORT static void init(const std::shared_ptr &_configuration); + static std::shared_ptr get(); + + logger_impl() = default; + ~logger_impl(); + + std::shared_ptr get_configuration() const; + +#ifdef USE_DLT + void log(level_e _level, const char *_data); + +private: + void enable_dlt(const std::string &_application, const std::string &_context); +#endif + +private: + static std::mutex mutex__; + std::shared_ptr configuration_; + +#ifdef USE_DLT + DLT_DECLARE_CONTEXT(dlt_); +#endif +}; + +} // namespace logger +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_LOGGER_CONFIGURATION_HPP_ diff --git a/implementation/logger/src/logger_impl.cpp b/implementation/logger/src/logger_impl.cpp new file mode 100644 index 0000000..7e79aa2 --- /dev/null +++ b/implementation/logger/src/logger_impl.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2020 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 + +#include + +#include "../include/logger_impl.hpp" +#include "../../configuration/include/configuration.hpp" + +namespace vsomeip_v3 { +namespace logger { + +std::mutex logger_impl::mutex__; + +void +logger_impl::init(const std::shared_ptr &_configuration) { + std::lock_guard its_lock(mutex__); + auto its_logger = logger_impl::get(); + its_logger->configuration_ = _configuration; + +#ifdef USE_DLT +# define VSOMEIP_LOG_DEFAULT_CONTEXT_ID "VSIP" +# define VSOMEIP_LOG_DEFAULT_CONTEXT_NAME "vSomeIP context" + + std::string its_context_id = runtime::get_property("LogContext"); + if (its_context_id == "") + its_context_id = VSOMEIP_LOG_DEFAULT_CONTEXT_ID; + + DLT_REGISTER_CONTEXT(its_logger->dlt_, its_context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME); +#endif +} + +logger_impl::~logger_impl() { +#ifdef USE_DLT + DLT_UNREGISTER_CONTEXT(dlt_); +#endif +} + +std::shared_ptr +logger_impl::get_configuration() const { + return configuration_; +} + +#ifdef USE_DLT +void +logger_impl::log(level_e _level, const char *_data) { + + // Prepare log level + DltLogLevelType its_level; + switch (_level) { + case level_e::LL_FATAL: + its_level = DLT_LOG_FATAL; + break; + case level_e::LL_ERROR: + its_level = DLT_LOG_ERROR; + break; + case level_e::LL_WARNING: + its_level = DLT_LOG_WARN; + break; + case level_e::LL_INFO: + its_level = DLT_LOG_INFO; + break; + case level_e::LL_DEBUG: + its_level = DLT_LOG_DEBUG; + break; + case level_e::LL_VERBOSE: + its_level = DLT_LOG_VERBOSE; + break; + default: + its_level = DLT_LOG_DEFAULT; + }; + + DLT_LOG_STRING(dlt_, its_level, _data); +} +#endif + +static std::shared_ptr *the_logger_ptr__(nullptr); +static std::mutex the_logger_mutex__; + +std::shared_ptr +logger_impl::get() { +#ifndef _WIN32 + std::lock_guard its_lock(the_logger_mutex__); +#endif + if (the_logger_ptr__ == nullptr) { + the_logger_ptr__ = new std::shared_ptr(); + } + if (the_logger_ptr__ != nullptr) { + if (!(*the_logger_ptr__)) { + *the_logger_ptr__ = std::make_shared(); + } + return (*the_logger_ptr__); + } + return (nullptr); +} + +#ifndef _WIN32 +static void logger_impl_teardown(void) __attribute__((destructor)); +static void logger_impl_teardown(void) +{ + if (the_logger_ptr__ != nullptr) { + std::lock_guard its_lock(the_logger_mutex__); + the_logger_ptr__->reset(); + delete the_logger_ptr__; + the_logger_ptr__ = nullptr; + } +} +#endif + +} // namespace logger +} // namespace vsomeip_v3 diff --git a/implementation/logger/src/message.cpp b/implementation/logger/src/message.cpp new file mode 100644 index 0000000..363db37 --- /dev/null +++ b/implementation/logger/src/message.cpp @@ -0,0 +1,157 @@ +// Copyright (C) 2020 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 +#include +#include +#include +#include + +#ifdef ANDROID +#include +#endif + +#include + +#include "../include/logger_impl.hpp" +#include "../../configuration/include/configuration.hpp" + +namespace vsomeip_v3 { +namespace logger { + +std::mutex message::mutex__; + +message::message(level_e _level) + : std::ostream(&buffer_), + level_(_level) { + + when_ = std::chrono::system_clock::now(); +} + +message::~message() { + std::lock_guard its_lock(mutex__); + auto its_logger = logger_impl::get(); + auto its_configuration = its_logger->get_configuration(); + + if (!its_configuration) + return; + + if (level_ > its_configuration->get_loglevel()) + return; + + if (its_configuration->has_console_log() + || its_configuration->has_file_log()) { + + // Prepare log level + const char *its_level; + switch (level_) { + case level_e::LL_FATAL: + its_level = "fatal"; + break; + case level_e::LL_ERROR: + its_level = "error"; + break; + case level_e::LL_WARNING: + its_level = "warning"; + break; + case level_e::LL_INFO: + its_level = "info"; + break; + case level_e::LL_DEBUG: + its_level = "debug"; + break; + case level_e::LL_VERBOSE: + its_level = "verbose"; + break; + default: + its_level = "none"; + }; + + // Prepare time stamp + auto its_time_t = std::chrono::system_clock::to_time_t(when_); + auto its_time = std::localtime(&its_time_t); + auto its_ms = (when_.time_since_epoch().count() / 100) % 1000000; + + if (its_configuration->has_console_log()) { +#ifndef ANDROID + std::cout + << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " " + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "." + << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" + << its_level << "] " + << buffer_.data_.str() + << std::endl; +#else + switch (level_) { + case level_e::LL_FATAL: + ALOGE(buffer_.data_.str()); + break; + case level_e::LL_ERROR: + ALOGE(buffer_.data_.str()); + break; + case level_e::LL_WARNING: + ALOGW(buffer_.data_.str()); + break; + case level_e::LL_INFO: + ALOGI(buffer_.data_.str()); + break; + case level_e::LL_DEBUG: + ALOGD(buffer_.data_.str()); + break; + case level_e::LL_VERBOSE: + ALOGV(buffer_.data_.str()); + break; + default: + ALOGI(buffer_.data_.str()); + }; +#endif // !ANDROID + } + + if (its_configuration->has_file_log()) { + std::ofstream its_logfile( + its_configuration->get_logfile(), + std::ios_base::app); + if (its_logfile.is_open()) { + its_logfile + << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " " + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "." + << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" + << its_level << "] " + << buffer_.data_.str() + << std::endl; + } + } + } else if (its_configuration->has_dlt_log()) { +#ifdef USE_DLT + its_logger->log(level_, buffer_.data_.str().c_str()); +#endif // USE_DLT + } +} + +std::streambuf::int_type +message::buffer::overflow(std::streambuf::int_type c) { + if (c != EOF) { + data_ << (char)c; + } + + return (c); +} + +std::streamsize +message::buffer::xsputn(const char *s, std::streamsize n) { + data_.write(s, n); + return (n); +} + +} // namespace logger +} // namespace vsomeip_v3 diff --git a/implementation/logging/include/android_sink_backend.hpp b/implementation/logging/include/android_sink_backend.hpp deleted file mode 100644 index defda48..0000000 --- a/implementation/logging/include/android_sink_backend.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2014-2017 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_V3_ANDROID_SINK_BACKEND_HPP_ -#define VSOMEIP_V3_ANDROID_SINK_BACKEND_HPP_ - -#include -#include -#include - -namespace logging = boost::log; -namespace sinks = boost::log::sinks; - -namespace vsomeip_v3 { - -class android_sink_backend : - public sinks::basic_sink_backend< - sinks::combine_requirements< - sinks::synchronized_feeding - >::type - > { -public: - android_sink_backend(); - virtual ~android_sink_backend(); - - void consume(const logging::record_view &rec); -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_ANDROID_SINK_BACKEND_HPP_ diff --git a/implementation/logging/include/defines.hpp b/implementation/logging/include/defines.hpp deleted file mode 100644 index de5142d..0000000 --- a/implementation/logging/include/defines.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) 2014-2017 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 LOGGING_DEFINES_HPP_ -#define LOGGING_DEFINES_HPP_ - -#define VSOMEIP_LOG_DEFAULT_CONTEXT_ID "VSIP" -#define VSOMEIP_LOG_DEFAULT_CONTEXT_NAME "vSomeIP context" - -#endif /* LOGGING_DEFINES_HPP_ */ diff --git a/implementation/logging/include/dlt_sink_backend.hpp b/implementation/logging/include/dlt_sink_backend.hpp deleted file mode 100644 index 73a9e79..0000000 --- a/implementation/logging/include/dlt_sink_backend.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2014-2017 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_V3_DLT_SINK_BACKEND_HPP_ -#define VSOMEIP_V3_DLT_SINK_BACKEND_HPP_ - -#ifdef USE_DLT -#include -#endif - -#include -#include -#include - -namespace logging = boost::log; -namespace sinks = boost::log::sinks; - -namespace vsomeip_v3 { - -class dlt_sink_backend : - public sinks::basic_sink_backend< - sinks::combine_requirements< - sinks::synchronized_feeding - >::type - > { -public: - dlt_sink_backend(const std::string &_app_id, - const std::string &_context_id); - virtual ~dlt_sink_backend(); - - void consume(const logging::record_view &rec); - -private: - -#ifdef USE_DLT - DltLogLevelType level_as_dlt(logging::trivial::severity_level _level); - DLT_DECLARE_CONTEXT(dlt_) -#endif -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_DLT_SINK_BACKEND_HPP_ diff --git a/implementation/logging/include/logger_impl.hpp b/implementation/logging/include/logger_impl.hpp deleted file mode 100644 index 4556f0d..0000000 --- a/implementation/logging/include/logger_impl.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2014-2017 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_V3_LOGGER_IMPL_HPP -#define VSOMEIP_V3_LOGGER_IMPL_HPP - -#include -#include - -#include -#include -#include -#include - -#include -#include "dlt_sink_backend.hpp" -#include "android_sink_backend.hpp" - -namespace vsomeip_v3 { - -class configuration; - -BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string) -BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", - boost::log::trivial::severity_level) - -typedef boost::log::sinks::synchronous_sink< - boost::log::sinks::text_ostream_backend> sink_t; -typedef boost::log::sinks::synchronous_sink< - dlt_sink_backend> dlt_sink_t; -typedef boost::log::sinks::synchronous_sink< - android_sink_backend> android_sink_t; - -class logger_impl: public logger { -public: - static std::shared_ptr & get(); - VSOMEIP_IMPORT_EXPORT static void init(const std::shared_ptr &_configuration); - - logger_impl(); - - boost::log::sources::severity_logger_mt< - boost::log::trivial::severity_level> & get_internal(); - -private: - void enable_console(); - void disable_console(); - - void enable_file(const std::string &_path); - void disable_file(); - - void enable_dlt(const std::string &_app_id, - const std::string &_context_id); - void disable_dlt(); - - void enable_android(); - void disable_android(); - -private: - boost::log::sources::severity_logger_mt< - boost::log::trivial::severity_level> logger_; - boost::log::trivial::severity_level loglevel_; - - boost::shared_ptr console_sink_; - boost::shared_ptr file_sink_; - boost::shared_ptr dlt_sink_; - boost::shared_ptr android_sink_; - boost::log::core_ptr log_core_; - -private: - void use_null_logger(); -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_LOGGER_IMPL_HPP diff --git a/implementation/logging/src/android_sink_backend.cpp b/implementation/logging/src/android_sink_backend.cpp deleted file mode 100644 index bde7afb..0000000 --- a/implementation/logging/src/android_sink_backend.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2014-2017 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 "../include/android_sink_backend.hpp" - -#define LOG_TAG "vSomeIP" - -#ifdef ANDROID -#include -#endif - -#include -#include "../include/defines.hpp" - -namespace expressions = boost::log::expressions; - -namespace vsomeip_v3 -{ - -android_sink_backend::android_sink_backend() { - -} - -android_sink_backend::~android_sink_backend() { - -} - -BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level) - -void android_sink_backend::consume(const logging::record_view &rec) { -#ifdef ANDROID - auto message = rec[expressions::smessage].get().c_str(); - auto severity_level = rec[severity]; - - switch (*severity_level) { - case logging::trivial::fatal: - ALOGE(message); - break; - case logging::trivial::error: - ALOGE(message); - break; - case logging::trivial::warning: - ALOGW(message); - break; - case logging::trivial::info: - ALOGI(message); - break; - case logging::trivial::debug: - ALOGD(message); - break; - case logging::trivial::trace: - ALOGV(message); - break; - default: - ALOGI(message); - break; - } - -#else - (void)rec; -#endif -} - -} // namespace vsomeip_v3 diff --git a/implementation/logging/src/dlt_sink_backend.cpp b/implementation/logging/src/dlt_sink_backend.cpp deleted file mode 100644 index d38039c..0000000 --- a/implementation/logging/src/dlt_sink_backend.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2014-2017 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 "../include/dlt_sink_backend.hpp" - -#ifdef USE_DLT -#include -#endif - -#include -#include "../include/defines.hpp" - -namespace expressions = boost::log::expressions; - -namespace vsomeip_v3 -{ - -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(dlt_, _context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME); -#else - (void)_context_id; -#endif -} - -dlt_sink_backend::~dlt_sink_backend() { -#ifdef USE_DLT - DLT_UNREGISTER_CONTEXT(dlt_); -#endif -} - -BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level) - -void dlt_sink_backend::consume(const logging::record_view &rec) { -#ifdef USE_DLT - auto message = rec[expressions::smessage]; - auto severity_level = rec[severity]; - DLT_LOG_STRING(dlt_, (severity_level)?level_as_dlt(*severity_level):DLT_LOG_WARN, - (message)?message.get().c_str():"consume() w/o message"); -#else - (void)rec; -#endif -} - -#ifdef USE_DLT -DltLogLevelType dlt_sink_backend::level_as_dlt(logging::trivial::severity_level _level) { - switch (_level) { - case logging::trivial::fatal: - return DLT_LOG_FATAL; - case logging::trivial::error: - return DLT_LOG_ERROR; - case logging::trivial::warning: - return DLT_LOG_WARN; - case logging::trivial::info: - return DLT_LOG_INFO; - case logging::trivial::debug: - return DLT_LOG_DEBUG; - case logging::trivial::trace: - return DLT_LOG_VERBOSE; - default: - return DLT_LOG_DEFAULT; - } -} -#endif - -} // namespace vsomeip_v3 diff --git a/implementation/logging/src/logger.cpp b/implementation/logging/src/logger.cpp deleted file mode 100644 index 9e22fd0..0000000 --- a/implementation/logging/src/logger.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2014-2017 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 "../include/logger_impl.hpp" - -namespace vsomeip_v3 { - -std::shared_ptr logger::get() { - return logger_impl::get(); -} - -} // namespace vsomeip_v3l diff --git a/implementation/logging/src/logger_impl.cpp b/implementation/logging/src/logger_impl.cpp deleted file mode 100644 index ec3aa9b..0000000 --- a/implementation/logging/src/logger_impl.cpp +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (C) 2014-2017 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// The "empty_deleter"-struct was moved from the log-package -// to the more generic "utility"-package in V1.55. If we'd -// use the "old" include, we get a "deprecation" warning -// when compiling with the newer boost version. Therefore a -// version dependent include handling is done here, which -// can/should be removed in case GPT is updating Boost to V1.55. -#if BOOST_VERSION < 105500 -#include -#elif BOOST_VERSION < 105600 -#include -#else -#include -#endif - -#include - -#include "../include/logger_impl.hpp" -#include "../../configuration/include/configuration.hpp" -#include "../include/defines.hpp" - -namespace logging = boost::log; -namespace sources = boost::log::sources; -namespace sinks = boost::log::sinks; -namespace keywords = boost::log::keywords; -namespace expressions = boost::log::expressions; -namespace attributes = boost::log::attributes; - -using namespace boost::log::trivial; - -namespace vsomeip_v3 { - -std::shared_ptr & logger_impl::get() { - static std::shared_ptr the_logger__ = std::make_shared< - logger_impl>(); - return the_logger__; -} - -logger_impl::logger_impl() - : loglevel_(debug), - log_core_(logging::core::get()) { - logging::add_common_attributes(); -} - -boost::log::sources::severity_logger_mt & -logger_impl::get_internal() { - return logger_; -} - -void logger_impl::init(const std::shared_ptr &_configuration) { - get()->loglevel_ = _configuration->get_loglevel(); - logging::core::get()->set_exception_handler(boost::log::make_exception_suppressor()); - logging::core::get()->set_filter( - logging::trivial::severity >= get()->loglevel_); - - if (_configuration->has_console_log()) { - get()->enable_console(); -#ifdef ANDROID - get()->enable_android(); -#endif - } else { - get()->disable_console(); - } - - if (_configuration->has_file_log()) - get()->enable_file(_configuration->get_logfile()); - else - get()->disable_file(); - - if (_configuration->has_dlt_log()) { - std::string app_id = runtime::get_property("LogApplication"); - if (app_id == "") app_id = VSOMEIP_LOG_DEFAULT_APPLICATION_ID; - std::string context_id = runtime::get_property("LogContext"); - if (context_id == "") context_id = VSOMEIP_LOG_DEFAULT_CONTEXT_ID; - get()->enable_dlt(app_id, context_id); - } else - get()->disable_dlt(); - - if (!_configuration->has_console_log() && - !_configuration->has_file_log() && - !_configuration->has_dlt_log()) { - get()->use_null_logger(); - } -} - -void logger_impl::enable_console() { - if (console_sink_) - return; - - auto vsomeip_log_format = expressions::stream - << expressions::format_date_time( - "TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << " [" - << expressions::attr("Severity") << "] " - << expressions::smessage; - - boost::shared_ptr backend = boost::make_shared< - sinks::text_ostream_backend>(); - backend->add_stream(boost::shared_ptr(&std::clog, -#if BOOST_VERSION < 105500 - boost::log::empty_deleter() -#elif BOOST_VERSION < 105600 - boost::empty_deleter() -#else - boost::null_deleter() -#endif - )); - - console_sink_ = boost::make_shared(backend); - console_sink_->set_formatter(vsomeip_log_format); - logging::core::get()->add_sink(console_sink_); -} - -void logger_impl::disable_console() { - if (console_sink_) - logging::core::get()->remove_sink(console_sink_); -} - -void logger_impl::enable_file(const std::string &_path) { - if (file_sink_) - return; - - auto vsomeip_log_format = expressions::stream - << expressions::format_date_time( - "TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << " [" - << expressions::attr("Severity") << "] " - << expressions::smessage; - - boost::shared_ptr backend = boost::make_shared< - sinks::text_ostream_backend>(); - backend->add_stream( - boost::shared_ptr( - boost::make_shared(_path))); - - file_sink_ = boost::make_shared(backend); - file_sink_->set_formatter(vsomeip_log_format); - logging::core::get()->add_sink(file_sink_); -} - -void logger_impl::disable_file() { - if (file_sink_) - logging::core::get()->remove_sink(file_sink_); -} - - -void logger_impl::enable_dlt(const std::string &_app_id, - const std::string &_context_id) { -#ifdef USE_DLT - if (dlt_sink_) - return; - - boost::shared_ptr backend = boost::make_shared(_app_id, - _context_id); - dlt_sink_ = boost::make_shared(backend); - logging::core::get()->add_sink(dlt_sink_); -#else - (void)_app_id; - (void)_context_id; -#endif -} - -void logger_impl::disable_dlt() { - if (dlt_sink_) - logging::core::get()->remove_sink(dlt_sink_); -} - -void logger_impl::enable_android() { -#ifdef ANDROID - if (android_sink_) - return; - - boost::shared_ptr backend = boost::make_shared(); - android_sink_ = boost::make_shared(backend); - logging::core::get()->add_sink(android_sink_); -#endif -} - -void logger_impl::disable_android() { - if (android_sink_) - logging::core::get()->remove_sink(android_sink_); -} - -void logger_impl::use_null_logger() { - boost::shared_ptr backend = boost::make_shared< - sinks::text_ostream_backend>(); - backend->add_stream( - boost::shared_ptr(new std::ofstream("/dev/null") // TODO: how to call this on windows - )); - - file_sink_ = boost::make_shared(backend); - logging::core::get()->add_sink(file_sink_); -} - -} // namespace vsomeip_v3 - diff --git a/implementation/plugin/src/plugin_manager_impl.cpp b/implementation/plugin/src/plugin_manager_impl.cpp index 6da2d82..159eea9 100644 --- a/implementation/plugin/src/plugin_manager_impl.cpp +++ b/implementation/plugin/src/plugin_manager_impl.cpp @@ -200,6 +200,7 @@ void * plugin_manager_impl::load_symbol(void * _handle, } #else if (0 != _handle) { + dlerror(); // Clear previous error its_symbol = dlsym(_handle, _symbol.c_str()); const char *dlsym_error = dlerror(); if (dlsym_error) { diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp index 684a49b..b22b6ed 100644 --- a/implementation/routing/include/event.hpp +++ b/implementation/routing/include/event.hpp @@ -104,7 +104,7 @@ public: void remove_subscriber(eventgroup_t _eventgroup, client_t _client); bool has_subscriber(eventgroup_t _eventgroup, client_t _client); std::set get_subscribers(); - std::set get_subscribers(eventgroup_t _eventgroup); + VSOMEIP_EXPORT std::set get_subscribers(eventgroup_t _eventgroup); void clear_subscribers(); void add_ref(client_t _client, bool _is_provided); diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp index 65f7e89..32ce5f2 100644 --- a/implementation/routing/include/eventgroupinfo.hpp +++ b/implementation/routing/include/eventgroupinfo.hpp @@ -71,6 +71,8 @@ public: VSOMEIP_EXPORT void add_event(const std::shared_ptr& _event); VSOMEIP_EXPORT void remove_event(const std::shared_ptr& _event); VSOMEIP_EXPORT reliability_type_e get_reliability() const; + VSOMEIP_EXPORT void set_reliability(reliability_type_e _reliability); + VSOMEIP_EXPORT bool is_reliability_auto_mode() const; VSOMEIP_EXPORT std::set> get_remote_subscriptions() const; @@ -90,6 +92,8 @@ public: VSOMEIP_EXPORT void remove_remote_subscription( const remote_subscription_id_t _id); + void clear_remote_subscriptions(); + VSOMEIP_EXPORT std::set > get_unicast_targets() const; VSOMEIP_EXPORT std::set > @@ -129,6 +133,7 @@ private: remote_subscription_id_t id_; std::atomic reliability_; + std::atomic reliability_auto_mode_; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp index 00f2b57..685aad9 100644 --- a/implementation/routing/include/remote_subscription.hpp +++ b/implementation/routing/include/remote_subscription.hpp @@ -43,7 +43,7 @@ public: remote_subscription_id_t get_id() const; void set_id(const remote_subscription_id_t _id); - std::shared_ptr get_parent() const; + VSOMEIP_EXPORT std::shared_ptr get_parent() const; void set_parent(const std::shared_ptr &_parent); VSOMEIP_EXPORT std::shared_ptr get_eventgroupinfo() const; @@ -87,7 +87,7 @@ public: const bool _is_subscribe); VSOMEIP_EXPORT std::uint32_t get_answers() const; - void set_answers(const std::uint32_t _answers); + VSOMEIP_EXPORT void set_answers(const std::uint32_t _answers); private: std::atomic id_; diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index bead207..767d60e 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -153,8 +153,7 @@ public: } std::shared_ptr find_or_create_remote_client( - service_t _service, instance_t _instance, bool _reliable, - client_t _client); + service_t _service, instance_t _instance, bool _reliable); void remove_local(client_t _client, bool _remove_uid); void on_stop_offer_service(client_t _client, @@ -230,7 +229,16 @@ public: std::shared_ptr &_subscription); void expire_subscriptions(const boost::asio::ip::address &_address); + void expire_subscriptions(const boost::asio::ip::address &_address, + std::uint16_t _port, bool _reliable); + void expire_subscriptions(const boost::asio::ip::address &_address, + const configuration::port_range_t& _range, + bool _reliable); void expire_services(const boost::asio::ip::address &_address); + void expire_services(const boost::asio::ip::address &_address, + std::uint16_t _port , bool _reliable); + void expire_services(const boost::asio::ip::address &_address, + const configuration::port_range_t& _range , bool _reliable); std::chrono::steady_clock::time_point expire_subscriptions(bool _force); @@ -269,7 +277,9 @@ public: void register_reboot_notification_handler(const reboot_notification_handler_t& _handler) const; void register_routing_ready_handler(const routing_ready_handler_t& _handler); void register_routing_state_handler(const routing_state_handler_t& _handler); - void sd_acceptance_enabled(const boost::asio::ip::address& _address); + void sd_acceptance_enabled(const boost::asio::ip::address& _address, + const configuration::port_range_t& _range, + bool _reliable); void on_resend_provided_events_response(pending_remote_offer_id_t _id); bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr& _policy, diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp index d1a29df..346e733 100644 --- a/implementation/routing/include/routing_manager_proxy.hpp +++ b/implementation/routing/include/routing_manager_proxy.hpp @@ -25,8 +25,6 @@ class configuration; class event; class routing_manager_host; -class logger; - class routing_manager_proxy: public routing_manager_base { public: routing_manager_proxy(routing_manager_host *_host, bool _client_side_logging, @@ -252,8 +250,6 @@ private: boost::asio::steady_timer register_application_timer_; - std::shared_ptr logger_; - std::mutex request_timer_mutex_; boost::asio::steady_timer request_debounce_timer_; bool request_debounce_timer_running_; diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp index 7575733..bc0ba3e 100644 --- a/implementation/routing/src/event.cpp +++ b/implementation/routing/src/event.cpp @@ -67,7 +67,7 @@ event_t event::get_event() const { } void event::set_event(event_t _event) { - message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit + message_->set_method(_event); } event_type_e event::get_type() const { diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp index 52c6c1e..3b3a808 100644 --- a/implementation/routing/src/eventgroupinfo.cpp +++ b/implementation/routing/src/eventgroupinfo.cpp @@ -25,7 +25,8 @@ eventgroupinfo::eventgroupinfo() port_(ILLEGAL_PORT), threshold_(0), id_(PENDING_SUBSCRIPTION_ID), - reliability_(reliability_type_e::RT_UNKNOWN) { + reliability_(reliability_type_e::RT_UNKNOWN), + reliability_auto_mode_(false) { } eventgroupinfo::eventgroupinfo( @@ -40,7 +41,8 @@ eventgroupinfo::eventgroupinfo( port_(ILLEGAL_PORT), threshold_(0), id_(PENDING_SUBSCRIPTION_ID), - reliability_(reliability_type_e::RT_UNKNOWN) { + reliability_(reliability_type_e::RT_UNKNOWN), + reliability_auto_mode_(false) { } eventgroupinfo::~eventgroupinfo() { @@ -124,6 +126,12 @@ void eventgroupinfo::add_event(const std::shared_ptr& _event) { std::lock_guard its_lock(events_mutex_); events_.insert(_event); + if (!reliability_auto_mode_ && + _event->get_reliability() == reliability_type_e::RT_UNKNOWN) { + reliability_auto_mode_ = true; + return; + } + switch (_event->get_reliability()) { case reliability_type_e::RT_RELIABLE: if (reliability_ == reliability_type_e::RT_UNRELIABLE) { @@ -156,6 +164,14 @@ reliability_type_e eventgroupinfo::get_reliability() const { return reliability_; } +void eventgroupinfo::set_reliability(reliability_type_e _reliability) { + reliability_ = _reliability; +} + +bool eventgroupinfo::is_reliability_auto_mode() const { + return reliability_auto_mode_; +} + uint32_t eventgroupinfo::get_unreliable_target_count() const { uint32_t its_count(0); @@ -228,6 +244,8 @@ eventgroupinfo::update_remote_subscription( } else { its_item.second->set_answers( its_item.second->get_answers() + 1); + _subscription->set_parent(its_item.second); + _subscription->set_answers(0); } } } else { @@ -276,6 +294,12 @@ eventgroupinfo::remove_remote_subscription( subscriptions_.erase(_id); } +void +eventgroupinfo::clear_remote_subscriptions() { + std::lock_guard its_lock(subscriptions_mutex_); + subscriptions_.clear(); +} + std::set > eventgroupinfo::get_unicast_targets() const { std::set> its_targets; @@ -300,7 +324,7 @@ eventgroupinfo::get_multicast_targets() const { } bool eventgroupinfo::is_selective() const { - /* Selective eventgroups always contain a single event */ + // Selective eventgroups always contain a single event std::lock_guard its_lock(events_mutex_); if (events_.size() != 1) return false; @@ -320,39 +344,57 @@ void eventgroupinfo::send_initial_events( const std::shared_ptr &_reliable, const std::shared_ptr &_unreliable) const { - std::lock_guard its_lock(events_mutex_); - for (const auto &its_event : events_) { - if (its_event && its_event->get_type() == event_type_e::ET_FIELD) { -#ifndef VSOMEIP_ENABLE_COMPAT - const auto its_reliability = its_event->get_reliability(); - switch (its_reliability) { - case reliability_type_e::RT_RELIABLE: - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); - break; - case reliability_type_e::RT_UNRELIABLE: - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); - break; - case reliability_type_e::RT_BOTH: - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); - break; - default: - VSOMEIP_WARNING << __func__ << "Event reliability unknown: [" - << std::hex << std::setw(4) << std::setfill('0') << service_ << "." - << std::hex << std::setw(4) << std::setfill('0') << instance_ << "." - << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]"; - } -#else - if (_reliable) { - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); - } - if (_unreliable) { - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); - } + + std::set > its_reliable_events, its_unreliable_events; + + // Build sets of reliable/unreliable events first to avoid having to + // hold the "events_mutex_" in parallel to the internal event mutexes. + { + std::lock_guard its_lock(events_mutex_); + for (const auto &its_event : events_) { + if (its_event && its_event->get_type() == event_type_e::ET_FIELD) { + auto its_reliability = its_event->get_reliability(); +#ifdef VSOMEIP_ENABLE_COMPAT + if (its_reliability == reliability_type_e::RT_UNKNOWN) { + if (_reliable) { + if (_unreliable) { + its_reliability = reliability_type_e::RT_BOTH; + } else { + its_reliability = reliability_type_e::RT_RELIABLE; + } + } else if (_unreliable) { + its_reliability = reliability_type_e::RT_UNRELIABLE; + } + } #endif + switch (its_reliability) { + case reliability_type_e::RT_RELIABLE: + its_reliable_events.insert(its_event); + break; + case reliability_type_e::RT_UNRELIABLE: + its_unreliable_events.insert(its_event); + break; + case reliability_type_e::RT_BOTH: + its_reliable_events.insert(its_event); + its_unreliable_events.insert(its_event); + break; + default: + VSOMEIP_WARNING << __func__ << "Event reliability unknown: [" + << std::hex << std::setw(4) << std::setfill('0') << service_ << "." + << std::hex << std::setw(4) << std::setfill('0') << instance_ << "." + << std::hex << std::setw(4) << std::setfill('0') << eventgroup_ << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event->get_event() << "]"; + } + } } } + + // Send events + for (const auto its_event : its_reliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); + + for (const auto its_event : its_unreliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); } } // namespace vsomeip_v3 diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp index a896b36..939e0d1 100644 --- a/implementation/routing/src/remote_subscription.cpp +++ b/implementation/routing/src/remote_subscription.cpp @@ -178,7 +178,8 @@ remote_subscription::set_client_state(const client_t _client, if (found_item->second.second == std::chrono::steady_clock::time_point() && (_state == remote_subscription_state_e::SUBSCRIPTION_ACKED || _state == remote_subscription_state_e::SUBSCRIPTION_NACKED)) { - found_item->second.second = std::chrono::steady_clock::now(); + found_item->second.second = std::chrono::steady_clock::now() + + std::chrono::seconds(ttl_); } } } diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp index 77e5b83..5b1149e 100644 --- a/implementation/routing/src/routing_manager_base.cpp +++ b/implementation/routing/src/routing_manager_base.cpp @@ -1265,11 +1265,15 @@ std::shared_ptr routing_manager_base::get_serializer() { std::unique_lock its_lock(serializer_mutex_); while (serializers_.empty()) { - VSOMEIP_INFO << std::hex << "client " << get_client() << - "routing_manager_base::get_serializer ~> all in use!"; + VSOMEIP_INFO << __func__ << ": Client " + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << " has no available serializer. Waiting..."; serializer_condition_.wait(its_lock); - VSOMEIP_INFO << std::hex << "client " << get_client() << - "routing_manager_base::get_serializer ~> wait finished!"; + VSOMEIP_INFO << __func__ << ": Client " + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << " now checking for available serializer."; } auto its_serializer = serializers_.front(); diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 48e2cb5..c132569 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -162,9 +162,17 @@ void routing_manager_impl::init() { void routing_manager_impl::start() { #ifndef _WIN32 - netlink_connector_ = std::make_shared(host_->get_io(), - configuration_->get_unicast_address(), - boost::asio::ip::address::from_string(configuration_->get_sd_multicast())); + boost::asio::ip::address its_multicast; + try { + its_multicast = boost::asio::ip::address::from_string(configuration_->get_sd_multicast()); + } catch (...) { + VSOMEIP_ERROR << "Illegal multicast address \"" + << configuration_->get_sd_multicast() + << "\". Please check your configuration."; + } + + netlink_connector_ = std::make_shared( + host_->get_io(), configuration_->get_unicast_address(), its_multicast); netlink_connector_->register_net_if_changes_handler( std::bind(&routing_manager_impl::on_net_interface_or_route_state_changed, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); @@ -326,7 +334,7 @@ bool routing_manager_impl::offer_service(client_t _client, << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << ":" << std::dec << int(_major) << "." << std::dec << _minor << "]" - << " (" << _must_queue << ")"; + << " (" << std::boolalpha << _must_queue << ")"; // only queue commands if method was NOT called via erase_offer_command() if (_must_queue) { @@ -420,7 +428,7 @@ void routing_manager_impl::stop_offer_service(client_t _client, << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << ":" << std::dec << int(_major) << "." << _minor << "]" - << " (" << _must_queue << ")"; + << " (" << std::boolalpha << _must_queue << ")"; if (_must_queue) { if (!insert_offer_command(_service, _instance, VSOMEIP_STOP_OFFER_SERVICE, @@ -505,7 +513,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, } its_info->add_client(_client); ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true, VSOMEIP_ROUTING_CLIENT); + _service, _instance, true); } } } @@ -617,7 +625,8 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, if (its_info) { discovery_->subscribe(_service, _instance, _eventgroup, _major, configured_ttl, - its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT); + its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT, + its_info); } } else { its_critical.unlock(); @@ -653,7 +662,6 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, bool last_subscriber_removed(true); - auto its_event = find_event(_service, _instance, _event); std::shared_ptr its_info = find_eventgroup(_service, _instance, _eventgroup); if (its_info) { @@ -682,12 +690,11 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } } - if (last_subscriber_removed - || (its_event && its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT)) { - if (its_info) { - discovery_->unsubscribe(_service, _instance, _eventgroup, - its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT); - } + if (its_info && + (last_subscriber_removed || its_info->is_selective())) { + + discovery_->unsubscribe(_service, _instance, _eventgroup, + its_info->is_selective() ? _client : VSOMEIP_ROUTING_CLIENT); } } else { if (get_client() == _client) { @@ -797,9 +804,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } } if (is_request) { - client_t client = VSOMEIP_ROUTING_CLIENT; its_target = ep_mgr_impl_->find_or_create_remote_client( - its_service, _instance, _reliable, client); + its_service, _instance, _reliable); if (its_target) { #ifdef USE_DLT const uint16_t its_data_size @@ -1089,7 +1095,7 @@ void routing_manager_impl::register_event(client_t _client, << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << _notifier - << ":is_provider=" << _is_provided << "]"; + << ":is_provider=" << std::boolalpha << _is_provided << "]"; } void routing_manager_impl::register_shadow_event(client_t _client, @@ -1681,6 +1687,17 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se } erase_offer_command(_service, _instance); } + + std::lock_guard its_eventgroups_lock(eventgroups_mutex_); + auto find_service = eventgroups_.find(_service); + if (find_service != eventgroups_.end()) { + auto find_instance = find_service->second.find(_instance); + if (find_instance != find_service->second.end()) { + for (auto e : find_instance->second) { + e.second->clear_remote_subscriptions(); + } + } + } } else { erase_offer_command(_service, _instance); } @@ -2186,10 +2203,10 @@ void routing_manager_impl::add_routing_info( if (udp_inserted) { // atomically create reliable and unreliable endpoint ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, VSOMEIP_ROUTING_CLIENT); + _service, _instance); } else { ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true, VSOMEIP_ROUTING_CLIENT); + _service, _instance, true); } connected = true; } @@ -2265,7 +2282,7 @@ void routing_manager_impl::add_routing_info( == ANY_MINOR)) { if(!connected) { ep_mgr_impl_->find_or_create_remote_client(_service, _instance, - false, VSOMEIP_ROUTING_CLIENT); + false); connected = true; } its_info->add_client(client_id.first); @@ -2463,45 +2480,59 @@ void routing_manager_impl::update_routing_info(std::chrono::milliseconds _elapse } } -void routing_manager_impl::expire_services(const boost::asio::ip::address &_address) { +void routing_manager_impl::expire_services( + const boost::asio::ip::address &_address) { + expire_services(_address, configuration::port_range_t(ANY_PORT, ANY_PORT), + false); +} + +void routing_manager_impl::expire_services( + const boost::asio::ip::address &_address, std::uint16_t _port, + bool _reliable) { + expire_services(_address, configuration::port_range_t(_port, _port), + _reliable); +} + +void routing_manager_impl::expire_services( + const boost::asio::ip::address &_address, + const configuration::port_range_t& _range, bool _reliable) { std::map > its_expired_offers; + const bool expire_all = (_range.first == ANY_PORT + && _range.second == ANY_PORT); + for (auto &s : get_services_remote()) { for (auto &i : s.second) { - bool is_gone(false); boost::asio::ip::address its_address; std::shared_ptr its_client_endpoint = std::dynamic_pointer_cast( - i.second->get_endpoint(true)); + i.second->get_endpoint(_reliable)); + if (!its_client_endpoint && expire_all) { + its_client_endpoint = std::dynamic_pointer_cast( + i.second->get_endpoint(!_reliable)); + } if (its_client_endpoint) { - if (its_client_endpoint->get_remote_address(its_address)) { - is_gone = (its_address == _address); - } - } else { - its_client_endpoint = - std::dynamic_pointer_cast( - i.second->get_endpoint(false)); - if (its_client_endpoint) { - if (its_client_endpoint->get_remote_address(its_address)) { - is_gone = (its_address == _address); + if ((expire_all || (its_client_endpoint->get_remote_port() >= _range.first + && its_client_endpoint->get_remote_port() <= _range.second)) + && its_client_endpoint->get_remote_address(its_address) + && its_address == _address) { + if (discovery_) { + discovery_->unsubscribe_all(s.first, i.first); } + its_expired_offers[s.first].push_back(i.first); } } - - if (is_gone) { - if (discovery_) - discovery_->unsubscribe_all(s.first, i.first); - its_expired_offers[s.first].push_back(i.first); - } } } for (auto &s : its_expired_offers) { for (auto &i : s.second) { - VSOMEIP_INFO << "expire_services for address: " << _address.to_string() + VSOMEIP_INFO << "expire_services for address: " << _address << " : delete service/instance " << std::hex << std::setw(4) << std::setfill('0') << s.first - << "." << std::hex << std::setw(4) << std::setfill('0') << i; + << "." << std::hex << std::setw(4) << std::setfill('0') << i + << " port [" << std::dec << _range.first << "," << _range.second + << "] reliability=" << std::boolalpha << _reliable; del_routing_info(s.first, i, true, true); } } @@ -2510,49 +2541,74 @@ void routing_manager_impl::expire_services(const boost::asio::ip::address &_addr void routing_manager_impl::expire_subscriptions( const boost::asio::ip::address &_address) { - { - std::lock_guard its_lock(eventgroups_mutex_); - for (const auto &its_service : eventgroups_) { - for (const auto &its_instance : its_service.second) { - for (const auto &its_eventgroup : its_instance.second) { - const auto its_info = its_eventgroup.second; - for (auto its_subscription - : its_info->get_remote_subscriptions()) { - // Note: get_remote_subscription delivers a copied - // set of subscriptions. Thus, its is possible to - // to remove them within the loop. - const auto its_reliable = its_subscription->get_reliable(); - const auto its_unreliable = its_subscription->get_unreliable(); - if ((its_reliable && its_reliable->get_address() == _address) - || (its_unreliable && its_unreliable->get_address() == _address)) { - - // TODO: Check whether subscriptions to different hosts are valid. - // IF yes, we probably need to simply reset the corresponding - // endpoint instead of removing the subscription... - - if (its_reliable) { - VSOMEIP_ERROR << __func__ - << ": removing subscription to " - << std::hex << its_info->get_service() << "." - << std::hex << its_info->get_instance() << "." - << std::hex << its_info->get_eventgroup() - << " from target " - << its_reliable->get_address().to_string() << ":" - << std::dec << its_reliable->get_port(); - } - if (its_unreliable) { + expire_subscriptions(_address, + configuration::port_range_t(ANY_PORT, ANY_PORT), false); +} + +void +routing_manager_impl::expire_subscriptions( + const boost::asio::ip::address &_address, std::uint16_t _port, + bool _reliable) { + expire_subscriptions(_address, configuration::port_range_t(_port, _port), + _reliable); +} + +void +routing_manager_impl::expire_subscriptions( + const boost::asio::ip::address &_address, + const configuration::port_range_t& _range, bool _reliable) { + const bool expire_all = (_range.first == ANY_PORT + && _range.second == ANY_PORT); + + std::lock_guard its_lock(eventgroups_mutex_); + for (const auto &its_service : eventgroups_) { + for (const auto &its_instance : its_service.second) { + for (const auto &its_eventgroup : its_instance.second) { + const auto its_info = its_eventgroup.second; + for (auto its_subscription + : its_info->get_remote_subscriptions()) { + // Note: get_remote_subscription delivers a copied + // set of subscriptions. Thus, its is possible to + // to remove them within the loop. + const auto its_ep_definition = + (_reliable) ? its_subscription->get_reliable() : + its_subscription->get_unreliable(); + + if (its_ep_definition + && its_ep_definition->get_address() == _address + && (expire_all || + (its_ep_definition->get_remote_port() >= _range.first + && its_ep_definition->get_remote_port() <= _range.second))) { + + // TODO: Check whether subscriptions to different hosts are valid. + // IF yes, we probably need to simply reset the corresponding + // endpoint instead of removing the subscription... + VSOMEIP_ERROR << __func__ + << ": removing subscription to " + << std::hex << its_info->get_service() << "." + << std::hex << its_info->get_instance() << "." + << std::hex << its_info->get_eventgroup() + << " from target " + << its_ep_definition->get_address() << ":" + << std::dec << its_ep_definition->get_port() + << " reliable=" << _reliable; + if (expire_all) { + const auto its_ep_definition2 = + (!_reliable) ? its_subscription->get_reliable() : + its_subscription->get_unreliable(); + if (its_ep_definition2) { VSOMEIP_ERROR << __func__ << ": removing subscription to " << std::hex << its_info->get_service() << "." << std::hex << its_info->get_instance() << "." << std::hex << its_info->get_eventgroup() << " from target " - << its_unreliable->get_address().to_string() << ":" - << std::dec << its_unreliable->get_port(); + << its_ep_definition2->get_address() << ":" + << std::dec << its_ep_definition2->get_port() + << " reliable=" << !_reliable; } - - on_remote_unsubscribe(its_subscription); } + on_remote_unsubscribe(its_subscription); } } } @@ -2570,22 +2626,34 @@ void routing_manager_impl::init_routing_info() { = configuration_->get_reliable_port(i.first, i.second); uint16_t its_unreliable_port = configuration_->get_unreliable_port(i.first, i.second); + major_version_t its_major + = configuration_->get_major_version(i.first, i.second); + minor_version_t its_minor + = configuration_->get_minor_version(i.first, i.second); + ttl_t its_ttl + = configuration_->get_ttl(i.first, i.second); if (its_reliable_port != ILLEGAL_PORT || its_unreliable_port != ILLEGAL_PORT) { + VSOMEIP_INFO << "Adding static remote service [" + << std::hex << std::setw(4) << std::setfill('0') + << i.first << "." << i.second + << std::dec << ":" << +its_major << "." << its_minor + << "]"; + add_routing_info(i.first, i.second, - DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL, + its_major, its_minor, its_ttl, its_address, its_reliable_port, its_address, its_unreliable_port); if(its_reliable_port != ILLEGAL_PORT) { ep_mgr_impl_->find_or_create_remote_client( - i.first, i.second, true, VSOMEIP_ROUTING_CLIENT); + i.first, i.second, true); } if(its_unreliable_port != ILLEGAL_PORT) { ep_mgr_impl_->find_or_create_remote_client( - i.first, i.second, false, VSOMEIP_ROUTING_CLIENT); + i.first, i.second, false); } } } @@ -2660,6 +2728,7 @@ void routing_manager_impl::on_remote_subscribe( if (its_reliable && its_unreliable) its_warning << "]"; VSOMEIP_WARNING << its_warning.str(); + _callback(_subscription); } } else { // new subscription auto its_id @@ -2810,10 +2879,9 @@ void routing_manager_impl::on_subscribe_ack(client_t _client, } std::shared_ptr routing_manager_impl::find_or_create_remote_client( - service_t _service, instance_t _instance, bool _reliable, - client_t _client) { + service_t _service, instance_t _instance, bool _reliable) { return ep_mgr_impl_->find_or_create_remote_client(_service, - _instance, _reliable, _client); + _instance, _reliable); } void routing_manager_impl::on_subscribe_nack(client_t _client, @@ -3082,7 +3150,7 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const #ifndef VSOMEIP_VERSION #define VSOMEIP_VERSION "unknown version" #endif - static int counter(0); + static int its_counter(0); static uint32_t its_interval = configuration_->get_log_version_interval(); bool is_diag_mode(false); @@ -3104,11 +3172,11 @@ void routing_manager_impl::log_version_timer_cbk(boost::system::error_code const << ((is_diag_mode == true) ? "diagnosis)" : "default)") << its_last_resume.str(); - counter++; - if (counter == 6) { + its_counter++; + if (its_counter == 6) { ep_mgr_->log_client_states(); ep_mgr_impl_->log_client_states(); - counter = 0; + its_counter = 0; } { @@ -3852,12 +3920,10 @@ void routing_manager_impl::register_routing_state_handler( } void routing_manager_impl::sd_acceptance_enabled( - const boost::asio::ip::address& _address) { - boost::system::error_code ec; - VSOMEIP_INFO << "ipsec-plugin-mgu: expire subscriptions and services: " - << _address.to_string(ec); - expire_subscriptions(_address); - expire_services(_address); + const boost::asio::ip::address& _address, + const configuration::port_range_t& _range, bool _reliable) { + expire_subscriptions(_address, _range, _reliable); + expire_services(_address, _range, _reliable); } void routing_manager_impl::memory_log_timer_cbk( diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index 8135c3f..3b95a2d 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -45,7 +45,6 @@ routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host, sender_(nullptr), receiver_(nullptr), register_application_timer_(io_), - logger_(logger::get()), request_debounce_timer_ (io_), request_debounce_timer_running_(false), client_side_logging_(_client_side_logging), @@ -342,9 +341,35 @@ void routing_manager_proxy::register_event(client_t _client, std::lock_guard its_lock(state_mutex_); is_first = pending_event_registrations_.find(registration) == pending_event_registrations_.end(); +#ifndef VSOMEIP_ENABLE_COMPAT if (is_first) { pending_event_registrations_.insert(registration); } +#else + bool insert = true; + if (is_first) { + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end();) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided + && iter->type_ == event_type_e::ET_EVENT + && _type == event_type_e::ET_SELECTIVE_EVENT) { + iter = pending_event_registrations_.erase(iter); + iter = pending_event_registrations_.insert(registration).first; + is_first = true; + insert = false; + break; + } else { + iter++; + } + } + if (insert) { + pending_event_registrations_.insert(registration); + } + } +#endif } if (is_first || _is_provided) { routing_manager_base::register_event(_client, @@ -399,17 +424,19 @@ void routing_manager_proxy::unregister_event(client_t _client, } } } - auto it = pending_event_registrations_.begin(); - while (it != pending_event_registrations_.end()) { - if (it->service_ == _service - && it->instance_ == _instance - && it->notifier_ == _notifier) { + + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end(); ) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided) { + pending_event_registrations_.erase(iter); break; + } else { + iter++; } - it++; } - if (it != pending_event_registrations_.end()) - pending_event_registrations_.erase(it); } } @@ -455,7 +482,7 @@ void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid, std::lock_guard its_lock(state_mutex_); if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) { - send_subscribe(_client, _service, _instance, _eventgroup, _major, _event ); + send_subscribe(client_, _service, _instance, _eventgroup, _major, _event ); } subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid}; pending_subscriptions_.insert(subscription); @@ -1548,20 +1575,23 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data, return; } #endif - - // inform host about its own registration state changes - host_->on_state(static_cast(inner_state_type_e::ST_REGISTERED)); - { std::lock_guard its_lock(state_mutex_); - boost::system::error_code ec; - register_application_timer_.cancel(ec); - send_registered_ack(); - send_pending_commands(); - state_ = inner_state_type_e::ST_REGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); + if (state_ == inner_state_type_e::ST_REGISTERING) { + boost::system::error_code ec; + register_application_timer_.cancel(ec); + send_registered_ack(); + send_pending_commands(); + state_ = inner_state_type_e::ST_REGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } } + + // inform host about its own registration state changes + if (state_ == inner_state_type_e::ST_REGISTERED) + host_->on_state(static_cast(inner_state_type_e::ST_REGISTERED)); + } } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) { { @@ -2278,25 +2308,23 @@ routing_manager_proxy::assign_client_timeout_cbk( void routing_manager_proxy::register_application_timeout_cbk( boost::system::error_code const &_error) { - if (!_error) { - bool register_again(false); - { - std::lock_guard its_lock(state_mutex_); - if (state_ != inner_state_type_e::ST_REGISTERED) { - state_ = inner_state_type_e::ST_DEREGISTERED; - register_again = true; - } - } - if (register_again) { - std::lock_guard its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " register timeout! Trying again..."; - if (sender_) { - sender_->restart(); - } + bool register_again(false); + { + std::lock_guard its_lock(state_mutex_); + if (!_error && state_ != inner_state_type_e::ST_REGISTERED) { + state_ = inner_state_type_e::ST_DEREGISTERED; + register_again = true; } } + if (register_again) { + std::lock_guard its_lock(sender_mutex_); + VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() + << " register timeout! Trying again..."; + + if (sender_) + sender_->restart(); + } } void routing_manager_proxy::send_registered_ack() { diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 65945f7..d7a1dd2 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -784,8 +784,8 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, void routing_manager_stub::on_register_application(client_t _client) { auto endpoint = host_->find_local(_client); if (endpoint) { - VSOMEIP_ERROR << "Registering application: " << std::hex << _client - << " failed. It is already registered!"; + VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client + << ". Last registration might have been taken too long."; } else { (void)host_->find_or_create_local(_client); std::lock_guard its_lock(routing_info_mutex_); diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index b439501..f60c390 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -33,7 +33,6 @@ namespace vsomeip_v3 { class runtime; class configuration; -class logger; class routing_manager; class routing_manager_stub; @@ -175,6 +174,7 @@ public: const std::string& _path, bool _enable); VSOMEIP_EXPORT void set_sd_acceptance_required( const sd_acceptance_map_type_t& _remotes, bool _enable); + VSOMEIP_EXPORT sd_acceptance_map_type_t get_sd_acceptance_required(); VSOMEIP_EXPORT void register_sd_acceptance_handler(sd_acceptance_handler_t _handler); @@ -389,9 +389,6 @@ private: std::size_t max_dispatchers_; std::size_t max_dispatch_time_; - // Workaround for destruction problem - std::shared_ptr logger_; - std::condition_variable stop_cv_; std::mutex start_stop_mutex_; bool stopped_; diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index 0018340..44b14fd 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -9,7 +9,6 @@ #include #include -#include #ifndef _WIN32 #include @@ -63,7 +62,6 @@ application_impl::application_impl(const std::string &_name) is_dispatching_(false), max_dispatchers_(VSOMEIP_MAX_DISPATCHERS), max_dispatch_time_(VSOMEIP_MAX_DISPATCH_TIME), - logger_(logger::get()), stopped_(false), block_stopping_(false), is_routing_manager_host_(false), @@ -420,10 +418,6 @@ void application_impl::start() { #endif try { io_.run(); -#if !defined(_WIN32) && !defined(ANDROID) - } catch (const boost::log::v2_mt_posix::system_error &e) { - std::cerr << "catched boost::log system_error in I/O thread" << std::endl; -#endif } catch (const std::exception &e) { VSOMEIP_ERROR << "application_impl::start() " "catched exception: " << e.what(); @@ -469,10 +463,6 @@ void application_impl::start() { stop_thread_.join(); } -#if !defined(_WIN32) && !defined(ANDROID) - } catch (const boost::log::v2_mt_posix::system_error &e) { - std::cerr << "catched boost::log system_error in I/O thread" << std::endl; -#endif } catch (const std::exception &e) { VSOMEIP_ERROR << "application_impl::start() catched exception: " << e.what(); } @@ -502,14 +492,10 @@ void application_impl::start() { } void application_impl::stop() { -#if !defined(_WIN32) && !defined(ANDROID) - try { - VSOMEIP_INFO << "Stopping vsomeip application \"" << name_ << "\" (" + + VSOMEIP_INFO << "Stopping vsomeip application \"" << name_ << "\" (" << std::hex << std::setw(4) << std::setfill('0') << client_ << ")."; - } catch (const boost::log::v2_mt_posix::system_error &e) { - std::cerr << "catched boost::log system_error application_impl::stop" << std::endl; - } -#endif + bool block = true; { std::lock_guard its_lock_start_stop(start_stop_mutex_); @@ -1954,11 +1940,6 @@ void application_impl::shutdown() { running_dispatchers_.clear(); elapsed_dispatchers_.clear(); dispatchers_.clear(); -#if !defined(_WIN32) && !defined(ANDROID) - } catch (const boost::log::v2_mt_posix::system_error &e) { - std::cerr << "application_impl::" << __func__ << ": stopping dispatchers, " - << "catched boost::log system_error" << std::endl; -#endif } catch (const std::exception &e) { VSOMEIP_ERROR << "application_impl::" << __func__ << ": stopping dispatchers, " << " catched exception: " << e.what(); @@ -1967,11 +1948,6 @@ void application_impl::shutdown() { try { if (routing_) routing_->stop(); -#if !defined(_WIN32) && !defined(ANDROID) - } catch (const boost::log::v2_mt_posix::system_error &e) { - std::cerr << "application_impl::" << __func__ << ": stopping routing, " - << "catched boost::log system_error" << std::endl; -#endif } catch (const std::exception &e) { VSOMEIP_ERROR << "application_impl::" << __func__ << ": stopping routing, " << " catched exception: " << e.what(); @@ -1980,11 +1956,6 @@ void application_impl::shutdown() { try { work_.reset(); io_.stop(); -#if !defined(_WIN32) && !defined(ANDROID) - } catch (const boost::log::v2_mt_posix::system_error &e) { - std::cerr << "application_impl::" << __func__ << ": stopping io, " - << "catched boost::log system_error" << std::endl; -#endif } catch (const std::exception &e) { VSOMEIP_ERROR << "application_impl::" << __func__ << ": stopping io, " << " catched exception: " << e.what(); @@ -1998,11 +1969,6 @@ void application_impl::shutdown() { } } io_threads_.clear(); -#if !defined(_WIN32) && !defined(ANDROID) - } catch (const boost::log::v2_mt_posix::system_error &e) { - std::cerr << "application_impl::" << __func__ << ": joining threads, " - << "catched boost::log system_error" << std::endl; -#endif } catch (const std::exception &e) { VSOMEIP_ERROR << "application_impl::" << __func__ << ": joining threads, " << " catched exception: " << e.what(); @@ -2390,46 +2356,136 @@ void application_impl::register_reboot_notification_handler( } void application_impl::set_sd_acceptance_required( - const remote_info_t& _remote, const std::string& _path, bool _enable) { - if (is_routing()) { - const boost::asio::ip::address its_address = _remote.ip_.is_v4_ ? - static_cast(boost::asio::ip::address_v4(_remote.ip_.address_.v4_)) : - static_cast(boost::asio::ip::address_v6(_remote.ip_.address_.v6_)); - configuration_->set_sd_acceptance_required(its_address, _remote.port_, _path, _enable); - if (_enable && routing_) { - const auto rm_impl = std::dynamic_pointer_cast(routing_); - rm_impl->sd_acceptance_enabled(its_address); - } + const remote_info_t &_remote, const std::string &_path, bool _enable) { + + if (!is_routing()) { + return; + } + + const boost::asio::ip::address its_address(_remote.ip_.is_v4_ ? + static_cast(boost::asio::ip::address_v4( + _remote.ip_.address_.v4_)) : + static_cast(boost::asio::ip::address_v6( + _remote.ip_.address_.v6_))); + + if (_remote.first_ == std::numeric_limits::max() + && _remote.last_ == 0) { + // special case to (de)activate rules per IP + configuration_->set_sd_acceptance_rules_active(its_address, _enable); + return; + } + + configuration::port_range_t its_range { _remote.first_, _remote.last_ }; + configuration_->set_sd_acceptance_rule(its_address, + its_range, port_type_e::PT_UNKNOWN, + _path, _remote.is_reliable_, _enable, true); + + if (_enable && routing_) { + const auto rm_impl = std::dynamic_pointer_cast(routing_); + rm_impl->sd_acceptance_enabled(its_address, its_range, + _remote.is_reliable_); } } -void application_impl::set_sd_acceptance_required(const sd_acceptance_map_type_t& _remotes, - bool _enable) { - (void) _remotes; - (void) _enable; +void application_impl::set_sd_acceptance_required( + const sd_acceptance_map_type_t& _remotes, bool _enable) { + + (void)_remotes; + (void)_enable; + +#if 0 + if (!is_routing()) { + return; + } + + configuration::sd_acceptance_rules_t its_rules; + for (const auto& remote_info : _remotes) { + const boost::asio::ip::address its_address(remote_info.first.ip_.is_v4_ ? + static_cast(boost::asio::ip::address_v4( + remote_info.first.ip_.address_.v4_)) : + static_cast(boost::asio::ip::address_v6( + remote_info.first.ip_.address_.v6_))); + const boost::icl::interval::interval_type its_interval = + remote_info.first.is_range_ ? + boost::icl::interval::closed( + remote_info.first.first_, + ((remote_info.first.last_ == ANY_PORT) ? + std::numeric_limits::max() : + remote_info.first.last_)) : + boost::icl::interval::closed( + remote_info.first.first_, remote_info.first.first_); + + const bool its_reliability = remote_info.first.is_reliable_; + + const auto found_address = its_rules.find(its_address); + if (found_address != its_rules.end()) { + const auto found_reliability = found_address->second.second.find( + its_reliability); + if (found_reliability != found_address->second.second.end()) { + found_reliability->second.insert(its_interval); + } else { + found_address->second.second.emplace(std::make_pair( + its_reliability, + boost::icl::interval_set(its_interval))); + } + } else { + its_rules.insert(std::make_pair(its_address, + std::make_pair(remote_info.second, + std::map>( + {{ its_reliability, + boost::icl::interval_set( + its_interval) } })))); + } + } + + configuration_->set_sd_acceptance_rules(its_rules, _enable); +#endif } application::sd_acceptance_map_type_t application_impl::get_sd_acceptance_required() { + sd_acceptance_map_type_t its_ret; + if (is_routing()) { - for (const auto& e : configuration_->get_sd_acceptance_required()) { + for (const auto& e : configuration_->get_sd_acceptance_rules()) { remote_info_t its_remote_info; - its_remote_info.ip_.is_v4_ = e.first.first.is_v4(); - if (e.first.first.is_v4()) { - its_remote_info.ip_.address_.v4_ = e.first.first.to_v4().to_bytes(); - its_remote_info.ip_.is_v4_ = true; + its_remote_info.ip_.is_v4_ = e.first.is_v4(); + if (its_remote_info.ip_.is_v4_) { + its_remote_info.ip_.address_.v4_ = e.first.to_v4().to_bytes(); } else { - its_remote_info.ip_.address_.v6_ = e.first.first.to_v6().to_bytes(); - its_remote_info.ip_.is_v4_ = false; + its_remote_info.ip_.address_.v6_ = e.first.to_v6().to_bytes(); + } + for (const auto& reliability : e.second.second) { + its_remote_info.is_reliable_ = reliability.first; + for (const auto& port_range : reliability.second.first) { + if (port_range.lower() == port_range.upper()) { + its_remote_info.first_ = port_range.lower(); + its_remote_info.last_ = port_range.lower(); + its_remote_info.is_range_ = false; + } else { + its_remote_info.first_ = port_range.lower(); + its_remote_info.last_ = port_range.upper(); + its_remote_info.is_range_ = true; + } + its_ret[its_remote_info] = e.second.first; + } + for (const auto& port_range : reliability.second.second) { + if (port_range.lower() == port_range.upper()) { + its_remote_info.first_ = port_range.lower(); + its_remote_info.last_ = port_range.lower(); + its_remote_info.is_range_ = false; + } else { + its_remote_info.first_ = port_range.lower(); + its_remote_info.last_ = port_range.upper(); + its_remote_info.is_range_ = true; + } + its_ret[its_remote_info] = e.second.first; + } } - its_remote_info.port_ = e.first.second; - its_remote_info.first_ = ANY_PORT; - its_remote_info.last_ = ANY_PORT; - its_remote_info.is_range_ = false; - its_ret[its_remote_info] = e.second; } } + return its_ret; } diff --git a/implementation/security/include/policy.hpp b/implementation/security/include/policy.hpp index 018fbd5..f8727f8 100644 --- a/implementation/security/include/policy.hpp +++ b/implementation/security/include/policy.hpp @@ -6,9 +6,11 @@ #ifndef VSOMEIP_V3_POLICY_HPP_ #define VSOMEIP_V3_POLICY_HPP_ -#include -#include #include +#include +#include +#include +#include #include #include @@ -25,9 +27,11 @@ struct policy { ids_t ids_; bool allow_who_; - std::set> services_; - std::set> offers_; + std::map services_; + std::map offers_; bool allow_what_; + + std::mutex mutex_; }; } // namespace vsomeip_v3 diff --git a/implementation/security/src/security_impl.cpp b/implementation/security/src/security_impl.cpp index a60a6f8..ef1404d 100644 --- a/implementation/security/src/security_impl.cpp +++ b/implementation/security/src/security_impl.cpp @@ -81,6 +81,7 @@ security_impl::check_credentials(client_t _client, uid_t _uid, } for (const auto &p : its_policies) { + std::lock_guard its_policy_lock(p->mutex_); for (auto its_credential : p->ids_) { bool has_uid(false), has_gid(false); for (auto its_range : std::get<0>(its_credential)) { @@ -163,6 +164,7 @@ security_impl::is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, } for (const auto &p : its_policies) { + std::lock_guard its_policy_lock(p->mutex_); bool has_uid(false), has_gid(false), has_service(false), has_instance_id(false), has_method_id(false); for (auto its_credential : p->ids_) { has_uid = has_gid = false; @@ -183,35 +185,32 @@ security_impl::is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, break; } - for (auto its_offer : p->services_) { - if (std::get<0>(its_offer) == _service) { - for (auto its_ids : std::get<1>(its_offer)) { - has_service = has_instance_id = has_method_id = false; - for (auto its_instance_range : std::get<0>(its_ids)) { - if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) { - has_instance_id = true; - break; - } + auto its_service = p->services_.find(_service); + if (its_service != p->services_.end()) { + for (auto its_ids : its_service->second) { + has_service = has_instance_id = has_method_id = false; + for (auto its_instance_range : std::get<0>(its_ids)) { + if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) { + has_instance_id = true; + break; } - if (!_is_request_service) { - for (auto its_method_range : std::get<1>(its_ids)) { - if (std::get<0>(its_method_range) <= _method && _method <= std::get<1>(its_method_range)) { - has_method_id = true; - break; - } + } + if (!_is_request_service) { + for (auto its_method_range : std::get<1>(its_ids)) { + if (std::get<0>(its_method_range) <= _method && _method <= std::get<1>(its_method_range)) { + has_method_id = true; + break; } - } else { - // handle VSOMEIP_REQUEST_SERVICE - has_method_id = true; - } - - if (has_instance_id && has_method_id) { - has_service = true; - break; } + } else { + // handle VSOMEIP_REQUEST_SERVICE + has_method_id = true; } - if (has_service) + + if (has_instance_id && has_method_id) { + has_service = true; break; + } } } @@ -281,6 +280,7 @@ security_impl::is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, } for (const auto &p : its_policies) { + std::lock_guard its_policy_lock(p->mutex_); bool has_uid(false), has_gid(false), has_offer(false); for (auto its_credential : p->ids_) { has_uid = has_gid = false; @@ -301,21 +301,19 @@ security_impl::is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, break; } - for (auto its_offer : p->offers_) { - has_offer = false; - if (std::get<0>(its_offer) == _service) { - for (auto its_instance_range : std::get<1>(its_offer)) { - if (std::get<0>(its_instance_range) <= _instance && _instance <= std::get<1>(its_instance_range)) { - has_offer = true; - break; - } - } - if (has_offer) + auto find_service = p->offers_.find(_service); + if (find_service != p->offers_.end()) { + for (auto its_instance_range : find_service->second) { + if (std::get<0>(its_instance_range) <= _instance + && _instance <= std::get<1>(its_instance_range)) { + has_offer = true; break; + } } } - if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) { + if ((has_uid && has_gid && p->allow_who_) + || ((!has_uid || !has_gid) && !p->allow_who_)) { if (p->allow_what_ == has_offer) { return true; } @@ -458,6 +456,7 @@ security_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { if (!any_client_policies_.empty()) { std::vector>::iterator p_it = any_client_policies_.begin(); while (p_it != any_client_policies_.end()) { + std::lock_guard its_policy_lock((*p_it)->mutex_); bool has_uid(false), has_gid(false); for (auto its_credential : p_it->get()->ids_) { has_uid = has_gid = false; @@ -492,7 +491,7 @@ security_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { } void -security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr& _policy) { +security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr &_policy) { remove_security_policy(_uid, _gid); std::lock_guard its_lock(any_client_policies_mutex_); any_client_policies_.push_back(_policy); @@ -500,13 +499,14 @@ security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, const std::s void security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, - const std::shared_ptr& _credentials_policy, client_t _client) { + const std::shared_ptr &_policy, client_t _client) { bool was_found(false); std::lock_guard its_lock(any_client_policies_mutex_); - for (const auto& its_policy : any_client_policies_) { + for (const auto &p : any_client_policies_) { + std::lock_guard its_policy_lock(p->mutex_); bool has_uid(false), has_gid(false); - for (auto its_credential : its_policy->ids_) { + for (auto its_credential : p->ids_) { has_uid = has_gid = false; for (auto its_range : std::get<0>(its_credential)) { if (std::get<0>(its_range) <= _uid && _uid <= std::get<1>(its_range)) { @@ -520,7 +520,7 @@ security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, break; } } - if (has_uid && has_gid && its_policy->allow_who_) { + if (has_uid && has_gid && p->allow_who_) { was_found = true; break; } @@ -531,7 +531,7 @@ security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, } // Do not add the new (credentials-only-policy) if a allow credentials policy with same credentials was found if (!was_found) { - any_client_policies_.push_back(_credentials_policy); + any_client_policies_.push_back(_policy); VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x" << std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid; } @@ -581,6 +581,7 @@ security_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr & if (uid_allowed) { std::lock_guard its_lock(service_interface_whitelist_mutex_); + std::lock_guard its_policy_lock(_policy->mutex_); for (auto its_request : _policy->services_) { auto its_requested_service = std::get<0>(its_request); bool has_service(false); @@ -668,6 +669,8 @@ security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, // get user ID String if (parse_uid_gid(_buffer, _buffer_size, its_uid, its_gid)) { + std::lock_guard its_policy_lock(_policy->mutex_); + _uid = its_uid; _gid = its_gid; @@ -762,8 +765,14 @@ security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, parsed_req_bytes += (skip_array_length_ + instances_array_length); } if (!its_instance_method_ranges.empty()) { - _policy->services_.insert( + auto find_service = _policy->services_.find(its_service_id); + if (find_service != _policy->services_.end()) { + find_service->second.insert(its_instance_method_ranges.begin(), + its_instance_method_ranges.end()); + } else { + _policy->services_.insert( std::make_pair(its_service_id, its_instance_method_ranges)); + } } } } @@ -803,8 +812,14 @@ security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, parsed_offers_bytes += (skip_array_length_ + ids_array_length); } if (!its_instance_ranges.empty()) { - _policy->offers_.insert( - std::make_pair(its_service_id, its_instance_ranges)); + auto find_service = _policy->offers_.find(its_service_id); + if (find_service != _policy->offers_.end()) { + find_service->second.insert(its_instance_ranges.begin(), + its_instance_ranges.end()); + } else { + _policy->offers_.insert( + std::make_pair(its_service_id, its_instance_ranges)); + } } } } @@ -1166,8 +1181,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) { } } if (service != 0x0 && !its_instance_method_ranges.empty()) { - policy->services_.insert( + auto find_policy = policy->services_.find(service); + if (find_policy != policy->services_.end()) { + find_policy->second.insert(its_instance_method_ranges.begin(), + its_instance_method_ranges.end()); + } else { + policy->services_.insert( std::make_pair(service, its_instance_method_ranges)); + } } } } else if (l->first == "offers") { @@ -1197,8 +1218,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) { } } if (service != 0x0 && !its_instance_ranges.empty()) { - policy->offers_.insert( - std::make_pair(service, its_instance_ranges)); + auto find_service = policy->offers_.find(service); + if (find_service != policy->offers_.end()) { + find_service->second.insert(its_instance_ranges.begin(), + its_instance_ranges.end()); + } else { + policy->offers_.insert( + std::make_pair(service, its_instance_ranges)); + } } } } @@ -1268,8 +1295,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) { } } if (service != 0x0 && !its_instance_method_ranges.empty()) { - policy->services_.insert( + auto find_policy = policy->services_.find(service); + if (find_policy != policy->services_.end()) { + find_policy->second.insert(its_instance_method_ranges.begin(), + its_instance_method_ranges.end()); + } else { + policy->services_.insert( std::make_pair(service, its_instance_method_ranges)); + } } } } @@ -1300,8 +1333,14 @@ security_impl::load_policy(const boost::property_tree::ptree &_tree) { } } if (service != 0x0 && !its_instance_ranges.empty()) { - policy->offers_.insert( - std::make_pair(service, its_instance_ranges)); + auto find_service = policy->offers_.find(service); + if (find_service != policy->offers_.end()) { + find_service->second.insert(its_instance_ranges.begin(), + its_instance_ranges.end()); + } else { + policy->offers_.insert( + std::make_pair(service, its_instance_ranges)); + } } } } @@ -1620,7 +1659,7 @@ static void security_teardown(void) __attribute__((destructor)); static void security_teardown(void) { if (the_security_ptr__ != nullptr) { - std::lock_guard itsLock(the_security_mutex__); + std::lock_guard its_lock(the_security_mutex__); the_security_ptr__->reset(); delete the_security_ptr__; the_security_ptr__ = nullptr; diff --git a/implementation/service_discovery/include/selective_option_impl.hpp b/implementation/service_discovery/include/selective_option_impl.hpp index 0660f1e..863408f 100644 --- a/implementation/service_discovery/include/selective_option_impl.hpp +++ b/implementation/service_discovery/include/selective_option_impl.hpp @@ -28,6 +28,7 @@ public: bool operator==(const option_impl &_other) const; std::set get_clients() const; + void set_clients(const std::set &_clients); bool add_client(client_t _client); bool remove_client(client_t _client); bool has_clients() const; diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index 0a5adc0..778ce08 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -19,6 +19,7 @@ namespace vsomeip_v3 { class configuration; +class eventgroupinfo; namespace sd { @@ -39,7 +40,8 @@ public: virtual void subscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - ttl_t _ttl, client_t _client) = 0; + ttl_t _ttl, client_t _client, + const std::shared_ptr& _info) = 0; 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; diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index 94b67ec..88e093b 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -69,10 +69,15 @@ public: const boost::asio::ip::address &_address, uint16_t _port) = 0; virtual std::shared_ptr find_or_create_remote_client( - service_t _service, instance_t _instance, bool _reliable, client_t _client) = 0; + service_t _service, instance_t _instance, bool _reliable) = 0; virtual void expire_subscriptions(const boost::asio::ip::address &_address) = 0; + virtual void expire_subscriptions(const boost::asio::ip::address &_address, + std::uint16_t _port, bool _reliable) = 0; virtual void expire_services(const boost::asio::ip::address &_address) = 0; + virtual void expire_services(const boost::asio::ip::address &_address, + std::uint16_t _port, bool _reliable) = 0; + virtual void on_remote_subscribe( std::shared_ptr &_subscription, @@ -88,6 +93,9 @@ public: service_t _service, instance_t _instance) const = 0; virtual std::map> get_offered_service_instances( service_t _service) const = 0; + + virtual std::set get_subscribed_eventgroups(service_t _service, + instance_t _instance) = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index ba3c723..53b18c0 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -75,7 +75,7 @@ public: void subscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, - client_t _client); + client_t _client, const std::shared_ptr& _info); void unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, client_t _client); void unsubscribe_all(service_t _service, instance_t _instance); @@ -128,18 +128,30 @@ private: entry_data_t create_eventgroup_entry( service_t _service, instance_t _instance, eventgroup_t _eventgroup, const std::shared_ptr &_subscription, - remote_offer_type_e _offer_type); + reliability_type_e _offer_type); void insert_subscription_ack( const std::shared_ptr& _acknowledgement, const std::shared_ptr &_info, ttl_t _ttl, - const std::shared_ptr &_target = nullptr, - const client_t _client = VSOMEIP_ROUTING_CLIENT); + const std::shared_ptr &_target, + const std::set &_clients); + typedef std::set> expired_ports_t; + struct sd_acceptance_state_t { + explicit sd_acceptance_state_t(expired_ports_t& _expired_ports) + : expired_ports_(_expired_ports), + sd_acceptance_required_(false), + accept_entries_(false) { + } + + expired_ports_t& expired_ports_; + bool sd_acceptance_required_; + bool accept_entries_; + }; void process_serviceentry(std::shared_ptr &_entry, const std::vector > &_options, bool _unicast_flag, std::vector > &_resubscribes, - bool _received_via_mcast, bool _accept_offers); + bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state); void process_offerservice_serviceentry( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl, @@ -148,7 +160,7 @@ private: const boost::asio::ip::address &_unreliable_address, uint16_t _unreliable_port, std::vector > &_resubscribes, - bool _received_via_mcast); + bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state); void send_offer_service( const std::shared_ptr &_info, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, @@ -164,7 +176,8 @@ private: const std::vector > &_options, std::shared_ptr &_acknowledgement, const boost::asio::ip::address &_destination, - bool _is_stop_subscribe_subscribe, bool _force_initial_events); + bool _is_stop_subscribe_subscribe, bool _force_initial_events, + const sd_acceptance_state_t& _sd_ac_state); void handle_eventgroup_subscription(service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, uint8_t _counter, uint16_t _reserved, @@ -175,6 +188,7 @@ private: std::shared_ptr &_acknowledgement, bool _is_stop_subscribe_subscribe, bool _force_initial_events, const std::set &_clients, + const sd_acceptance_state_t& _sd_ac_state, const std::shared_ptr& _info); void handle_eventgroup_subscription_ack(service_t _service, instance_t _instance, eventgroup_t _eventgroup, @@ -300,16 +314,23 @@ private: bool update_remote_offer_type(service_t _service, instance_t _instance, remote_offer_type_e _offer_type, const boost::asio::ip::address &_reliable_address, - const boost::asio::ip::address &_unreliable_address); + std::uint16_t _reliable_port, + const boost::asio::ip::address &_unreliable_address, + std::uint16_t _unreliable_port); void remove_remote_offer_type(service_t _service, instance_t _instance, - const boost::asio::ip::address &_address); + const boost::asio::ip::address &_reliable_address, + std::uint16_t _reliable_port, + const boost::asio::ip::address &_unreliable_address, + std::uint16_t _unreliable_port); void remove_remote_offer_type_by_ip(const boost::asio::ip::address &_address); + void remove_remote_offer_type_by_ip(const boost::asio::ip::address &_address, + std::uint16_t _port, bool _reliable); std::shared_ptr create_subscription( - service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, const std::shared_ptr &_reliable, - const std::shared_ptr &_unreliable); + const std::shared_ptr &_unreliable, + const std::shared_ptr &_info); std::shared_ptr get_remote_subscription( const service_t _service, const instance_t _instance, @@ -332,6 +353,9 @@ private: void add_entry_data_to_remote_subscription_ack_msg( const std::shared_ptr& _acknowledgement, const entry_data_t &_data); + reliability_type_e get_eventgroup_reliability( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const std::shared_ptr& _subscription); private: boost::asio::io_service &io_; @@ -436,7 +460,9 @@ private: mutable std::mutex remote_offer_types_mutex_; std::map, remote_offer_type_e> remote_offer_types_; - std::map>> remote_offers_by_ip_; + std::map, + std::set>>> remote_offers_by_ip_; reboot_notification_handler_t reboot_notification_handler_; sd_acceptance_handler_t sd_acceptance_handler_; diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp index f172348..adbd66c 100644 --- a/implementation/service_discovery/include/subscription.hpp +++ b/implementation/service_discovery/include/subscription.hpp @@ -17,6 +17,7 @@ namespace vsomeip_v3 { class endpoint; +class eventgroupinfo; namespace sd { @@ -60,6 +61,9 @@ public: bool has_client() const; bool has_client(const client_t _client) const; + void set_eventgroupinfo(const std::shared_ptr _info); + std::weak_ptr get_eventgroupinfo() const; + private: major_version_t major_; ttl_t ttl_; @@ -74,6 +78,8 @@ private: mutable std::mutex clients_mutex_; std::map clients_; // client-> is acknowledged? + + std::weak_ptr eg_info_; }; } // namespace sd diff --git a/implementation/service_discovery/src/remote_subscription_ack.cpp b/implementation/service_discovery/src/remote_subscription_ack.cpp index 80be082..03270c9 100644 --- a/implementation/service_discovery/src/remote_subscription_ack.cpp +++ b/implementation/service_discovery/src/remote_subscription_ack.cpp @@ -59,15 +59,14 @@ remote_subscription_ack::get_target_address() const { bool remote_subscription_ack::is_pending() const { for (const auto& its_subscription : subscriptions_) { - if (its_subscription->is_pending()) { + if (its_subscription->is_pending() + && its_subscription->get_answers() != 0) { return true; } } return false; } - - std::set > remote_subscription_ack::get_subscriptions() const { return subscriptions_; diff --git a/implementation/service_discovery/src/selective_option_impl.cpp b/implementation/service_discovery/src/selective_option_impl.cpp index c61be22..17063d9 100755 --- a/implementation/service_discovery/src/selective_option_impl.cpp +++ b/implementation/service_discovery/src/selective_option_impl.cpp @@ -36,6 +36,11 @@ std::set selective_option_impl::get_clients() const { return (its_clients); } +void selective_option_impl::set_clients(const std::set &_clients) { + clients_ = _clients; + length_ = uint16_t(1 + clients_.size() * sizeof(client_t)); +} + bool selective_option_impl::add_client(client_t _client) { auto its_result = clients_.insert(_client); length_ = uint16_t(1 + clients_.size() * sizeof(client_t)); diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index e5c4a32..7ae5395 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -35,6 +35,7 @@ #include "../../endpoints/include/udp_server_endpoint_impl.hpp" #include "../../message/include/serializer.hpp" #include "../../plugin/include/plugin_manager_impl.hpp" +#include "../../routing/include/event.hpp" #include "../../routing/include/eventgroupinfo.hpp" #include "../../routing/include/serviceinfo.hpp" #include "../../utility/include/byteorder.hpp" @@ -73,7 +74,7 @@ service_discovery_impl::service_discovery_impl( last_msg_received_timer_(_host->get_io()), last_msg_received_timer_timeout_(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY + (VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY / 10)) { - // TODO: cleanup start condition! + next_subscription_expiration_ = std::chrono::steady_clock::now() + std::chrono::hours(24); } @@ -234,31 +235,45 @@ void service_discovery_impl::subscribe( service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - ttl_t _ttl, client_t _client) { - { - std::lock_guard its_lock(subscribed_mutex_); - 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()) { - auto found_eventgroup = found_instance->second.find(_eventgroup); - if (found_eventgroup != found_instance->second.end()) { - auto its_subscription = found_eventgroup->second; - if (its_subscription->get_major() != _major) { - VSOMEIP_ERROR - << "Subscriptions to different versions of the same " - "service instance are not supported!"; - } else if (its_subscription->is_selective()) { - if (its_subscription->add_client(_client)) { - its_subscription->set_state(_client, - subscription_state_e::ST_NOT_ACKNOWLEDGED); - send_subscription(its_subscription, - _service, _instance, _eventgroup, - _client); + ttl_t _ttl, client_t _client, + const std::shared_ptr &_info) { +#ifdef VSOMEIP_ENABLE_COMPAT + bool is_selective(_info ? _info->is_selective() : false); +#endif // VSOMEIP_ENABLE_COMPAT + + std::lock_guard its_lock(subscribed_mutex_); + 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()) { + auto found_eventgroup = found_instance->second.find(_eventgroup); + if (found_eventgroup != found_instance->second.end()) { + auto its_subscription = found_eventgroup->second; +#ifdef VSOMEIP_ENABLE_COMPAT + if (!its_subscription->is_selective() && is_selective) { + its_subscription->set_selective(true); + its_subscription->remove_client(VSOMEIP_ROUTING_CLIENT); + for (const auto e : _info->get_events()) { + for (const auto c : e->get_subscribers(_eventgroup)) { + its_subscription->add_client(c); } } - return; } +#endif // VSOMEIP_ENABLE_COMPAT + if (its_subscription->get_major() != _major) { + VSOMEIP_ERROR + << "Subscriptions to different versions of the same " + "service instance are not supported!"; + } else if (its_subscription->is_selective()) { + if (its_subscription->add_client(_client)) { + its_subscription->set_state(_client, + subscription_state_e::ST_NOT_ACKNOWLEDGED); + send_subscription(its_subscription, + _service, _instance, _eventgroup, + _client); + } + } + return; } } } @@ -267,31 +282,26 @@ service_discovery_impl::subscribe( get_subscription_endpoints(_service, _instance, its_reliable, its_unreliable); - { - std::lock_guard its_lock(subscribed_mutex_); + // New subscription + std::shared_ptr its_subscription + = create_subscription( + _major, _ttl, its_reliable, its_unreliable, _info); - // New subscription - std::shared_ptr its_subscription - = create_subscription( - _service, _instance, _eventgroup, _major, - _ttl, its_reliable, its_unreliable); - - if (!its_subscription) { - VSOMEIP_ERROR << __func__ - << ": creating subscription failed!"; - return; - } + if (!its_subscription) { + VSOMEIP_ERROR << __func__ + << ": creating subscription failed!"; + return; + } - subscribed_[_service][_instance][_eventgroup] = its_subscription; + subscribed_[_service][_instance][_eventgroup] = its_subscription; - its_subscription->add_client(_client); - its_subscription->set_state(_client, - subscription_state_e::ST_NOT_ACKNOWLEDGED); + its_subscription->add_client(_client); + its_subscription->set_state(_client, + subscription_state_e::ST_NOT_ACKNOWLEDGED); - send_subscription(its_subscription, - _service, _instance, _eventgroup, - _client); - } + send_subscription(its_subscription, + _service, _instance, _eventgroup, + _client); } void @@ -300,38 +310,36 @@ service_discovery_impl::send_subscription( const service_t _service, const instance_t _instance, const eventgroup_t _eventgroup, const client_t _client) { + (void)_client; + auto its_reliable = _subscription->get_endpoint(true); auto its_unreliable = _subscription->get_endpoint(false); boost::asio::ip::address its_address; get_subscription_address(its_reliable, its_unreliable, its_address); - if (!its_address.is_unspecified()) { entry_data_t its_data; - - const remote_offer_type_e its_offer_type - = get_remote_offer_type(_service, _instance); - if (its_offer_type == remote_offer_type_e::UNRELIABLE && - !its_reliable && its_unreliable) { + const reliability_type_e its_reliability_type = + get_eventgroup_reliability(_service, _instance, _eventgroup, _subscription); + if (its_reliability_type == reliability_type_e::RT_UNRELIABLE && its_unreliable) { if (its_unreliable->is_established()) { its_data = create_eventgroup_entry(_service, _instance, - _eventgroup, _subscription, its_offer_type); + _eventgroup, _subscription, its_reliability_type); } else { _subscription->set_udp_connection_established(false); } - } else if (its_offer_type == remote_offer_type_e::RELIABLE && - its_reliable && !its_unreliable) { + } else if (its_reliability_type == reliability_type_e::RT_RELIABLE && its_reliable) { if (its_reliable->is_established()) { its_data = create_eventgroup_entry(_service, _instance, - _eventgroup, _subscription, its_offer_type); + _eventgroup, _subscription, its_reliability_type); } else { _subscription->set_tcp_connection_established(false); } - } else if (its_offer_type == remote_offer_type_e::RELIABLE_UNRELIABLE && + } else if (its_reliability_type == reliability_type_e::RT_BOTH && its_reliable && its_unreliable) { if (its_reliable->is_established() && its_unreliable->is_established()) { its_data = create_eventgroup_entry(_service, _instance, - _eventgroup, _subscription, its_offer_type); + _eventgroup, _subscription, its_reliability_type); } else { if (!its_reliable->is_established()) { _subscription->set_tcp_connection_established(false); @@ -340,16 +348,14 @@ service_discovery_impl::send_subscription( _subscription->set_udp_connection_established(false); } } + } else if (its_reliability_type == reliability_type_e::RT_UNKNOWN) { + VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't determine reliability type for subscription to [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "] "; } if (its_data.entry_) { - if (_subscription->is_selective()) { - auto its_selective_option = std::make_shared(); - (void)its_selective_option->add_client(_client); - - its_data.options_.push_back(its_selective_option); - } - // TODO: Implement a simple path, that sends a single message auto its_current_message = std::make_shared(); std::vector > its_messages; @@ -368,9 +374,9 @@ service_discovery_impl::get_subscription_endpoints( std::shared_ptr &_reliable, std::shared_ptr &_unreliable) const { _unreliable = host_->find_or_create_remote_client( - _service, _instance, false, VSOMEIP_ROUTING_CLIENT); + _service, _instance, false); _reliable = host_->find_or_create_remote_client( - _service, _instance, true, VSOMEIP_ROUTING_CLIENT); + _service, _instance, true); } void @@ -423,28 +429,37 @@ service_discovery_impl::unsubscribe(service_t _service, if (!its_subscription->has_client()) { its_subscription->set_ttl(0); } else if (its_subscription->is_selective()) { - auto its_major = its_subscription->get_major(); - // create a dummy subscription object to unsubscribe // the single client. + auto its_major = its_subscription->get_major(); + its_subscription = std::make_shared(); its_subscription->set_major(its_major); its_subscription->set_ttl(0); its_subscription->set_selective(true); - its_subscription->add_client(_client); its_subscription->set_endpoint(its_reliable, true); its_subscription->set_endpoint(its_unreliable, false); } } - const remote_offer_type_e its_offer_type - = get_remote_offer_type(its_subscription); + // For selective subscriptions, the client must be added again + // to generate the selective option + if (its_subscription->is_selective()) + its_subscription->add_client(_client); + const reliability_type_e its_reliability_type = + get_eventgroup_reliability(_service, _instance, _eventgroup, its_subscription); auto its_data = create_eventgroup_entry(_service, _instance, - _eventgroup, its_subscription, its_offer_type); - if (its_data.entry_) { + _eventgroup, its_subscription, its_reliability_type); + if (its_data.entry_) its_current_message->add_entry_data(its_data.entry_, its_data.options_); - } + + // Remove it again before updating (only impacts last unsubscribe) + if (its_subscription->is_selective()) + (void)its_subscription->remove_client(_client); + + // Ensure to update the "real" subscription + its_subscription = found_eventgroup->second; // Finally update the subscriptions if (!its_subscription->has_client()) { @@ -470,8 +485,6 @@ service_discovery_impl::unsubscribe_all( auto its_current_message = std::make_shared();; boost::asio::ip::address its_address; - const remote_offer_type_e its_offer_type - = get_remote_offer_type(_service, _instance); { std::lock_guard its_lock(subscribed_mutex_); @@ -482,8 +495,13 @@ service_discovery_impl::unsubscribe_all( for (auto &its_eventgroup : found_instance->second) { auto its_subscription = its_eventgroup.second; its_subscription->set_ttl(0); + + const reliability_type_e its_reliability = + get_eventgroup_reliability(_service, _instance, + its_eventgroup.first, its_subscription); + auto its_data = create_eventgroup_entry(_service, _instance, - its_eventgroup.first, its_subscription, its_offer_type); + its_eventgroup.first, its_subscription, its_reliability); auto its_reliable = its_subscription->get_endpoint(true); auto its_unreliable = its_subscription->get_endpoint(false); get_subscription_address( @@ -672,7 +690,7 @@ entry_data_t service_discovery_impl::create_eventgroup_entry( service_t _service, instance_t _instance, eventgroup_t _eventgroup, const std::shared_ptr &_subscription, - remote_offer_type_e _offer_type) { + reliability_type_e _reliability_type) { entry_data_t its_data; its_data.entry_ = nullptr; @@ -683,18 +701,18 @@ service_discovery_impl::create_eventgroup_entry( bool insert_reliable(false); bool insert_unreliable(false); - switch (_offer_type) { - case remote_offer_type_e::RELIABLE: + switch (_reliability_type) { + case reliability_type_e::RT_RELIABLE: if (its_reliable_endpoint) { insert_reliable = true; } break; - case remote_offer_type_e::UNRELIABLE: + case reliability_type_e::RT_UNRELIABLE: if (its_unreliable_endpoint) { insert_unreliable = true; } break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: + case reliability_type_e::RT_BOTH: if (its_reliable_endpoint && its_unreliable_endpoint) { insert_reliable = true; insert_unreliable = true; @@ -705,13 +723,13 @@ service_discovery_impl::create_eventgroup_entry( } if (!insert_reliable && !insert_unreliable - && _offer_type != remote_offer_type_e::UNKNOWN) { + && _reliability_type != reliability_type_e::RT_UNKNOWN) { VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as " - "subscription doesn't match offer type: [" + "subscription doesn't match reliability type: [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "] " - << _offer_type; + << (uint16_t) _reliability_type; return its_data; } std::shared_ptr its_entry, its_other; @@ -753,11 +771,13 @@ service_discovery_impl::create_eventgroup_entry( auto its_option = create_ip_option(unicast_, its_port, true); its_data.options_.push_back(its_option); } else { - VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as " + VSOMEIP_WARNING << __func__ << ": Cannot create subscription as " "local reliable port is zero: [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; + its_data.entry_ = nullptr; + its_data.other_ = nullptr; return its_data; } } @@ -805,21 +825,20 @@ service_discovery_impl::create_eventgroup_entry( auto its_option = create_ip_option(unicast_, its_port, false); its_data.options_.push_back(its_option); } else { - VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as " + VSOMEIP_WARNING << __func__ << ": Cannot create subscription as " " local unreliable port is zero: [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; + its_data.entry_ = nullptr; + its_data.other_ = nullptr; return its_data; } } - if (its_entry - &&_subscription->is_selective()) { + if (its_entry &&_subscription->is_selective()) { auto its_selective_option = std::make_shared(); - for (const auto &its_client : _subscription->get_clients()) - (void)its_selective_option->add_client(its_client); - + its_selective_option->set_clients(_subscription->get_clients()); its_data.options_.push_back(its_selective_option); } @@ -836,7 +855,7 @@ service_discovery_impl::insert_subscription_ack( const std::shared_ptr& _acknowledgement, const std::shared_ptr &_info, ttl_t _ttl, const std::shared_ptr &_target, - const client_t _client) { + const std::set &_clients) { std::unique_lock its_lock(_acknowledgement->get_lock()); auto its_message = _acknowledgement->get_current_message(); @@ -871,11 +890,10 @@ service_discovery_impl::insert_subscription_ack( } } - if (_client != VSOMEIP_ROUTING_CLIENT) { + if (_clients.size() > 1 || (*(_clients.begin())) != 0) { auto its_selective_option = its_eventgroup_entry->get_selective_option(); - if (its_selective_option) { - its_selective_option->add_client(_client); - } + if (its_selective_option) + its_selective_option->set_clients(_clients); } return; @@ -911,10 +929,11 @@ service_discovery_impl::insert_subscription_ack( its_data.options_.push_back(its_option); } } + // Selective - if (_client != VSOMEIP_ROUTING_CLIENT) { + if (_clients.size() > 1 || (*(_clients.begin())) != 0) { auto its_selective_option = std::make_shared(); - (void)its_selective_option->add_client(_client); + (void)its_selective_option->set_clients(_clients); its_data.options_.push_back(its_selective_option); } @@ -1031,43 +1050,30 @@ service_discovery_impl::on_message( bool force_initial_events(false); bool sd_acceptance_queried(false); - bool accept_offers(false); - bool expired_services(false); + expired_ports_t expired_ports; + sd_acceptance_state_t accept_state(expired_ports); for (auto iter = its_entries.begin(); iter != its_end; iter++) { if (!sd_acceptance_queried) { + sd_acceptance_queried = true; if (sd_acceptance_handler_) { + accept_state.sd_acceptance_required_ + = configuration_->is_protected_device(_sender); remote_info_t remote; - remote.port_ = ANY_PORT; remote.first_ = ANY_PORT; remote.last_ = ANY_PORT; remote.is_range_ = false; - if (configuration_->sd_acceptance_required(_sender, ANY_PORT)) { - if (_sender.is_v4()) { - remote.ip_.address_.v4_ = _sender.to_v4().to_bytes(); - remote.ip_.is_v4_ = true; - } else { - remote.ip_.address_.v6_ = _sender.to_v6().to_bytes(); - remote.ip_.is_v4_ = false; - } - accept_offers = sd_acceptance_handler_(remote); - if (!accept_offers && !expired_services) { - VSOMEIP_WARNING << "service_discovery_impl::" << __func__ - << ": Do not accept offer / subscribe from " - << std::hex << std::setw(4) << std::setfill('0') - << _sender.to_string(); - remove_remote_offer_type_by_ip(_sender); - host_->expire_subscriptions(_sender); - host_->expire_services(_sender); - expired_services = true; - } + if (_sender.is_v4()) { + remote.ip_.address_.v4_ = _sender.to_v4().to_bytes(); + remote.ip_.is_v4_ = true; } else { - accept_offers = true; + remote.ip_.address_.v6_ = _sender.to_v6().to_bytes(); + remote.ip_.is_v4_ = false; } + accept_state.accept_entries_ = sd_acceptance_handler_(remote); } else { - accept_offers = true; + accept_state.accept_entries_ = true; } - sd_acceptance_queried = true; } if ((*iter)->is_service_entry()) { std::shared_ptr its_service_entry @@ -1075,8 +1081,8 @@ service_discovery_impl::on_message( bool its_unicast_flag = its_message->get_unicast_flag(); process_serviceentry(its_service_entry, its_options, its_unicast_flag, its_resubscribes, - received_via_mcast, accept_offers); - } else if (accept_offers) { + received_via_mcast, accept_state); + } else { std::shared_ptr its_eventgroup_entry = std::dynamic_pointer_cast(*iter); @@ -1095,7 +1101,8 @@ service_discovery_impl::on_message( check_stop_subscribe_subscribe(iter, its_end, its_options); process_eventgroupentry(its_eventgroup_entry, its_options, its_acknowledgement, _destination, - is_stop_subscribe_subscribe, force_initial_events); + is_stop_subscribe_subscribe, force_initial_events, + accept_state); } } @@ -1139,7 +1146,8 @@ service_discovery_impl::process_serviceentry( const std::vector > &_options, bool _unicast_flag, std::vector > &_resubscribes, - bool _received_via_mcast, bool _accept_offers) { + bool _received_via_mcast, + const sd_acceptance_state_t& _sd_ac_state) { // Read service info from entry entry_type_e its_type = _entry->get_type(); @@ -1221,20 +1229,17 @@ service_discovery_impl::process_serviceentry( its_major, its_minor, _unicast_flag); break; case entry_type_e::OFFER_SERVICE: - if (_accept_offers) { process_offerservice_serviceentry(its_service, its_instance, its_major, its_minor, its_ttl, its_reliable_address, its_reliable_port, its_unreliable_address, its_unreliable_port, _resubscribes, - _received_via_mcast); - } + _received_via_mcast, _sd_ac_state); break; case entry_type_e::UNKNOWN: default: VSOMEIP_ERROR << __func__ << ": Unsupported service entry type"; } - - } else if (_accept_offers) { + } else if (!_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_) { std::shared_ptr its_request = find_request(its_service, its_instance); if (its_request) { std::lock_guard its_lock(requested_mutex_); @@ -1242,8 +1247,8 @@ service_discovery_impl::process_serviceentry( its_request->set_sent_counter(std::uint8_t(repetitions_max_ + 1)); } remove_remote_offer_type(its_service, its_instance, - (its_reliable_port != ILLEGAL_PORT ? - its_reliable_address : its_unreliable_address)); + its_reliable_address, its_reliable_port, + its_unreliable_address, its_unreliable_port); unsubscribe_all(its_service, its_instance); if (!is_diagnosis_ && !is_suspended_) { host_->del_routing_info(its_service, its_instance, @@ -1262,7 +1267,7 @@ service_discovery_impl::process_offerservice_serviceentry( const boost::asio::ip::address &_unreliable_address, uint16_t _unreliable_port, std::vector > &_resubscribes, - bool _received_via_mcast) { + bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state) { std::shared_ptr < runtime > its_runtime = runtime_.lock(); if (!its_runtime) return; @@ -1290,11 +1295,106 @@ service_discovery_impl::process_offerservice_serviceentry( << std::hex << std::setw(4) << std::setfill('0') << _instance << "]"; } - if (update_remote_offer_type(_service,_instance, offer_type, - _reliable_address, _unreliable_address)) { + if (_sd_ac_state.sd_acceptance_required_) { + + auto expire_subscriptions_and_services = + [this, &_sd_ac_state](const boost::asio::ip::address& _address, + std::uint16_t _port, bool _reliable) { + const auto its_port_pair = std::make_pair(_reliable, _port); + if (_sd_ac_state.expired_ports_.find(its_port_pair) == + _sd_ac_state.expired_ports_.end()) { + VSOMEIP_WARNING << "service_discovery_impl::" << __func__ + << ": Do not accept offer from " + << _address.to_string() << ":" + << std::dec << _port << " reliable=" << _reliable; + remove_remote_offer_type_by_ip(_address, _port, _reliable); + host_->expire_subscriptions(_address, _port, _reliable); + host_->expire_services(_address, _port, _reliable); + _sd_ac_state.expired_ports_.insert(its_port_pair); + } + }; + + // return if the registered sd_acceptance handler returned false + // and for the provided port sd_acceptance is necessary + switch (offer_type) { + case remote_offer_type_e::UNRELIABLE: + if (!_sd_ac_state.accept_entries_ + && configuration_->is_protected_port( + _unreliable_address, _unreliable_port, false)) { + expire_subscriptions_and_services(_unreliable_address, + _unreliable_port, false); + return; + } + break; + case remote_offer_type_e::RELIABLE: + if (!_sd_ac_state.accept_entries_ + && configuration_->is_protected_port( + _reliable_address, _reliable_port, true)) { + expire_subscriptions_and_services(_reliable_address, + _reliable_port, true); + return; + } + break; + case remote_offer_type_e::RELIABLE_UNRELIABLE: + if (!_sd_ac_state.accept_entries_ + && (configuration_->is_protected_port( + _unreliable_address, _unreliable_port, false) + || configuration_->is_protected_port( + _reliable_address, _reliable_port, true))) { + expire_subscriptions_and_services(_unreliable_address, + _unreliable_port, false); + expire_subscriptions_and_services(_reliable_address, + _reliable_port, true); + return; + } + break; + case remote_offer_type_e::UNKNOWN: + default: + break; + } + } + + if (update_remote_offer_type(_service, _instance, offer_type, + _reliable_address, _reliable_port, + _unreliable_address, _unreliable_port)) { VSOMEIP_WARNING << __func__ << ": Remote offer type changed [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "]"; + + // Only update eventgroup reliability type if it was initially unknown + auto its_eventgroups = host_->get_subscribed_eventgroups(_service, _instance); + for (auto eg : its_eventgroups) { + auto its_info = host_->find_eventgroup( + _service, _instance, eg); + if (its_info) { + if (its_info->is_reliability_auto_mode()) { + reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); + switch (offer_type) { + case remote_offer_type_e::RELIABLE: + its_reliability = reliability_type_e::RT_RELIABLE; + break; + case remote_offer_type_e::UNRELIABLE: + its_reliability = reliability_type_e::RT_UNRELIABLE; + break; + case remote_offer_type_e::RELIABLE_UNRELIABLE: + its_reliability = reliability_type_e::RT_BOTH; + break; + default: + ; + } + if (its_reliability != reliability_type_e::RT_UNKNOWN + && its_reliability != its_info->get_reliability()) { + VSOMEIP_WARNING << "sd::" << __func__ << ": eventgroup reliability type changed [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << eg << "]" + << " using reliability type: " + << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) its_reliability; + its_info->set_reliability(its_reliability); + } + } + } + } } host_->add_routing_info(_service, _instance, @@ -1314,8 +1414,6 @@ service_discovery_impl::process_offerservice_serviceentry( auto found_instance = found_service->second.find(_instance); if (found_instance != found_service->second.end()) { if (0 < found_instance->second.size()) { - const remote_offer_type_e its_offer_type = - get_remote_offer_type(_service, _instance); for (const auto& its_eventgroup : found_instance->second) { auto its_subscription = its_eventgroup.second; std::shared_ptr its_reliable, its_unreliable; @@ -1333,8 +1431,12 @@ service_discovery_impl::process_offerservice_serviceentry( subscription_state_e::ST_RESUBSCRIBING_NOT_ACKNOWLEDGED); } } + const reliability_type_e its_reliability = + get_eventgroup_reliability(_service, _instance, + its_eventgroup.first, its_subscription); + auto its_data = create_eventgroup_entry(_service, _instance, - its_eventgroup.first, its_subscription, its_offer_type); + its_eventgroup.first, its_subscription, its_reliability); if (its_data.entry_) { add_entry_data(_resubscribes, its_data); } @@ -1443,8 +1545,6 @@ service_discovery_impl::on_endpoint_connected( auto found_instance = found_service->second.find(_instance); if (found_instance != found_service->second.end()) { if (0 < found_instance->second.size()) { - const remote_offer_type_e its_offer_type = - get_remote_offer_type(_service, _instance); for (const auto &its_eventgroup : found_instance->second) { std::shared_ptr its_subscription(its_eventgroup.second); if (its_subscription) { @@ -1487,8 +1587,10 @@ service_discovery_impl::on_endpoint_connected( its_subscription->set_state(its_client, subscription_state_e::ST_NOT_ACKNOWLEDGED); + const reliability_type_e its_reliability_type = + get_eventgroup_reliability(_service, _instance, its_eventgroup.first, its_subscription); auto its_data = create_eventgroup_entry(_service, _instance, - its_eventgroup.first, its_subscription, its_offer_type); + its_eventgroup.first, its_subscription, its_reliability_type); if (its_data.entry_) { add_entry_data(its_messages, its_data); @@ -1571,7 +1673,10 @@ service_discovery_impl::process_eventgroupentry( const std::vector > &_options, std::shared_ptr &_acknowledgement, const boost::asio::ip::address &_destination, - bool _is_stop_subscribe_subscribe, bool _force_initial_events) { + bool _is_stop_subscribe_subscribe, bool _force_initial_events, + const sd_acceptance_state_t& _sd_ac_state) { + + std::set its_clients({0}); // maybe overridden for selectives auto its_sender = _acknowledgement->get_target_address(); auto its_session = _entry->get_owning_message()->get_session(); @@ -1601,7 +1706,7 @@ service_discovery_impl::process_eventgroupentry( << "] session: " << std::hex << std::setw(4) << std::setfill('0') << its_session << ", ttl: " << its_ttl; if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } } else { // We received a subscription [n]ack for an eventgroup that does not exist. @@ -1617,7 +1722,7 @@ service_discovery_impl::process_eventgroupentry( << its_sender.to_string(ec) << " session: " << std::hex << std::setw(4) << std::setfill('0') << its_session; if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } return; } @@ -1630,7 +1735,7 @@ service_discovery_impl::process_eventgroupentry( << its_sender.to_string(ec) << " session: " << std::hex << std::setw(4) << std::setfill('0') << its_session; if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } return; } @@ -1644,7 +1749,7 @@ service_discovery_impl::process_eventgroupentry( if (its_ttl > 0) { // increase number of required acks by one as number required acks // is calculated based on the number of referenced options - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } return; } @@ -1655,7 +1760,7 @@ service_discovery_impl::process_eventgroupentry( << its_sender.to_string(ec) << " session: " << std::hex << std::setw(4) << std::setfill('0') << its_session; if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } return; } @@ -1672,7 +1777,7 @@ service_discovery_impl::process_eventgroupentry( << std::hex << std::setw(4) << std::setfill('0') << its_session; if (its_ttl > 0) { // set to 0 to ensure an answer containing at least this subscribe_nack is sent out - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } return; } @@ -1697,7 +1802,6 @@ service_discovery_impl::process_eventgroupentry( boost::asio::ip::address its_second_address; uint16_t its_second_port(ILLEGAL_PORT); bool is_second_reliable(false); - std::set its_clients({0}); // maybe overridden for selectives for (auto i : { 1, 2 }) { for (auto its_index : _entry->get_options(uint8_t(i))) { @@ -1718,7 +1822,7 @@ service_discovery_impl::process_eventgroupentry( << std::hex << std::setw(4) << std::setfill('0') << its_session; if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type && its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } return; } @@ -1733,7 +1837,7 @@ service_discovery_impl::process_eventgroupentry( its_ipv4_option->get_address()); if (!check_layer_four_protocol(its_ipv4_option)) { if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } return; } @@ -1749,7 +1853,7 @@ service_discovery_impl::process_eventgroupentry( if (is_first_reliable == is_second_reliable && its_second_port != ILLEGAL_PORT) { if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } boost::system::error_code ec; VSOMEIP_ERROR << __func__ @@ -1763,7 +1867,7 @@ service_discovery_impl::process_eventgroupentry( if (!check_ipv4_address(its_first_address) || 0 == its_first_port) { if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } boost::system::error_code ec; VSOMEIP_ERROR << __func__ @@ -1784,7 +1888,7 @@ service_discovery_impl::process_eventgroupentry( if (is_second_reliable == is_first_reliable && its_first_port != ILLEGAL_PORT) { if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } boost::system::error_code ec; VSOMEIP_ERROR << __func__ @@ -1798,7 +1902,7 @@ service_discovery_impl::process_eventgroupentry( if (!check_ipv4_address(its_second_address) || 0 == its_second_port) { if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } boost::system::error_code ec; VSOMEIP_ERROR << __func__ @@ -1829,7 +1933,7 @@ service_discovery_impl::process_eventgroupentry( its_ipv6_option->get_address()); if (!check_layer_four_protocol(its_ipv6_option)) { if(its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } boost::system::error_code ec; VSOMEIP_ERROR << "Invalid layer 4 protocol type in IPv6 endpoint option specified! " @@ -1847,7 +1951,7 @@ service_discovery_impl::process_eventgroupentry( if (is_first_reliable == is_second_reliable && its_second_port != ILLEGAL_PORT) { if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } boost::system::error_code ec; VSOMEIP_ERROR << __func__ @@ -1867,7 +1971,7 @@ service_discovery_impl::process_eventgroupentry( if (is_second_reliable == is_first_reliable && its_first_port != ILLEGAL_PORT) { if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); } boost::system::error_code ec; VSOMEIP_ERROR << __func__ @@ -1983,7 +2087,7 @@ service_discovery_impl::process_eventgroupentry( << its_sender.to_string(ec) << " session: " << std::hex << std::setw(4) << std::setfill('0') << its_session; if (its_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, its_clients); return; } break; @@ -1997,7 +2101,7 @@ service_discovery_impl::process_eventgroupentry( its_first_address, its_first_port, is_first_reliable, its_second_address, its_second_port, is_second_reliable, _acknowledgement, _is_stop_subscribe_subscribe, - _force_initial_events, its_clients, its_info); + _force_initial_events, its_clients, _sd_ac_state, its_info); } else { if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) { //this type is used for ACK and NACK messages if (its_ttl > 0) { @@ -2025,6 +2129,7 @@ service_discovery_impl::handle_eventgroup_subscription( std::shared_ptr &_acknowledgement, bool _is_stop_subscribe_subscribe, bool _force_initial_events, const std::set &_clients, + const sd_acceptance_state_t& _sd_ac_state, const std::shared_ptr& _info) { (void)_counter; (void)_reserved; @@ -2062,7 +2167,7 @@ service_discovery_impl::handle_eventgroup_subscription( } } if (reliablility_nack && _ttl > 0) { - insert_subscription_ack(_acknowledgement, _info, 0); + insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); boost::system::error_code ec; // TODO: Add sender and session id VSOMEIP_WARNING << __func__ @@ -2103,13 +2208,13 @@ service_discovery_impl::handle_eventgroup_subscription( << (uint32_t) _info->get_major() << "] subscriber: " << _first_address.to_string(ec) << ":" << std::dec << _first_port; if (_ttl > 0) { - insert_subscription_ack(_acknowledgement, its_info, 0); + insert_subscription_ack(_acknowledgement, its_info, 0, nullptr, _clients); } return; } else { boost::asio::ip::address its_first_address, its_second_address; - uint16_t its_first_port, its_second_port; if (ILLEGAL_PORT != _first_port) { + uint16_t its_first_port(0); its_subscriber = endpoint_definition::get( _first_address, _first_port, _is_first_reliable, _service, _instance); if (!_is_first_reliable && @@ -2121,7 +2226,7 @@ service_discovery_impl::handle_eventgroup_subscription( its_reliable = its_subscriber; // check if TCP connection is established by client if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) { - insert_subscription_ack(_acknowledgement, _info, 0); + insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); boost::system::error_code ec; // TODO: Add sender and session id VSOMEIP_ERROR << "TCP connection to target1: [" @@ -2139,6 +2244,7 @@ service_discovery_impl::handle_eventgroup_subscription( } if (ILLEGAL_PORT != _second_port) { + uint16_t its_second_port(0); its_subscriber = endpoint_definition::get( _second_address, _second_port, _is_second_reliable, _service, _instance); if (!_is_second_reliable && @@ -2150,7 +2256,7 @@ service_discovery_impl::handle_eventgroup_subscription( its_reliable = its_subscriber; // check if TCP connection is established by client if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) { - insert_subscription_ack(_acknowledgement, _info, 0); + insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); boost::system::error_code ec; // TODO: Add sender and session id VSOMEIP_ERROR << "TCP connection to target2 : [" @@ -2168,6 +2274,26 @@ service_discovery_impl::handle_eventgroup_subscription( } } + // check if the subscription should be rejected because of sd_acceptance_handling + if (_ttl > 0 && _sd_ac_state.sd_acceptance_required_) { + bool insert_nack(false); + if (_first_port != ILLEGAL_PORT && !_sd_ac_state.accept_entries_ + && configuration_->is_protected_port(_first_address, + _first_port, _is_first_reliable)) { + insert_nack = true; + } + if (!insert_nack && _second_port != ILLEGAL_PORT + && !_sd_ac_state.accept_entries_ + && configuration_->is_protected_port(_second_address, + _second_port, _is_second_reliable)) { + insert_nack = true; + } + if (insert_nack) { + insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); + return; + } + } + // Create subscription object auto its_subscription = std::make_shared(); its_subscription->set_eventgroupinfo(_info); @@ -2953,9 +3079,10 @@ service_discovery_impl::last_offer_shorter_half_offer_delay_ago() { bool service_discovery_impl::check_source_address( const boost::asio::ip::address &its_source_address) const { + bool is_valid = true; // Check if source address is same as nodes unicast address - if(unicast_ == its_source_address) { + if (unicast_ == its_source_address) { VSOMEIP_ERROR << "Source address of message is same as DUT's unicast address! : " << its_source_address.to_string(); is_valid = false; @@ -2965,18 +3092,21 @@ service_discovery_impl::check_source_address( void service_discovery_impl::set_diagnosis_mode(const bool _activate) { + is_diagnosis_ = _activate; } bool service_discovery_impl::get_diagnosis_mode() { + return is_diagnosis_; } void service_discovery_impl::update_remote_subscription( const std::shared_ptr &_subscription) { - if (!_subscription->is_pending()) { + + if (!_subscription->is_pending() || 0 == _subscription->get_answers()) { std::shared_ptr its_ack; { std::lock_guard its_lock(pending_remote_subscriptions_mutex_); @@ -2995,13 +3125,15 @@ service_discovery_impl::update_remote_subscription( void service_discovery_impl::update_acknowledgement( const std::shared_ptr &_acknowledgement) { + if (_acknowledgement->is_complete() && !_acknowledgement->is_pending() && !_acknowledgement->is_done()) { + send_subscription_ack(_acknowledgement); std::lock_guard its_lock(pending_remote_subscriptions_mutex_); - for (const auto& its_subscription : _acknowledgement->get_subscriptions()) + for (const auto &its_subscription : _acknowledgement->get_subscriptions()) pending_remote_subscriptions_.erase(its_subscription); } } @@ -3241,7 +3373,9 @@ service_discovery_impl::update_remote_offer_type( service_t _service, instance_t _instance, remote_offer_type_e _offer_type, const boost::asio::ip::address &_reliable_address, - const boost::asio::ip::address &_unreliable_address) { + std::uint16_t _reliable_port, + const boost::asio::ip::address &_unreliable_address, + std::uint16_t _unreliable_port) { bool ret(false); std::lock_guard its_lock(remote_offer_types_mutex_); const std::pair its_si_pair = std::make_pair(_service, _instance); @@ -3256,13 +3390,18 @@ service_discovery_impl::update_remote_offer_type( } switch (_offer_type) { case remote_offer_type_e::UNRELIABLE: - remote_offers_by_ip_[_unreliable_address].insert(its_si_pair); + remote_offers_by_ip_[_unreliable_address][std::make_pair(false, + _unreliable_port)].insert(its_si_pair); break; case remote_offer_type_e::RELIABLE: - remote_offers_by_ip_[_reliable_address].insert(its_si_pair); + remote_offers_by_ip_[_reliable_address][std::make_pair(true, + _reliable_port)].insert(its_si_pair); break; case remote_offer_type_e::RELIABLE_UNRELIABLE: - remote_offers_by_ip_[_unreliable_address].insert(its_si_pair); + remote_offers_by_ip_[_unreliable_address][std::make_pair(false, + _unreliable_port)].insert(its_si_pair); + remote_offers_by_ip_[_unreliable_address][std::make_pair(true, + _reliable_port)].insert(its_si_pair); break; case remote_offer_type_e::UNKNOWN: default: @@ -3278,35 +3417,83 @@ service_discovery_impl::update_remote_offer_type( void service_discovery_impl::remove_remote_offer_type( service_t _service, instance_t _instance, - const boost::asio::ip::address &_address) { + const boost::asio::ip::address &_reliable_address, + std::uint16_t _reliable_port, + const boost::asio::ip::address &_unreliable_address, + std::uint16_t _unreliable_port) { std::lock_guard its_lock(remote_offer_types_mutex_); const std::pair its_si_pair = std::make_pair(_service, _instance); remote_offer_types_.erase(its_si_pair); - auto found_services = remote_offers_by_ip_.find(_address); - if (found_services != remote_offers_by_ip_.end()) { - found_services->second.erase(its_si_pair); + + auto delete_from_remote_offers_by_ip = [&]( + const boost::asio::ip::address& _address, std::uint16_t _port, + bool _reliable) { + const auto found_address = remote_offers_by_ip_.find(_address); + if (found_address != remote_offers_by_ip_.end()) { + auto found_port = found_address->second.find( + std::make_pair(_reliable, _port)); + if (found_port != found_address->second.end()) { + if (found_port->second.erase(std::make_pair(_service, _instance))) { + if (found_port->second.empty()) { + found_address->second.erase(found_port); + if (found_address->second.empty()) { + remote_offers_by_ip_.erase(found_address); + } + } + } + } + } + }; + if (_reliable_port != ILLEGAL_PORT) { + delete_from_remote_offers_by_ip(_reliable_address, _reliable_port, + true); + } + if (_unreliable_port != ILLEGAL_PORT) { + delete_from_remote_offers_by_ip(_unreliable_address, _unreliable_port, + false); } } void service_discovery_impl::remove_remote_offer_type_by_ip( const boost::asio::ip::address &_address) { + remove_remote_offer_type_by_ip(_address, ANY_PORT, false); +} + +void service_discovery_impl::remove_remote_offer_type_by_ip( + const boost::asio::ip::address &_address, std::uint16_t _port, bool _reliable) { std::lock_guard its_lock(remote_offer_types_mutex_); - auto found_services = remote_offers_by_ip_.find(_address); - if (found_services != remote_offers_by_ip_.end()) { - for (const auto& si : found_services->second) { - remote_offer_types_.erase(si); + const auto found_address = remote_offers_by_ip_.find(_address); + if (found_address != remote_offers_by_ip_.end()) { + if (_port == ANY_PORT) { + for (const auto& port : found_address->second) { + for (const auto& si : port.second) { + remote_offer_types_.erase(si); + } + } + remote_offers_by_ip_.erase(_address); + } else { + const auto its_port_reliability = std::make_pair(_reliable, _port); + const auto found_port = found_address->second.find(its_port_reliability); + if (found_port != found_address->second.end()) { + for (const auto& si : found_port->second) { + remote_offer_types_.erase(si); + } + found_address->second.erase(found_port); + if (found_address->second.empty()) { + remote_offers_by_ip_.erase(found_address); + } + } } } - remote_offers_by_ip_.erase(_address); } std::shared_ptr service_discovery_impl::create_subscription( - service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, const std::shared_ptr &_reliable, - const std::shared_ptr &_unreliable) { + const std::shared_ptr &_unreliable, + const std::shared_ptr &_info) { auto its_subscription = std::make_shared(); its_subscription->set_major(_major); its_subscription->set_ttl(_ttl); @@ -3322,10 +3509,9 @@ service_discovery_impl::create_subscription( } // check whether the eventgroup is selective - auto its_eventgroup = host_->find_eventgroup(_service, _instance, _eventgroup); - if (its_eventgroup) { - its_subscription->set_selective(its_eventgroup->is_selective()); - } + its_subscription->set_selective(_info->is_selective()); + + its_subscription->set_eventgroupinfo(_info); return its_subscription; } @@ -3333,33 +3519,70 @@ service_discovery_impl::create_subscription( void service_discovery_impl::send_subscription_ack( const std::shared_ptr &_acknowledgement) { + if (_acknowledgement->is_done()) return; _acknowledgement->done(); - std::uint32_t its_answers(1); + std::uint32_t its_max_answers(1); // Must be 1 as "_acknowledgement" not + // necessarily contains subscriptions + bool do_not_answer(false); + std::shared_ptr its_parent; // Find highest number of necessary answers for (const auto& its_subscription : _acknowledgement->get_subscriptions()) { - if (its_subscription->get_answers() > its_answers) - its_answers = its_subscription->get_answers(); + auto its_answers = its_subscription->get_answers(); + if (its_answers > its_max_answers) { + its_max_answers = its_answers; + } else if (its_answers == 0) { + do_not_answer = true; + its_parent = its_subscription->get_parent(); + } + } + + if (do_not_answer) { + if (its_parent) { + std::lock_guard its_lock(pending_remote_subscriptions_mutex_); + auto its_parent_ack = pending_remote_subscriptions_[its_parent]; + if (its_parent_ack) { + for (const auto &its_subscription : its_parent_ack->get_subscriptions()) { + if (its_subscription != its_parent) + its_subscription->set_answers(its_subscription->get_answers() + 1); + } + } + } + return; } // send messages - for (std::uint32_t i = 0; i < its_answers; i++) { - for (const auto& its_subscription : _acknowledgement->get_subscriptions()) { + for (std::uint32_t i = 0; i < its_max_answers; i++) { + for (const auto &its_subscription : _acknowledgement->get_subscriptions()) { if (i < its_subscription->get_answers()) { if (its_subscription->get_ttl() > 0) { auto its_info = its_subscription->get_eventgroupinfo(); if (its_info) { + std::set its_acked; + std::set its_nacked; for (const auto& its_client : its_subscription->get_clients()) { - auto its_ttl = (its_subscription->get_client_state(its_client) - == remote_subscription_state_e::SUBSCRIPTION_ACKED ? - its_subscription->get_ttl() : 0); + if (its_subscription->get_client_state(its_client) + == remote_subscription_state_e::SUBSCRIPTION_ACKED) { + its_acked.insert(its_client); + } else { + its_nacked.insert(its_client); + } + } - insert_subscription_ack(_acknowledgement, its_info, its_ttl, - its_subscription->get_subscriber(), its_client); + if (0 < its_acked.size()) { + insert_subscription_ack(_acknowledgement, its_info, + its_subscription->get_ttl(), + its_subscription->get_subscriber(), its_acked); + } + + if (0 < its_nacked.size()) { + insert_subscription_ack(_acknowledgement, its_info, + 0, + its_subscription->get_subscriber(), its_nacked); } } } @@ -3371,6 +3594,8 @@ service_discovery_impl::send_subscription_ack( update_subscription_expiration_timer(its_messages); } + std::this_thread::yield(); + // We might need to send initial events for (const auto &its_subscription : _acknowledgement->get_subscriptions()) { // Assumption: We do _NOT_ need to check whether this is a child @@ -3430,5 +3655,58 @@ service_discovery_impl::register_reboot_notification_handler( reboot_notification_handler_ = _handler; } +reliability_type_e service_discovery_impl::get_eventgroup_reliability( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const std::shared_ptr& _subscription) { + reliability_type_e its_reliability = reliability_type_e::RT_UNKNOWN; + auto its_info = _subscription->get_eventgroupinfo().lock(); + if (its_info) { + its_reliability = its_info->get_reliability(); + if (its_reliability == reliability_type_e::RT_UNKNOWN + && its_info->is_reliability_auto_mode()) { + // fallback: determine how service is offered + // and update reliability type of eventgroup + switch (get_remote_offer_type(_service, _instance)) { + case remote_offer_type_e::RELIABLE: + its_reliability = reliability_type_e::RT_RELIABLE; + break; + case remote_offer_type_e::UNRELIABLE: + its_reliability = reliability_type_e::RT_UNRELIABLE; + break; + case remote_offer_type_e::RELIABLE_UNRELIABLE: + its_reliability = reliability_type_e::RT_BOTH; + break; + default: + ; + } + VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't determine eventgroup reliability type for [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]" + << " using reliability type: " + << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) its_reliability; + its_info->set_reliability(its_reliability); + } + } else { + VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't lock eventgroupinfo [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "] "; + auto its_eg_info = host_->find_eventgroup(_service, _instance, _eventgroup); + if (its_eg_info) { + _subscription->set_eventgroupinfo(its_eg_info); + its_reliability = its_eg_info->get_reliability(); + } + } + + if (its_reliability == reliability_type_e::RT_UNKNOWN) { + VSOMEIP_WARNING << "sd::" << __func__ << ": eventgroup reliability type is unknown [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; + } + return its_reliability; +} + } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp index 03a55d7..8869f50 100644 --- a/implementation/service_discovery/src/subscription.cpp +++ b/implementation/service_discovery/src/subscription.cpp @@ -116,5 +116,13 @@ bool subscription::has_client(const client_t _client) const { return (clients_.find(_client) != clients_.end()); } +void subscription::set_eventgroupinfo( + const std::shared_ptr _info) { + eg_info_ = _info; +} +std::weak_ptr subscription::get_eventgroupinfo() const { + return eg_info_; +} + } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp index 4147463..7f05e95 100644 --- a/implementation/utility/src/utility.cpp +++ b/implementation/utility/src/utility.cpp @@ -75,8 +75,7 @@ bool utility::is_routing_manager(const std::shared_ptr &_config) its_lockfile.append(its_network.begin(), its_network.end()); lock_handle__ = CreateFileW(its_lockfile.c_str(), GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL); if (lock_handle__ == INVALID_HANDLE_VALUE) { - VSOMEIP_ERROR << __func__ << ": CreateFileW failed: " - << its_lockfile << " " << std::hex << GetLastError(); + VSOMEIP_ERROR << __func__ << ": CreateFileW failed: " << std::hex << GetLastError(); } } else { VSOMEIP_ERROR << __func__ << ": Could not get temp folder: " @@ -87,6 +86,12 @@ bool utility::is_routing_manager(const std::shared_ptr &_config) return (lock_handle__ != INVALID_HANDLE_VALUE); #else std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network()); +#ifdef __ANDROID__ // NDK + const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); + if (nullptr != env_base_path) { + its_base_path = {env_base_path + _config->get_network()}; + } +#endif std::string its_lockfile(its_base_path + ".lck"); int its_lock_ctrl(-1); @@ -123,7 +128,7 @@ void utility::remove_lockfile(const std::shared_ptr &_config) { its_lockfile.append(its_network.begin(), its_network.end()); if (DeleteFileW(its_lockfile.c_str()) == 0) { VSOMEIP_ERROR << __func__ << ": DeleteFileW failed: " - << its_lockfile << ": " << std::hex << GetLastError(); + << std::hex << GetLastError(); } } else { @@ -133,6 +138,12 @@ void utility::remove_lockfile(const std::shared_ptr &_config) { } #else std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network()); +#ifdef __ANDROID__ // NDK + const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); + if (nullptr != env_base_path) { + its_base_path = {env_base_path + _config->get_network()}; + } +#endif std::string its_lockfile(its_base_path + ".lck"); if (lock_fd__ != -1) { @@ -174,7 +185,17 @@ bool utility::is_folder(const std::string &_path) { const std::string utility::get_base_path( const std::shared_ptr &_config) { +#ifdef __ANDROID__ // NDK + const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); + if (nullptr != env_base_path) { + std::string its_base_path(env_base_path + _config->get_network()); + return std::string(env_base_path + _config->get_network() + "-"); + } else { + return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-"); + } +#else return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-"); +#endif } client_t diff --git a/interface/compat/vsomeip/runtime.hpp b/interface/compat/vsomeip/runtime.hpp index a3cb0d3..fda15ec 100644 --- a/interface/compat/vsomeip/runtime.hpp +++ b/interface/compat/vsomeip/runtime.hpp @@ -47,7 +47,7 @@ class payload; * contains the main public API of vsomeip. * */ -class VSOMEIP_IMPORT_EXPORT runtime { +class VSOMEIP_EXPORT runtime { public: static std::string get_property(const std::string &_name); diff --git a/interface/vsomeip/application.hpp b/interface/vsomeip/application.hpp index a67368f..366ecf1 100644 --- a/interface/vsomeip/application.hpp +++ b/interface/vsomeip/application.hpp @@ -796,7 +796,6 @@ public: * * \param _remotes remote infos for which SD acceptance handler should be * called - * \param _path Path which indicates need for offer acceptance * \param _enable enable or disable calling of offer acceptance handler */ typedef std::map sd_acceptance_map_type_t; diff --git a/interface/vsomeip/enumeration_types.hpp b/interface/vsomeip/enumeration_types.hpp index 8f31c0d..a6bc315 100644 --- a/interface/vsomeip/enumeration_types.hpp +++ b/interface/vsomeip/enumeration_types.hpp @@ -42,7 +42,7 @@ enum class return_code_e : uint8_t { E_WRONG_PROTOCOL_VERSION = 0x07, E_WRONG_INTERFACE_VERSION = 0x08, E_MALFORMED_MESSAGE = 0x09, - E_WRONG_MESSAGE_TYPE = 0xA, + E_WRONG_MESSAGE_TYPE = 0x0A, E_UNKNOWN = 0xFF }; diff --git a/interface/vsomeip/handler.hpp b/interface/vsomeip/handler.hpp index 2700567..7e2bbe9 100644 --- a/interface/vsomeip/handler.hpp +++ b/interface/vsomeip/handler.hpp @@ -65,15 +65,15 @@ struct ip_address_t { struct remote_info_t { ip_address_t ip_; - std::uint16_t port_; std::uint16_t first_; std::uint16_t last_; bool is_range_; + bool is_reliable_; bool operator<(const remote_info_t& _other) const { - return std::tie(ip_, port_, first_, last_, is_range_) < - std::tie(_other.ip_, _other.port_, _other.first_, _other.last_, - _other.is_range_); + return std::tie(ip_, first_, last_, is_range_, is_reliable_) < + std::tie(_other.ip_, _other.first_, _other.last_, + _other.is_range_, _other.is_reliable_); } }; diff --git a/interface/vsomeip/internal/logger.hpp b/interface/vsomeip/internal/logger.hpp index bbf8e65..db92b86 100644 --- a/interface/vsomeip/internal/logger.hpp +++ b/interface/vsomeip/internal/logger.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020 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/. @@ -6,46 +6,61 @@ #ifndef VSOMEIP_V3_LOGGER_HPP_ #define VSOMEIP_V3_LOGGER_HPP_ -#include - -#ifdef _WIN32 -#include -#endif +#include +#include +#include +#include +#include +#include #include -#include -#include - namespace vsomeip_v3 { +namespace logger { + +enum class VSOMEIP_IMPORT_EXPORT level_e : std::uint8_t { + LL_NONE = 0, + LL_FATAL = 1, + LL_ERROR = 2, + LL_WARNING = 3, + LL_INFO = 4, + LL_DEBUG = 5, + LL_VERBOSE = 6 +}; + +class message + : public std::ostream { -class VSOMEIP_IMPORT_EXPORT logger { public: - static std::shared_ptr get(); + VSOMEIP_IMPORT_EXPORT message(level_e _level); + VSOMEIP_IMPORT_EXPORT ~message(); - virtual ~logger() { - } +private: + class buffer : public std::streambuf { + public: + int_type overflow(int_type); + std::streamsize xsputn(const char *, std::streamsize); - virtual boost::log::sources::severity_logger_mt< - boost::log::trivial::severity_level> & get_internal() = 0; -}; + std::stringstream data_; + }; -#define VSOMEIP_LOG_DEFAULT_APPLICATION_ID "VSIP" -#define VSOMEIP_LOG_DEFAULT_APPLICATION_NAME "vSomeIP application|SysInfra|IPC" - -#define VSOMEIP_FATAL BOOST_LOG_SEV(vsomeip_v3::logger::get()->get_internal(), \ - boost::log::trivial::severity_level::fatal) -#define VSOMEIP_ERROR BOOST_LOG_SEV(vsomeip_v3::logger::get()->get_internal(), \ - boost::log::trivial::severity_level::error) -#define VSOMEIP_WARNING BOOST_LOG_SEV(vsomeip_v3::logger::get()->get_internal(), \ - boost::log::trivial::severity_level::warning) -#define VSOMEIP_INFO BOOST_LOG_SEV(vsomeip_v3::logger::get()->get_internal(), \ - boost::log::trivial::severity_level::info) -#define VSOMEIP_DEBUG BOOST_LOG_SEV(vsomeip_v3::logger::get()->get_internal(), \ - boost::log::trivial::severity_level::debug) -#define VSOMEIP_TRACE BOOST_LOG_SEV(vsomeip_v3::logger::get()->get_internal(), \ - boost::log::trivial::severity_level::trace) + std::chrono::system_clock::time_point when_; + buffer buffer_; + level_e level_; + static std::mutex mutex__; +}; +} // namespace logger } // namespace vsomeip_v3 +#define VSOMEIP_FATAL vsomeip_v3::logger::message(vsomeip_v3::logger::level_e::LL_FATAL) +#define VSOMEIP_ERROR vsomeip_v3::logger::message(vsomeip_v3::logger::level_e::LL_ERROR) +#define VSOMEIP_WARNING vsomeip_v3::logger::message(vsomeip_v3::logger::level_e::LL_WARNING) +#define VSOMEIP_INFO vsomeip_v3::logger::message(vsomeip_v3::logger::level_e::LL_INFO) +#define VSOMEIP_DEBUG vsomeip_v3::logger::message(vsomeip_v3::logger::level_e::LL_DEBUG) +#define VSOMEIP_TRACE vsomeip_v3::logger::message(vsomeip_v3::logger::level_e::LL_VERBOSE) + +#define VSOMEIP_LOG_DEFAULT_APPLICATION_ID "VSIP" +#define VSOMEIP_LOG_DEFAULT_APPLICATION_NAME "vSomeIP application|SysInfra|IPC" + #endif // VSOMEIP_V3_LOGGER_HPP_ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b3cd6a9..8250c1c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3327,39 +3327,39 @@ if(NOT ${TESTS_BAT}) # 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} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} SAME_SERVICE_ID) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} SAME_SERVICE_ID) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp @@ -3372,15 +3372,15 @@ if(NOT ${TESTS_BAT}) # subscribe notify one id tests add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) # cpu load tests @@ -3391,111 +3391,111 @@ if(NOT ${TESTS_BAT}) # initial event tests add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} SAME_SERVICE_ID) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} SAME_SERVICE_ID MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY SERVICE_OFFERED_TCP_AND_UDP) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} SAME_SERVICE_ID MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp PROPERTIES TIMEOUT 120) # offer tests diff --git a/test/big_payload_tests/big_payload_test_udp_client.json b/test/big_payload_tests/big_payload_test_udp_client.json index d499638..7015f8a 100644 --- a/test/big_payload_tests/big_payload_test_udp_client.json +++ b/test/big_payload_tests/big_payload_test_udp_client.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "netmask":"255.255.255.0", "logging": { @@ -25,7 +25,7 @@ { "service":"0x1240", "instance":"0x01", - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "unreliable": "30509", "someip-tp" : { "client-to-service" : [ "0x8421" ] diff --git a/test/big_payload_tests/big_payload_test_udp_service.json b/test/big_payload_tests/big_payload_test_udp_service.json index 886ed4b..bc90c40 100644 --- a/test/big_payload_tests/big_payload_test_udp_service.json +++ b/test/big_payload_tests/big_payload_test_udp_service.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"debug", diff --git a/test/configuration_tests/configuration-test.cpp b/test/configuration_tests/configuration-test.cpp index 558cd4e..4056664 100644 --- a/test/configuration_tests/configuration-test.cpp +++ b/test/configuration_tests/configuration-test.cpp @@ -95,6 +95,25 @@ template } } +std::string loglevel_to_string(vsomeip::logger::level_e &_level) { + switch (_level) { + case vsomeip::logger::level_e::LL_FATAL: + return "fatal"; + case vsomeip::logger::level_e::LL_ERROR: + return "error"; + case vsomeip::logger::level_e::LL_WARNING: + return "warning"; + case vsomeip::logger::level_e::LL_INFO: + return "info"; + case vsomeip::logger::level_e::LL_DEBUG: + return "debug"; + case vsomeip::logger::level_e::LL_VERBOSE: + return "verbose"; + default: + return "unknown"; + } +} + void check_file(const std::string &_config_file, const std::string &_expected_unicast_address, bool _expected_has_console, @@ -187,7 +206,7 @@ void check_file(const std::string &_config_file, bool has_file = its_configuration->has_file_log(); bool has_dlt = its_configuration->has_dlt_log(); std::string logfile = its_configuration->get_logfile(); - boost::log::trivial::severity_level loglevel + vsomeip::logger::level_e loglevel = its_configuration->get_loglevel(); bool has_version_logging = its_configuration->log_version(); std::uint32_t version_logging_interval = its_configuration->get_log_version_interval(); @@ -196,7 +215,7 @@ void check_file(const std::string &_config_file, EXPECT_TRUE(check(has_file, _expected_has_file, "HAS FILE")); EXPECT_TRUE(check(has_dlt, _expected_has_dlt, "HAS DLT")); EXPECT_TRUE(check(logfile, _expected_logfile, "LOGFILE")); - EXPECT_TRUE(check(boost::log::trivial::to_string(loglevel), + EXPECT_TRUE(check(loglevel_to_string(loglevel), _expected_loglevel, "LOGLEVEL")); EXPECT_TRUE(check(has_version_logging, _expected_version_logging_enabled, "VERSION LOGGING")); diff --git a/test/e2e_tests/e2e_test_client.cpp b/test/e2e_tests/e2e_test_client.cpp index dc04b56..260ad7e 100644 --- a/test/e2e_tests/e2e_test_client.cpp +++ b/test/e2e_tests/e2e_test_client.cpp @@ -78,10 +78,12 @@ void e2e_test_client::on_state(vsomeip::state_type_e _state) { app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8001), - its_eventgroups, vsomeip::event_type_e::ET_FIELD); + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8002), - its_eventgroups_2, vsomeip::event_type_e::ET_FIELD); + its_eventgroups_2, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); } } diff --git a/test/e2e_tests/e2e_test_service.cpp b/test/e2e_tests/e2e_test_service.cpp index 9984cbc..7165cd8 100644 --- a/test/e2e_tests/e2e_test_service.cpp +++ b/test/e2e_tests/e2e_test_service.cpp @@ -61,7 +61,7 @@ bool e2e_test_service::init() { app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8001), its_eventgroups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); // set value to field which gets filled by e2e protection with CRC on sending // after e2e protection the payload for first event should look like: @@ -78,7 +78,7 @@ bool e2e_test_service::init() { app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8002), its_eventgroups_2, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); // set value to field which gets filled by e2e protection with CRC on sending // after e2e protection the payload for first event should look like: diff --git a/test/event_tests/event_test_client.cpp b/test/event_tests/event_test_client.cpp index f415702..227de85 100644 --- a/test/event_tests/event_test_client.cpp +++ b/test/event_tests/event_test_client.cpp @@ -63,7 +63,8 @@ public: its_eventgroups.insert(service_info_.eventgroup_id); app_->request_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id, - its_eventgroups, vsomeip::event_type_e::ET_EVENT); + its_eventgroups, vsomeip::event_type_e::ET_EVENT, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); app_->register_subscription_status_handler(service_info_.service_id, service_info_.instance_id, service_info_.eventgroup_id, service_info_.event_id, diff --git a/test/event_tests/event_test_service.cpp b/test/event_tests/event_test_service.cpp index f9cf28f..74a4bbf 100644 --- a/test/event_tests/event_test_service.cpp +++ b/test/event_tests/event_test_service.cpp @@ -20,7 +20,7 @@ class event_test_service { public: - event_test_service(struct event_test::service_info _service_info) : + event_test_service(struct event_test::service_info _service_info, bool _use_tcp) : service_info_(_service_info), test_mode_(event_test::test_mode_e::UNKNOWN), app_(vsomeip::runtime::get()->create_application("event_test_service")), @@ -29,7 +29,8 @@ public: wait_until_shutdown_method_called_(true), client_subscribed_(false), notifications_to_send_(0), - offer_thread_(std::bind(&event_test_service::run, this)) { + offer_thread_(std::bind(&event_test_service::run, this)), + use_tcp_(_use_tcp) { if (!app_->init()) { ADD_FAILURE() << "Couldn't initialize application"; return; @@ -43,7 +44,8 @@ public: app_->offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); app_->register_message_handler(service_info_.service_id, service_info_.instance_id, service_info_.shutdown_method_id, std::bind(&event_test_service::on_shutdown_method_called, this, @@ -172,11 +174,14 @@ private: std::mutex mutex_; std::condition_variable condition_; std::thread offer_thread_; + bool use_tcp_; }; +static bool use_tcp = false; + TEST(someip_event_test, send_events) { - event_test_service its_sample(event_test::service); + event_test_service its_sample(event_test::service, use_tcp); } @@ -184,6 +189,13 @@ TEST(someip_event_test, send_events) int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); + + if (std::string("TCP")== std::string(argv[1])) { + use_tcp = true; + } else if (std::string("UDP")== std::string(argv[1])) { + use_tcp = false; + } + return RUN_ALL_TESTS(); } #endif diff --git a/test/event_tests/event_test_slave_starter.sh b/test/event_tests/event_test_slave_starter.sh index 964175b..c09bd79 100755 --- a/test/event_tests/event_test_slave_starter.sh +++ b/test/event_tests/event_test_slave_starter.sh @@ -25,7 +25,7 @@ fi ../examples/routingmanagerd/./routingmanagerd & PID_VSOMEIPD=$! -./event_test_service & +./event_test_service $COMMUNICATIONMODE & PID_SERVICE=$! # Wait until all clients and services are finished 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 6a2eab9..4fc3085 100644 --- a/test/initial_event_tests/initial_event_test_availability_checker.cpp +++ b/test/initial_event_tests/initial_event_test_availability_checker.cpp @@ -152,10 +152,13 @@ int main(int argc, char** argv) client_number = std::stoi(std::string(argv[1]), nullptr); - if (argc >= 3 && std::string("SAME_SERVICE_ID") == std::string(argv[2])) { - use_same_service_id = true; - } else { - use_same_service_id = false; + if (argc >= 2) { + for (int i = 2; i < argc; i++) { + if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { + use_same_service_id = true; + std::cout << "Availability checker: Using same service ID" << std::endl; + } + } } return RUN_ALL_TESTS(); } diff --git a/test/initial_event_tests/initial_event_test_client.cpp b/test/initial_event_tests/initial_event_test_client.cpp index a26e7b0..bc9d46a 100644 --- a/test/initial_event_tests/initial_event_test_client.cpp +++ b/test/initial_event_tests/initial_event_test_client.cpp @@ -35,7 +35,8 @@ public: std::array _service_infos, bool _subscribe_on_available, std::uint32_t _events_to_subscribe, bool _initial_event_strict_checking, - bool _dont_exit, bool _subscribe_only_one) : + bool _dont_exit, bool _subscribe_only_one, + vsomeip::reliability_type_e _reliability_type) : client_number_(_client_number), service_infos_(_service_infos), service_offered_tcp_and_udp_(_service_offered_tcp_and_udp), @@ -48,7 +49,8 @@ public: dont_exit_(_dont_exit), subscribe_only_one_(_subscribe_only_one), stop_thread_(&initial_event_test_client::wait_for_stop, this), - wait_for_signal_handler_registration_(true) + wait_for_signal_handler_registration_(true), + reliability_type_(_reliability_type) { if (!app_->init()) { ADD_FAILURE() << "Couldn't initialize application"; @@ -80,7 +82,8 @@ public: for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { app_->request_event(i.service_id, i.instance_id, static_cast(i.event_id + j), - its_eventgroups, vsomeip::event_type_e::ET_FIELD); + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + reliability_type_); } other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; @@ -364,9 +367,7 @@ public: } void handle_signal(int _signum) { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] Catched signal, going down (" - << std::dec <<_signum << ")"; + (void)_signum; std::lock_guard its_lock(stop_mutex_); wait_for_stop_ = false; stop_condition_.notify_one(); @@ -422,6 +423,7 @@ private: std::mutex signal_mutex_; std::condition_variable signal_condition_; std::thread signal_thread_; + vsomeip::reliability_type_e reliability_type_; }; static int client_number; @@ -432,6 +434,8 @@ static std::uint32_t subscribe_multiple_events; static bool initial_event_strict_checking; static bool dont_exit; static bool subscribe_only_one; +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; + extern "C" void signal_handler(int signum) { the_client->handle_signal(signum); @@ -445,12 +449,14 @@ TEST(someip_initial_event_test, wait_for_initial_events_of_all_services) initial_event_test::service_infos_same_service_id, subscribe_on_available, subscribe_multiple_events, initial_event_strict_checking, dont_exit, - subscribe_only_one); + subscribe_only_one, + reliability_type); } else { initial_event_test_client its_sample(client_number, service_offered_tcp_and_udp, initial_event_test::service_infos, subscribe_on_available, subscribe_multiple_events, initial_event_strict_checking, dont_exit, - subscribe_only_one); + subscribe_only_one, + reliability_type); } } @@ -494,6 +500,7 @@ int main(int argc, char** argv) subscribe_on_available = false; } else if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { use_same_service_id = true; + std::cout << "Using same service ID" << std::endl; } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) { subscribe_multiple_events = 5; } else if (std::string("STRICT_CHECKING") == std::string(argv[i])) { @@ -502,6 +509,15 @@ int main(int argc, char** argv) dont_exit = true; } else if (std::string("SUBSCRIBE_ONLY_ONE") == std::string(argv[i])) { subscribe_only_one = true; + } else if (std::string("TCP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + std::cout << "Using reliability type RT_RELIABLE" << std::endl; + } else if (std::string("UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + std::cout << "Using reliability type RT_UNRELIABLE" << std::endl; + } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + std::cout << "Using reliability type RT_BOTH" << std::endl; } } } diff --git a/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_master_udp.json b/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_master_udp.json index a5bdb5f..eedfde4 100644 --- a/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_master_udp.json +++ b/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_master_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", diff --git a/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_slave_udp.json b/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_slave_udp.json index caf4e12..4c47091 100644 --- a/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_slave_udp.json +++ b/test/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_slave_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "diagnosis" : "0x63", "logging": { diff --git a/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_master_udp.json b/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_master_udp.json index 5d15fbf..d0e4e8f 100644 --- a/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_master_udp.json +++ b/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_master_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", diff --git a/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_slave_udp.json b/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_slave_udp.json index 3c6a682..22a12c7 100644 --- a/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_slave_udp.json +++ b/test/initial_event_tests/initial_event_test_diff_client_ids_same_ports_slave_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "diagnosis" : "0x63", "logging": { 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 c78d3e8..8848f62 100755 --- a/test/initial_event_tests/initial_event_test_master_starter.sh +++ b/test/initial_event_tests/initial_event_test_master_starter.sh @@ -95,7 +95,9 @@ REMAINING_OPTIONS=${REMAINING_OPTIONS#SUBSCRIBE_ONLY_ONE} # wait until the services on the remote node were started as well +echo "WAITING FOR SERVICE AVAILABILITY" wait $PID_AVAILABILITY_CHECKER +echo "ALL SERVICES ARE AVAILABLE NOW" sleep 2 @@ -105,6 +107,7 @@ do CLIENT_PIDS+=($!) done + # Wait until all clients are finished for job in ${CLIENT_PIDS[*]} do diff --git a/test/initial_event_tests/initial_event_test_service.cpp b/test/initial_event_tests/initial_event_test_service.cpp index 3b96174..f075ed6 100644 --- a/test/initial_event_tests/initial_event_test_service.cpp +++ b/test/initial_event_tests/initial_event_test_service.cpp @@ -23,12 +23,13 @@ class initial_event_test_service { public: initial_event_test_service(struct initial_event_test::service_info _service_info, - std::uint32_t _events_to_offer) : + std::uint32_t _events_to_offer, vsomeip::reliability_type_e _reliability_type) : service_info_(_service_info), app_(vsomeip::runtime::get()->create_application()), wait_until_registered_(true), events_to_offer_(_events_to_offer), - offer_thread_(std::bind(&initial_event_test_service::run, this)) { + offer_thread_(std::bind(&initial_event_test_service::run, this)), + reliability_type_(_reliability_type) { if (!app_->init()) { ADD_FAILURE() << "Couldn't initialize application"; return; @@ -45,7 +46,7 @@ public: static_cast(service_info_.event_id + i), its_eventgroups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), false, true, nullptr, - vsomeip::reliability_type_e::RT_UNKNOWN); + reliability_type_); } // set value to field @@ -104,20 +105,24 @@ private: std::mutex mutex_; std::condition_variable condition_; std::thread offer_thread_; + vsomeip::reliability_type_e reliability_type_; }; static unsigned long service_number; static bool use_same_service_id; static std::uint32_t offer_multiple_events; +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; TEST(someip_initial_event_test, set_field_once) { if(use_same_service_id) { initial_event_test_service its_sample( - initial_event_test::service_infos_same_service_id[service_number], offer_multiple_events); + initial_event_test::service_infos_same_service_id[service_number], offer_multiple_events, + reliability_type); } else { initial_event_test_service its_sample( - initial_event_test::service_infos[service_number], offer_multiple_events); + initial_event_test::service_infos[service_number], offer_multiple_events, + reliability_type); } } @@ -143,8 +148,18 @@ int main(int argc, char** argv) for (int i = 2; i < argc; i++) { if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { use_same_service_id = true; + std::cout << "Using same service ID" << std::endl; } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) { offer_multiple_events = 5; + } else if (std::string("TCP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + std::cout << "Using reliability type RT_RELIABLE" << std::endl; + } else if (std::string("UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + std::cout << "Using reliability type RT_UNRELIABLE" << std::endl; + } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + std::cout << "Using reliability type RT_BOTH" << std::endl; } } } diff --git a/test/initial_event_tests/initial_event_test_slave_starter.sh b/test/initial_event_tests/initial_event_test_slave_starter.sh index 083119f..e240f5a 100755 --- a/test/initial_event_tests/initial_event_test_slave_starter.sh +++ b/test/initial_event_tests/initial_event_test_slave_starter.sh @@ -13,7 +13,7 @@ if [ $# -lt 1 ] then echo "Please pass a json file to this script." - echo "For example: $0 UDP initial_event_test_diff_client_ids_diff_ports_slave.json" + echo "For example: $0 initial_event_test_diff_client_ids_diff_ports_slave.json UDP" echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" echo "To ensure the first client only subscribes to one event pass SUBSCRIBE_ONLY_ONE as third/fourth parameter" exit 1 diff --git a/test/malicious_data_tests/malicious_data_test_service.cpp b/test/malicious_data_tests/malicious_data_test_service.cpp index 408ecb3..735f0f6 100644 --- a/test/malicious_data_tests/malicious_data_test_service.cpp +++ b/test/malicious_data_tests/malicious_data_test_service.cpp @@ -43,7 +43,8 @@ public: std::set its_eventgroups; its_eventgroups.insert(_service_info.eventgroup_id); app_->request_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_EVENT); + service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_UNKNOWN); app_->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, std::bind(&malicious_data_test_service::on_shutdown_method_called, this, diff --git a/test/npdu_tests/npdu_test_client_no_npdu.json b/test/npdu_tests/npdu_test_client_no_npdu.json index 6fb942f..1e20bee 100644 --- a/test/npdu_tests/npdu_test_client_no_npdu.json +++ b/test/npdu_tests/npdu_test_client_no_npdu.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"info", diff --git a/test/npdu_tests/npdu_test_client_npdu.json b/test/npdu_tests/npdu_test_client_npdu.json index 569d426..5bf34a0 100644 --- a/test/npdu_tests/npdu_test_client_npdu.json +++ b/test/npdu_tests/npdu_test_client_npdu.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"info", @@ -33,7 +33,7 @@ { "service":"0x1000", "instance":"0x0001", - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "unreliable":"30509", "reliable": { @@ -65,7 +65,7 @@ { "service":"0x2000", "instance":"0x0002", - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "unreliable":"30509", "reliable": { @@ -96,7 +96,7 @@ { "service":"0x3000", "instance":"0x0003", - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "unreliable":"30509", "reliable": { @@ -127,7 +127,7 @@ { "service":"0x4000", "instance":"0x0004", - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "unreliable":"30509", "reliable": { diff --git a/test/npdu_tests/npdu_test_service_no_npdu.json b/test/npdu_tests/npdu_test_service_no_npdu.json index 642db48..2a857be 100644 --- a/test/npdu_tests/npdu_test_service_no_npdu.json +++ b/test/npdu_tests/npdu_test_service_no_npdu.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"info", diff --git a/test/npdu_tests/npdu_test_service_npdu.json b/test/npdu_tests/npdu_test_service_npdu.json index 5dc905e..931c3e0 100644 --- a/test/npdu_tests/npdu_test_service_npdu.json +++ b/test/npdu_tests/npdu_test_service_npdu.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"info", diff --git a/test/offer_tests/offer_test_big_sd_msg_client.cpp b/test/offer_tests/offer_test_big_sd_msg_client.cpp index 3ef1f61..d379441 100644 --- a/test/offer_tests/offer_test_big_sd_msg_client.cpp +++ b/test/offer_tests/offer_test_big_sd_msg_client.cpp @@ -55,7 +55,8 @@ public: for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { app_->request_service(s,0x1,0x1,0x1); app_->request_event(s,0x1, offer_test::big_msg_event_id, - its_eventgroups, vsomeip::event_type_e::ET_EVENT); + its_eventgroups, vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_UNKNOWN); app_->subscribe(s, 0x1,offer_test::big_msg_eventgroup_id, 0x1, offer_test::big_msg_event_id); services_available_subribed_[s] = std::make_pair(false,0); diff --git a/test/offer_tests/offer_test_client.cpp b/test/offer_tests/offer_test_client.cpp index 11446fb..4a7e5eb 100644 --- a/test/offer_tests/offer_test_client.cpp +++ b/test/offer_tests/offer_test_client.cpp @@ -72,7 +72,8 @@ public: its_eventgroups.insert(service_info_.eventgroup_id); app_->request_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id, - its_eventgroups, vsomeip::event_type_e::ET_EVENT); + its_eventgroups, vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_BOTH); app_->subscribe(service_info_.service_id, service_info_.instance_id, service_info_.eventgroup_id, vsomeip::DEFAULT_MAJOR); diff --git a/test/offer_tests/offer_test_service.cpp b/test/offer_tests/offer_test_service.cpp index c56d005..87bd7e0 100644 --- a/test/offer_tests/offer_test_service.cpp +++ b/test/offer_tests/offer_test_service.cpp @@ -50,7 +50,7 @@ public: app_->offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_BOTH); inc_counter_and_notify(); diff --git a/test/pending_subscription_tests/pending_subscription_test_service.cpp b/test/pending_subscription_tests/pending_subscription_test_service.cpp index 29ce3f2..d68686c 100644 --- a/test/pending_subscription_tests/pending_subscription_test_service.cpp +++ b/test/pending_subscription_tests/pending_subscription_test_service.cpp @@ -47,7 +47,7 @@ public: service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); its_eventgroups.clear(); its_eventgroups.insert(static_cast(_service_info.eventgroup_id+1u)); @@ -56,7 +56,7 @@ public: static_cast(service_info_.event_id+1u), its_eventgroups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); app_->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, diff --git a/test/security_tests/security_test_client.cpp b/test/security_tests/security_test_client.cpp index e96d48a..2890e74 100644 --- a/test/security_tests/security_test_client.cpp +++ b/test/security_tests/security_test_client.cpp @@ -92,10 +92,12 @@ void security_test_client::on_state(vsomeip::state_type_e _state) { its_eventgroups.insert(0x01); app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8001), - its_eventgroups, vsomeip::event_type_e::ET_FIELD); + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8002), - its_eventgroups, vsomeip::event_type_e::ET_FIELD); + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x01, vsomeip::DEFAULT_MAJOR, static_cast(0x8001)); diff --git a/test/security_tests/security_test_service.cpp b/test/security_tests/security_test_service.cpp index 347a01b..3342eb9 100644 --- a/test/security_tests/security_test_service.cpp +++ b/test/security_tests/security_test_service.cpp @@ -45,13 +45,13 @@ bool security_test_service::init() { app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8001), its_eventgroups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); // also offer field 0x8002 which is not allowed to be received by client app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, static_cast(0x8002), its_eventgroups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); // set value to fields std::shared_ptr its_payload = diff --git a/test/someip_tp_tests/someip_tp_test_master.json b/test/someip_tp_tests/someip_tp_test_master.json index 9a08e77..9c03887 100644 --- a/test/someip_tp_tests/someip_tp_test_master.json +++ b/test/someip_tp_tests/someip_tp_test_master.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"info", @@ -25,7 +25,7 @@ { "service":"0x6767", "instance":"0x1", - "unicast" : "10.0.3.2", + "unicast" : "XXX.XXX.XXX.XXX", "unreliable":"40001", "someip-tp" : { "client-to-service": [ "0x6767", "0x8001" ] diff --git a/test/someip_tp_tests/someip_tp_test_master_starter.sh b/test/someip_tp_tests/someip_tp_test_master_starter.sh index 20c8c2a..984ee43 100755 --- a/test/someip_tp_tests/someip_tp_test_master_starter.sh +++ b/test/someip_tp_tests/someip_tp_test_master_starter.sh @@ -28,18 +28,18 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "Waiting for 5s" sleep 5 - 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_TARGET_DIR/vsomeip_lib/test; ./someip_tp_test_msg_sender 10.0.3.1 10.0.3.2 $TESTMODE\"" & + 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_TARGET_DIR/vsomeip_lib/test; ./someip_tp_test_msg_sender XXX.XXX.XXX.XXX XXX.XXX.XXX.XXX $TESTMODE\"" & echo "remote ssh pid: $!" elif [ ! -z "$USE_DOCKER" ]; then echo "Waiting for 5s" sleep 5 - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./someip_tp_test_msg_sender 10.0.3.1 10.0.3.2 $TESTMODE" & + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./someip_tp_test_msg_sender XXX.XXX.XXX.XXX XXX.XXX.XXX.XXX $TESTMODE" & else cat <offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); app_->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, @@ -84,7 +84,8 @@ public: app_->request_event(someip_tp_test::service_slave.service_id, someip_tp_test::service_slave.instance_id, someip_tp_test::service_slave.event_id, its_eventgroups, - vsomeip::event_type_e::ET_EVENT); + vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_UNRELIABLE); app_->register_message_handler(someip_tp_test::service_slave.service_id, someip_tp_test::service_slave.instance_id, someip_tp_test::service_slave.event_id, 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 a9adfe0..75e948e 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 @@ -10,16 +10,17 @@ # the testcase simply executes this script. This script then runs the services # and checks that all exit successfully. -if [ $# -lt 1 ] +if [ $# -lt 2 ] then - echo "Please pass a json file to this script." - echo "For example: $0 subscribe_notify_one_test_diff_client_ids_diff_ports_master.json" + echo "Please pass a json file and event reliability type to this script." + echo "For example: $0 subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json UDP" exit 1 fi # replace master with slave to be able display the correct json file to be used # with the slave script -MASTER_JSON_FILE=$1 +RELIABILITY_TYPE=$1 +MASTER_JSON_FILE=$2 CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} FAIL=0 @@ -27,30 +28,30 @@ FAIL=0 # Start the services export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_one export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_one_test_service 1 & +./subscribe_notify_one_test_service 1 $RELIABILITY_TYPE & export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_two export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_one_test_service 2 & +./subscribe_notify_one_test_service 2 $RELIABILITY_TYPE & export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_three export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_one_test_service 3 & +./subscribe_notify_one_test_service 3 $RELIABILITY_TYPE & sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting subscribe_notify_one_test_slave_starter.sh on slave LXC with parameters $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_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_one_test_slave_starter.sh $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_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_one_test_slave_starter.sh $CLIENT_JSON_FILE" & + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE" & else cat <create_application()), wait_until_registered_(true), @@ -36,7 +36,8 @@ public: wait_for_notify_(true), notify_thread_(std::bind(&subscribe_notify_one_test_service::notify_one, this)), subscription_state_handler_called_(0), - subscription_error_occured_(false) { + subscription_error_occured_(false), + reliability_type_(_reliability_type) { if (!app_->init()) { ADD_FAILURE() << "Couldn't initialize application"; return; @@ -51,7 +52,7 @@ public: app_->offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT, std::chrono::milliseconds::zero(), false, true, nullptr, - vsomeip::reliability_type_e::RT_UNKNOWN); + reliability_type_); app_->register_message_handler(service_info_.service_id, service_info_.instance_id, service_info_.method_id, @@ -94,7 +95,7 @@ public: std::set its_eventgroups; its_eventgroups.insert(i.eventgroup_id); - app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT); + app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT, reliability_type_); other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; other_services_received_notification_[std::make_pair(i.service_id, i.method_id)] = 0; @@ -455,27 +456,42 @@ private: std::atomic subscription_error_occured_; std::mutex subscribers_mutex_; + vsomeip::reliability_type_e reliability_type_; }; static unsigned long service_number; +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; + TEST(someip_subscribe_notify_one_test, send_ten_notifications_to_service) { subscribe_notify_one_test_service its_sample( - subscribe_notify_one_test::service_infos[service_number]); + subscribe_notify_one_test::service_infos[service_number], + reliability_type); } #ifndef _WIN32 int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a service number and subscription type, like: " << argv[0] << " 2 UDP" << std::endl; + if(argc < 3) { + std::cerr << "Please specify a service number and event reliability type, like: " << argv[0] << " 2 UDP" << std::endl; std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; + std::cerr << "Valid service reliability types are [UDP, TCP, TCP_AND_UDP]" << std::endl; + return 1; } service_number = std::stoul(std::string(argv[1]), nullptr); + + if (std::string("TCP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + } else if (std::string("UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + } else if (std::string("TCP_AND_UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + } + return RUN_ALL_TESTS(); } #endif diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh b/test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh index 10014ae..e41852c 100755 --- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh +++ b/test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh @@ -10,25 +10,25 @@ # the testcase simply executes this script. This script then runs the services # and checks that all exit successfully. -if [ $# -lt 1 ] +if [ $# -lt 2 ] then - echo "Please pass a json file to this script." - echo "For example: $0 subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json" + echo "Please pass a json file and event reliability type to this script." + echo "For example: $0 UDP subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json" exit 1 fi FAIL=0 # Start the services export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_four -export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_CONFIGURATION=$2 ./subscribe_notify_one_test_service 4 $1 & export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_five -export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_CONFIGURATION=$2 ./subscribe_notify_one_test_service 5 $1 & export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_six -export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_CONFIGURATION=$2 ./subscribe_notify_one_test_service 6 $1 & # Wait until all applications are finished diff --git a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json index e09d807..8413dda 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json +++ b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", diff --git a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json index 91e9ef8..bb2280c 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json +++ b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", diff --git a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json index 83e6963..d07c1e3 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json +++ b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", diff --git a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json index f379642..bda8fe0 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json +++ b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", diff --git a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json index a6dde19..649d1ba 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json +++ b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.1", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", diff --git a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json index 7e65f41..314737f 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json +++ b/test/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json @@ -1,5 +1,5 @@ { - "unicast":"10.0.3.2", + "unicast":"XXX.XXX.XXX.XXX", "logging": { "level":"warning", 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 9e009b4..f14550d 100755 --- a/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh +++ b/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh @@ -12,15 +12,17 @@ if [ $# -lt 1 ] then - echo "Please pass a json file to this script." - echo "For example: $0 subscribe_notify_test_diff_client_ids_diff_ports_master.json" + echo "Please pass a json file and event reliability type to this script." + echo "For example: $0 UDP subscribe_notify_test_diff_client_ids_diff_ports_master.json" echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" exit 1 fi # replace master with slave to be able display the correct json file to be used # with the slave script -MASTER_JSON_FILE=$1 +RELIABILITY_TYPE=$1 +MASTER_JSON_FILE=$2 +SAME_SERVICE_ID=$3 CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} FAIL=0 @@ -28,30 +30,30 @@ FAIL=0 # Start the services export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_one export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_test_service 1 $2 & +./subscribe_notify_test_service 1 $RELIABILITY_TYPE $3 & export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_two export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_test_service 2 $2 & +./subscribe_notify_test_service 2 $RELIABILITY_TYPE $3 & export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_three export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_test_service 3 $2 & +./subscribe_notify_test_service 3 $RELIABILITY_TYPE $3 & sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting subscribe_notify_test_slave_starter.sh on slave LXC with parameters $CLIENT_JSON_FILE $2" - 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_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_test_slave_starter.sh $CLIENT_JSON_FILE $2\"" & + 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_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE $3\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_slave_starter.sh $CLIENT_JSON_FILE $2" & + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE $3" & else cat <request_event(info_.service_id, info_.instance_id, info_.event_id, its_groups, - vsomeip::event_type_e::ET_FIELD); + vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); app_->request_event(info_.service_id, info_.instance_id, static_cast(info_.event_id + 2), - its_groups, vsomeip::event_type_e::ET_FIELD); + its_groups, vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); its_groups.erase(info_.eventgroup_id); its_groups.insert(static_cast(info_.eventgroup_id +1)); app_->request_event(info_.service_id, info_.instance_id, static_cast(info_.event_id+1), - its_groups, vsomeip::event_type_e::ET_FIELD); + its_groups, vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); app_->request_event(info_.service_id, info_.instance_id, static_cast(info_.event_id+2), - its_groups, vsomeip::event_type_e::ET_FIELD); + its_groups, vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); return true; } diff --git a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh index 943ef10..8da1ded 100755 --- a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh +++ b/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh @@ -20,6 +20,7 @@ fi # replace master with slave to be able display the correct json file to be used # with the slave script +RELIABILITY_TYPE=$1 MASTER_JSON_FILE=$2 if [ $1 == "UDP" ]; then SLAVE_JSON_FILE=${MASTER_JSON_FILE/master/udp_slave} @@ -41,16 +42,16 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting subscribe_notify_test_slave_starter.sh on slave LXC with parameters $SLAVE_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_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $SLAVE_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_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $RELIABILITY_TYPE $SLAVE_JSON_FILE\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $SLAVE_JSON_FILE" & + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $RELIABILITY_TYPE $SLAVE_JSON_FILE" & else cat <create_application()), wait_for_shutdown_(true), info_(_info), - notify_thread_(std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::wait_for_shutdown, this)) { + notify_thread_(std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::wait_for_shutdown, this)), + use_tcp_(_use_tcp) { } ~subscribe_notify_test_one_event_two_eventgroups_service() { @@ -70,24 +71,28 @@ public: app_->offer_event(info_.service_id, info_.instance_id, info_.event_id, its_groups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); app_->offer_event(info_.service_id, info_.instance_id, static_cast(info_.event_id + 2), its_groups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); its_groups.erase(info_.eventgroup_id); its_groups.insert(static_cast(info_.eventgroup_id + 1)); app_->offer_event(info_.service_id, info_.instance_id, static_cast(info_.event_id + 1), its_groups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); app_->offer_event(info_.service_id, info_.instance_id, static_cast(info_.event_id + 2), its_groups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); payload_ = vsomeip::runtime::get()->create_payload(); return true; @@ -186,6 +191,7 @@ private: subscribe_notify_test::service_info info_; std::thread notify_thread_; + bool use_tcp_; }; #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING @@ -197,11 +203,12 @@ private: } #endif +static bool use_tcp; TEST(someip_subscribe_notify_test_one_event_two_eventgroups, wait_for_attribute_set) { subscribe_notify_test_one_event_two_eventgroups_service its_service( - subscribe_notify_test::service_info_subscriber_based_notification); + subscribe_notify_test::service_info_subscriber_based_notification, use_tcp); #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING its_service_ptr = &its_service; signal(SIGINT, handle_signal); @@ -216,6 +223,24 @@ TEST(someip_subscribe_notify_test_one_event_two_eventgroups, wait_for_attribute_ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a offer type of the service, like: " << argv[0] << " UDP" << std::endl; + std::cerr << "Valid offer types include:" << std::endl; + std::cerr << "[UDP, TCP]" << std::endl; + return 1; + } + + if(std::string("TCP") == std::string(argv[1])) { + use_tcp = true; + } else if(std::string("UDP") == std::string(argv[1])) { + use_tcp = false; + } else { + std::cerr << "Wrong subscription type passed, exiting" << std::endl; + std::cerr << "Valid subscription types include:" << std::endl; + std::cerr << "[UDP, TCP]" << std::endl; + return 1; + } + return RUN_ALL_TESTS(); } #endif diff --git a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh index aa2784b..d9f0161 100755 --- a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh +++ b/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh @@ -10,21 +10,23 @@ # the testcase simply executes this script. This script then runs the services # and checks that all exit successfully. -if [ $# -lt 1 ]; then - echo "Please pass a json file to this script." - echo "For example: $0 subscribe_notify_test_one_event_two_eventgroups_slave.json" +if [ $# -lt 2 ]; then + echo "Please pass a json file and a subscription type to this script." + echo "Valid subscription types include:" + echo " [UDP, TCP]" + echo "For example: $0 UDP subscribe_notify_test_one_event_two_eventgroups_udp_slave.json" exit 1 fi FAIL=0 -export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_CONFIGURATION=$2 # start daemon ../examples/routingmanagerd/./routingmanagerd & PID_VSOMEIPD=$! # Start the services -./subscribe_notify_test_one_event_two_eventgroups_service & +./subscribe_notify_test_one_event_two_eventgroups_service $1 & PID_SERVICE=$! # wait until service exits successfully diff --git a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp b/test/subscribe_notify_tests/subscribe_notify_test_service.cpp index 6f13d39..c522d1a 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp +++ b/test/subscribe_notify_tests/subscribe_notify_test_service.cpp @@ -24,7 +24,8 @@ class subscribe_notify_test_service { public: subscribe_notify_test_service(struct subscribe_notify_test::service_info _service_info, - std::array _service_infos) : + std::array _service_infos, + vsomeip::reliability_type_e _reliability_type) : service_info_(_service_info), service_infos_(_service_infos), app_(vsomeip::runtime::get()->create_application()), @@ -37,7 +38,8 @@ public: wait_for_notify_(true), notify_thread_(std::bind(&subscribe_notify_test_service::notify, this)), subscription_state_handler_called_(0), - subscription_error_occured_(false) { + subscription_error_occured_(false), + reliability_type_(_reliability_type) { if (!app_->init()) { ADD_FAILURE() << "Couldn't initialize application"; return; @@ -61,7 +63,7 @@ public: app_->offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + false, true, nullptr, reliability_type_); // register availability for all other services and request their event. @@ -85,7 +87,7 @@ public: std::set its_eventgroups; its_eventgroups.insert(i.eventgroup_id); - app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_FIELD); + app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_FIELD, reliability_type_); other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; other_services_received_notification_[std::make_pair(i.service_id, i.method_id)] = 0; @@ -450,21 +452,26 @@ private: std::atomic subscription_error_occured_; std::mutex subscribers_mutex_; + vsomeip::reliability_type_e reliability_type_; }; static unsigned long service_number; static bool use_same_service_id; +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; + TEST(someip_subscribe_notify_test, send_ten_notifications_to_service) { if(use_same_service_id) { subscribe_notify_test_service its_sample( subscribe_notify_test::service_infos_same_service_id[service_number], - subscribe_notify_test::service_infos_same_service_id); + subscribe_notify_test::service_infos_same_service_id, + reliability_type); } else { subscribe_notify_test_service its_sample( subscribe_notify_test::service_infos[service_number], - subscribe_notify_test::service_infos); + subscribe_notify_test::service_infos, + reliability_type); } } @@ -473,19 +480,33 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); if(argc < 2) { - std::cerr << "Please specify a service number, like: " << argv[0] << " 2 SAME_SERVICE_ID" << std::endl; + std::cerr << "Please specify a service number and event reliability type, like: " << argv[0] << " 2 UDP SAME_SERVICE_ID" << std::endl; std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; + std::cerr << "Valid event reliability types are [UDP, TCP, TCP_AND_UDP]" << std::endl; std::cerr << "If SAME_SERVICE_ID is specified as third parameter the test is run w/ multiple instances of the same service" << std::endl; return 1; } service_number = std::stoul(std::string(argv[1]), nullptr); - if (argc >= 3 && std::string("SAME_SERVICE_ID") == std::string(argv[2])) { + if (argc >= 3) { + if (std::string("TCP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + } else if (std::string("UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + } else if (std::string("TCP_AND_UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + } + } + + if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { use_same_service_id = true; } else { use_same_service_id = false; } + + + return RUN_ALL_TESTS(); } #endif diff --git a/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh index 20362c7..dca9e71 100755 --- a/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh +++ b/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh @@ -18,20 +18,23 @@ then exit 1 fi +RELIABILITY_TYPE=$1 +SLAVE_JSON_FILE=$2 +SAME_SERVICE_ID=$3 FAIL=0 # Start the services export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_four -export VSOMEIP_CONFIGURATION=$1 -./subscribe_notify_test_service 4 $2 & +export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE +./subscribe_notify_test_service 4 $RELIABILITY_TYPE $3 & export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_five -export VSOMEIP_CONFIGURATION=$1 -./subscribe_notify_test_service 5 $2 & +export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE +./subscribe_notify_test_service 5 $RELIABILITY_TYPE $3 & export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_six -export VSOMEIP_CONFIGURATION=$1 -./subscribe_notify_test_service 6 $2 & +export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE +./subscribe_notify_test_service 6 $RELIABILITY_TYPE $3 & # Wait until all applications are finished for job in $(jobs -p) -- cgit v1.2.1