diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..039e0a9a9 --- /dev/null +++ b/.clang-format @@ -0,0 +1,76 @@ +# Copyright (C) 2016 Olivier Goffart +# +# You may use this file under the terms of the 3-clause BSD license. +# See the file LICENSE from this package for details. + +# This is the clang-format configuration style to be used by Qt, +# based on the rules from https://wiki.qt.io/Qt_Coding_Style and +# https://wiki.qt.io/Coding_Conventions + +--- +# Webkit style was loosely based on the Qt style +BasedOnStyle: WebKit + +Standard: c++17 + +# Column width is limited to 100 in accordance with Qt Coding Style. +# https://wiki.qt.io/Qt_Coding_Style +# Note that this may be changed at some point in the future. +ColumnLimit: 100 +# How much weight do extra characters after the line length limit have. +# PenaltyExcessCharacter: 4 + +# We want a space between the type and the star for pointer types. +PointerAlignment: Left + +# Align reference like PointerAlignment. +# ReferenceAlignment: Left + +# We use template< without space. +SpaceAfterTemplateKeyword: false + +# We want to break before the operators, but not before a '='. +BreakBeforeBinaryOperators: NonAssignment + +# Braces are usually attached, but not after functions or class declarations. +BreakBeforeBraces: Attach + +# When constructor initializers do not fit on one line, put them each on a new line. +# PackConstructorInitializers: CurrentLine + +# Indent initializers by 4 spaces +ConstructorInitializerIndentWidth: 4 + +# Indent width for line continuations. +ContinuationIndentWidth: 8 + +# No spaces inside the braced list. +Cpp11BracedListStyle: true + +# No indentation for namespaces. +NamespaceIndentation: None + +# Allow indentation for preprocessing directives (if/ifdef/endif). https://reviews.llvm.org/rL312125 +IndentPPDirectives: None + +# Horizontally align arguments after an open bracket. +# The coding style does not specify the following, but this is what gives +# results closest to the existing code. +AlignAfterOpenBracket: true +AlwaysBreakTemplateDeclarations: true + +# Ideally we should also allow less short function in a single line, but +# clang-format does not handle that. +AllowShortFunctionsOnASingleLine: Inline + +# The coding style specifies some include order categories, but also tells to +# separate categories with an empty line. It does not specify the order within +# the categories. Since the SortInclude feature of clang-format does not +# re-order includes separated by empty lines, the feature is not used. +SortIncludes: false + +# Break constructor initializers before the colon and after the commas. +BreakConstructorInitializers: AfterColon + +# Do not format macro definition body. +SkipMacroDefinitionBody: true diff --git a/.gitignore b/.gitignore index c219dacda..1c6a58ba8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /CMakeFiles /build*/* /examples/hello_world/build +/.idea/ /.vscode/ /.settings /.project @@ -9,169 +10,8 @@ /daemon/CMakeFiles /examples/CMakeFiles /implementation/configuration/include/internal.hpp -/test/network_tests/application_tests/application_test.json -/test/network_tests/application_tests/application_test_daemon.json -/test/network_tests/application_tests/application_test_no_dispatch_threads.json -/test/network_tests/application_tests/application_test_no_dispatch_threads_daemon.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_limited.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_queue_limited.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_random.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_limited.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_queue_limited.json -/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_random.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_client.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_service.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_client_random.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_service_random.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_client_limited_general.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_service_limited_general.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_client_queue_limited_general.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_client_queue_limited_specific.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_service_queue_limited_general.json -/test/network_tests/big_payload_tests/big_payload_test_tcp_service_queue_limited_specific.json -/test/network_tests/big_payload_tests/big_payload_test_udp_client.json -/test/network_tests/big_payload_tests/big_payload_test_udp_service.json -/test/network_tests/magic_cookies_tests/magic_cookies_test_client.json -/test/network_tests/magic_cookies_tests/magic_cookies_test_service.json -/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.json -/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.json -/test/network_tests/payload_tests/external_local_payload_test_client_external.json -/test/network_tests/payload_tests/external_local_payload_test_client_local.json -/test/network_tests/payload_tests/external_local_payload_test_service.json -/test/network_tests/routing_tests/external_local_routing_test_client_external.json -/test/network_tests/routing_tests/external_local_routing_test_service.json -/test/network_tests/routing_tests/local_routing_test_starter.sh -/test/network_tests/client_id_tests/client_id_test_diff_client_ids_diff_ports_master.json -/test/network_tests/client_id_tests/client_id_test_diff_client_ids_diff_ports_slave.json -/test/network_tests/client_id_tests/client_id_test_diff_client_ids_same_ports_master.json -/test/network_tests/client_id_tests/client_id_test_diff_client_ids_same_ports_slave.json -/test/network_tests/client_id_tests/client_id_test_diff_client_ids_partial_same_ports_master.json -/test/network_tests/client_id_tests/client_id_test_diff_client_ids_partial_same_ports_slave.json -/test/network_tests/client_id_tests/client_id_test_same_client_ids_diff_ports_master.json -/test/network_tests/client_id_tests/client_id_test_same_client_ids_diff_ports_slave.json -/test/network_tests/client_id_tests/client_id_test_same_client_ids_same_ports_master.json -/test/network_tests/client_id_tests/client_id_test_same_client_ids_same_ports_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_diff_ports_master.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_diff_ports_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_same_ports_master.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_same_ports_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json -/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json -/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json -/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json -/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json -/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json -/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_master_udp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_partial_same_ports_master_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_partial_same_ports_slave_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_tcp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_master_udp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_same_ports_slave_udp_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_tcp_slave_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_udp_slave_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_diff_ports_master_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_diff_ports_slave_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_same_ports_master_local_tcp.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_same_client_ids_same_ports_slave_local_tcp.json -/test/network_tests/cpu_load_tests/cpu_load_test_client_slave.json -/test/network_tests/cpu_load_tests/cpu_load_test_client_master.json -/test/network_tests/cpu_load_tests/cpu_load_test_service_slave.json -/test/network_tests/cpu_load_tests/cpu_load_test_service_master.json +/test/unit_tests/security_policy_manager_impl_tests/policy_manager_impl_unit_test_macro.hpp /tools/CMakeFiles -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_master.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_slave.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_partial_same_ports_master.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_partial_same_ports_slave.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_same_ports_master.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_same_ports_slave.json -/test/network_tests/initial_event_tests/initial_event_test_same_client_ids_diff_ports_master.json -/test/network_tests/initial_event_tests/initial_event_test_same_client_ids_diff_ports_slave.json -/test/network_tests/initial_event_tests/initial_event_test_same_client_ids_same_ports_master.json -/test/network_tests/initial_event_tests/initial_event_test_same_client_ids_same_ports_slave.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_master_tcp.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_same_ports_master_tcp.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_same_ports_slave_tcp.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_master_udp.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_diff_ports_slave_udp.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_same_ports_master_udp.json -/test/network_tests/initial_event_tests/initial_event_test_diff_client_ids_same_ports_slave_udp.json -/test/network_tests/offer_tests/offer_test_external_master.json -/test/network_tests/offer_tests/offer_test_external_slave.json -/test/network_tests/offer_tests/offer_test_external_master_starter.sh -/test/network_tests/offer_tests/offer_test_big_sd_msg_master_starter.sh -/test/network_tests/offer_tests/offer_test_big_sd_msg_master.json -/test/network_tests/offer_tests/offer_test_big_sd_msg_slave.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json -/test/network_tests/subscribe_notify_tests/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json -/test/network_tests/security_tests/security_test_config_client_external_allow.json -/test/network_tests/security_tests/security_test_config_client_external_deny.json -/test/network_tests/security_tests/security_test_config_service_external_allow.json -/test/network_tests/security_tests/security_test_config_service_external_deny.json -/test/network_tests/security_tests/security_test_local_config.json -/test/network_tests/pending_subscription_tests/pending_subscription_test_master.json -/test/network_tests/pending_subscription_tests/pending_subscription_test_master_starter.sh -/test/network_tests/malicious_data_tests/malicious_data_test_master.json -/test/network_tests/malicious_data_tests/malicious_data_test_master_starter.sh -/test/network_tests/e2e_tests/e2e_profile_04_test_client_external.json -/test/network_tests/e2e_tests/e2e_profile_04_test_service_external.json -/test/network_tests/e2e_tests/e2e_test_client_external.json -/test/network_tests/e2e_tests/e2e_test_service_external.json -/test/network_tests/event_tests/event_test_master.json -/test/network_tests/event_tests/event_test_slave_tcp.json -/test/network_tests/event_tests/event_test_slave_udp.json -/test/network_tests/npdu_tests/npdu_test_client_no_npdu.json -/test/network_tests/npdu_tests/npdu_test_client_npdu.json -/test/network_tests/npdu_tests/npdu_test_service_no_npdu.json -/test/network_tests/npdu_tests/npdu_test_service_npdu.json -/test/network_tests/someip_tp_tests/someip_tp_test_master.json -/test/network_tests/someip_tp_tests/someip_tp_test_master_starter.sh -/test/network_tests/second_address_tests/second_address_test_master_service_udp.json -/test/network_tests/second_address_tests/second_address_test_master_client.json -/test/network_tests/second_address_tests/second_address_test_slave_client.json -/test/network_tests/second_address_tests/second_address_test_slave_service_udp.json -/test/network_tests/second_address_tests/second_address_test_slave_starter.sh -/test/network_tests/debounce_tests/debounce_test_client.json -/test/network_tests/debounce_tests/debounce_test_service.json -/test/network_tests/debounce_filter_tests/debounce_filter_test_client.json -/test/network_tests/debounce_filter_tests/debounce_filter_test_service.json -/test/network_tests/suspend_resume_tests/suspend_resume_test_client.json -/test/network_tests/suspend_resume_tests/suspend_resume_test_service.json /Testing +/logs !build_qnx/* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..cf102622c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +fail_fast: false +repos: + - repo: https://github.com/pocc/pre-commit-hooks + rev: v1.3.5 + hooks: + - id: clang-format + args: [-i] diff --git a/.tests-whitelist b/.tests-whitelist new file mode 100644 index 000000000..29d4805c5 --- /dev/null +++ b/.tests-whitelist @@ -0,0 +1,39 @@ +# This file contains a list of test identifiers that are known to be flaky or non-critical. +# Tests listed here are allowed to fail without causing the overall test job to fail. + +# client_id_tests +client_id_test_utility +client_id_test_utility_masked_511 +client_id_test_utility_masked_4095 +client_id_test_utility_masked_127 +client_id_test_utility_discontinuous_masked_511 + +# initial_event_tests +initial_event_test_diff_client_ids_diff_ports_udp +initial_event_test_diff_client_ids_diff_ports_tcp +initial_event_test_diff_client_ids_diff_ports_both_tcp_and_udp +initial_event_test_diff_client_ids_same_ports_udp +initial_event_test_diff_client_ids_same_ports_tcp +initial_event_test_diff_client_ids_same_ports_both_tcp_and_udp +initial_event_test_diff_client_ids_partial_same_ports_both_tcp_and_udp +initial_event_test_diff_client_ids_diff_ports_same_service_id_udp +initial_event_test_multiple_events_diff_client_ids_diff_ports_udp +initial_event_test_multiple_events_diff_client_ids_diff_ports_tcp +initial_event_test_multiple_events_diff_client_ids_diff_ports_udp_and_tcp +initial_event_test_multiple_events_diff_client_ids_same_ports_udp +initial_event_test_multiple_events_diff_client_ids_same_ports_tcp +initial_event_test_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp +initial_event_test_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp +initial_event_test_multiple_events_diff_client_ids_diff_ports_same_service_id_udp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp_and_tcp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp +initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp +initial_event_test_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp +initial_event_test_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp +initial_event_test_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp_and_tcp +initial_event_test_diff_client_ids_diff_ports_client_subscribes_twice diff --git a/Android.bp b/Android.bp index f314f22b1..03fec1520 100644 --- a/Android.bp +++ b/Android.bp @@ -62,8 +62,7 @@ cc_defaults { ], local_include_dirs: [ - "interface", - "implementation/helper" + "interface" ] } @@ -80,8 +79,8 @@ cc_library_shared { cflags: [ "-DWITHOUT_SYSTEMD", - "-DVSOMEIP_VERSION=\"3.4.10\"", - "-DVSOMEIP_COMPAT_VERSION=\"3.4.10\"", + "-DVSOMEIP_VERSION=\"3.5.1\"", + "-DVSOMEIP_COMPAT_VERSION=\"3.5.1\"", "-DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\"", "-DUSE_DLT", ], diff --git a/Android.mk b/Android.mk index 67530094e..a7ccbc577 100644 --- a/Android.mk +++ b/Android.mk @@ -96,11 +96,11 @@ LOCAL_SHARED_LIBRARIES := \ libboost_filesystem \ LOCAL_CFLAGS := \ - -std=c++14 \ + -std=c++17 \ -frtti \ -fexceptions \ -DWITHOUT_SYSTEMD \ - -DVSOMEIP_VERSION=\"3.4.10\" \ + -DVSOMEIP_VERSION=\"3.5.1\" \ -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ -Wno-unused-parameter \ -Wno-non-virtual-dtor \ @@ -143,11 +143,11 @@ LOCAL_SHARED_LIBRARIES := \ libvsomeip3_dlt \ LOCAL_CFLAGS := \ - -std=c++14 \ + -std=c++17 \ -frtti \ -fexceptions \ -DWITHOUT_SYSTEMD \ - -DVSOMEIP_VERSION=\"3.4.10\" \ + -DVSOMEIP_VERSION=\"3.5.1\" \ -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ -Wno-unused-parameter \ -Wno-non-virtual-dtor \ @@ -194,8 +194,8 @@ LOCAL_CFLAGS := \ -frtti \ -fexceptions \ -DWITHOUT_SYSTEMD \ - -DVSOMEIP_VERSION=\"3.4.10\" \ - -DVSOMEIP_COMPAT_VERSION=\"3.4.10\" \ + -DVSOMEIP_VERSION=\"3.5.1\" \ + -DVSOMEIP_COMPAT_VERSION=\"3.5.1\" \ -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ -Wno-unused-parameter \ -Wno-non-virtual-dtor \ diff --git a/CHANGES b/CHANGES index f4e7081aa..ca972564b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,125 @@ Changes ======= +v3.5.1 +- Restructure Network Tests CMakeLists +- policy.cpp unit test +- Remove deprecated usage of byteorder and use bithelper +- unblock endpoint when closing it +- Find_Debounce_Time made configurable +- Check if configuration_ pointer exists before using +- Initialize routing_state_ +- Solved data race in configuration_impl class +- utility.cpp unit tests +- unit tests payload_impl +- unit tests serializer +- unit tests deserializer +- Unit Tests for policy_manager_impl.cpp +- Unit Test - Routing Manager set_routing_state +- Move documentation to markdown +- clang-format to verify the code vsomeip-lib +- fix deadlock with event and message debounce feature +- disabled some groups of tests +- Try to force connection reset on suspend +- Call availability handler on request service instance +- Handle endpoint queue size underflow +- Add Valgrind massif tool +- Create new train after scheduling to avoid duplicate messages +- Re-Added offer_tests group in all sanitizers tests +- removed extra DLT logs of the policies print +- COVESA-615: vsomeip.lck file not removed upon application termination +- COVESA-527: Locally switch off -Wstringop-overflow +- Create network regression test for specific issue +- Change IndentPPDirectives rule in clang-format +- applied auto in some identified lines by sonarqube +- Add Valgrind memcheck +- Ensure buffer is valid before de-referencing pointer +- Renaming folder test and fixing typos +- Fix minor formatting issues from some commits +- Adds interger overflow check +- Adds application name on cout logs +- Adding helgrind, to test output +- Boost 1.65 cleanup +- network_test - Offer Stop Offer test +- Support host name (env) for internal TCP communication +- Remove cached configuration after app stops +- Optimize tests/network-tests/CMakeLists.txt +- Check if pointer exists before dereferencing it +- avoid requiring valgrind locally +- Fix Lock-Order-Inversion in policy_manager_impl +- Revert "Fix to not ignore stop offers when sd acceptance is not required" +- Fix timeout on offer_stop_offer test +- Restore config_plugin_impl mutex +- Rework [STOP_]OFFER command handling +- some-tp memory consumption increasing fast +- Remove dlt traces from memory_test +- restart_routing_test enabled +- Fix cyclic events +- Tracing LOI +- improve connection log on error path +- added subscribe_notify groups to non-leak verification +- Relocate hostname config command +- allow subscribeACK if at least one offer was sent by SD +- Improve "end of file" error handling +- Update Clang-Format to Version 18 +- Debounce tests fix +- Wireshark dissector for vsomeip protocol +- Remove logging on operation cancel in connect_cbk +- Add additional info on failure to open TCP port +- Implementation of SOMEIPSD_00577 +- Refactor how niceness values are applied to threads +- prevent race between event expiration/forwarding +- Fix subscribe_notify_one tests +- Fix missing/blocked subscription requests +- change references to C++14 into C++17 +- Explicitly check whether an endpoint is in use +- Enabled all network tests with whitelist +- Fix target client id in local_send +- remove redundants package import definitions +- run unit tests on windows +- Fix debounce network tests +- type upgrade and temporary disable of test for QNX build +- Force abort hanging detached threads +- Application tests fix +- Remove behavior from catch block in ~message +- Stop/Start (network) endpoints on suspend/resume +- Reduce the number of copy operations on event payloads +- Sets linger to 0 in local tcp clients +- Prevent exception re-throw in ~message +- remove linger on local_tcp +- Fix android traces build +- Introduce stateful availability handler +- Update the availability state +- Reintroduces the TIME_WAIT for ltcei +- Faster handlers lookup +- Increase app registration timeout +- Force endpoint restart if re registering +- fix semaphore logs +- fix compile issue with pthreads in android +- Disabling set routing state unit test +- Fixing get_policy_manager error with security disabled + +v3.5.0 +- Load Policies Lazy Load +- Test - Processing SD messages with unknown type option +- ensure endpoints before deletion +- Improve "end of file" error handling +- Enable debouncing of events & selective events +- Revert "Test - Processing SD messages with unknown type" +- Logs added to points of failure on registration process +- One *.json to ignorem all +- Someip-tp remote address rework +- Fix crash in multicast_receive receive_cb +- Generate network_test configs directly to build +- Fix deadlock if binding of TCP client endpoint fails +- Added missing includes of iomanip to support compilation on Mint +- Cache not yet registered events +- Return true to make sure endpoints are deleted +- Byteorder implementation +- Reorder of prepare_stop method +- Allows applications in the same process using different security configurations +- Fix to not ignore stop offers when sd acceptance is not required + v3.4.10 - Fix QNX build - Fix missing Stop Offer diff --git a/CMakeLists.txt b/CMakeLists.txt index 3501e02c5..7eabb3a81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ set (VSOMEIP_NAME vsomeip3) set (VSOMEIP_COMPAT_NAME vsomeip) set (VSOMEIP_MAJOR_VERSION 3) -set (VSOMEIP_MINOR_VERSION 4) -set (VSOMEIP_PATCH_VERSION 10) +set (VSOMEIP_MINOR_VERSION 5) +set (VSOMEIP_PATCH_VERSION 1) set (VSOMEIP_HOTFIX_VERSION 0) set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION}) @@ -109,9 +109,13 @@ if (ENABLE_SIGNAL_HANDLING) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_SIGNAL_HANDLING") endif () +# Event caching +if (ENABLE_DEFAULT_EVENT_CACHING) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_DEFAULT_EVENT_CACHING") +endif () + if (NOT MSVC) # Sanitizers - if (ENABLE_UNDEFINED_SANITIZER) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") endif () @@ -131,6 +135,26 @@ if (NOT MSVC) if (ENABLE_PROFILING) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") endif () + + # Valgrind + find_program(VALGRIND "valgrind") + if (VALGRIND) + if (DEFINED VALGRIND_TYPE AND NOT VALGRIND_TYPE STREQUAL "") + set(TEST_ENTRYPOINT ${VALGRIND} --tool=${VALGRIND_TYPE}) + endif () + + if (VALGRIND_TYPE STREQUAL "helgrind") + set(TEST_ENTRYPOINT ${TEST_ENTRYPOINT} --suppressions=${VALGRIND_SUPPRESS_FILE} --gen-suppressions=all --log-file=${VALGRIND_LOGS_DIR}/test_name.out) + endif () + + if (VALGRIND_TYPE STREQUAL "massif") + set(TEST_ENTRYPOINT ${TEST_ENTRYPOINT} --massif-out-file=${VALGRIND_LOGS_DIR}/test_name.out) + endif () + + if (VALGRIND_TYPE STREQUAL "memcheck") + set(TEST_ENTRYPOINT ${TEST_ENTRYPOINT} --leak-check=yes --suppressions=${VALGRIND_SUPPRESS_FILE} --log-file=${VALGRIND_LOGS_DIR}/test_name.out) + endif () + endif () endif (NOT MSVC) # Compatibility @@ -163,7 +187,7 @@ add_definitions(-DVSOMEIP_INTERNAL_SUPPRESS_DEPRECATED) find_package(Threads REQUIRED) # Boost -find_package( Boost 1.55 COMPONENTS system thread filesystem REQUIRED ) +find_package( Boost 1.66 COMPONENTS system thread filesystem REQUIRED ) if(${CMAKE_SYSTEM_NAME} MATCHES "QNX") include_directories(${Boost_INCLUDE_DIR} ) else() @@ -192,12 +216,6 @@ endif() message( STATUS "Using boost version: ${VSOMEIP_BOOST_VERSION}" ) -if (${VSOMEIP_BOOST_VERSION} LESS 106600) -include_directories(SYSTEM - implementation/helper -) -endif () - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_BOOST_VERSION=${VSOMEIP_BOOST_VERSION}") find_package(PkgConfig) @@ -250,9 +268,10 @@ if (MSVC) # 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)") # Disable warning C4250 since it warns that the compiler is correctly following the C++ Standard. It's a "We-Are-Doing-Things-By-The-Book" notice, not a real warning. - 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 /wd4250") + 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 -D_WIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc /wd4250") set(USE_RT "") link_directories(${Boost_LIBRARY_DIR_DEBUG}) + add_compile_options(/MD$<$:d>) elseif(${CMAKE_SYSTEM_NAME} MATCHES "QNX") set(USE_RT "") else() @@ -308,6 +327,7 @@ set_target_properties (${VSOMEIP_NAME} PROPERTIES VERSION ${VSOMEIP_VERSION} SOV target_compile_features(${VSOMEIP_NAME} PRIVATE cxx_std_17) if (MSVC) set_target_properties(${VSOMEIP_NAME} PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION") + set_target_properties(${VSOMEIP_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) else () set_target_properties(${VSOMEIP_NAME} PROPERTIES LINK_FLAGS "-Wl,-wrap,socket -Wl,-wrap,accept -Wl,-wrap,open") endif () @@ -362,7 +382,11 @@ endif () target_link_libraries(${VSOMEIP_NAME}-e2e ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES}) if(${CMAKE_SYSTEM_NAME} MATCHES "QNX") + target_link_directories(${VSOMEIP_NAME} PUBLIC "${QNX_TARGET}/${CPUVARDIR}/io-sock/lib") target_link_libraries(${VSOMEIP_NAME}-e2e socket) + target_link_libraries(${VSOMEIP_NAME}-cfg socket) + target_link_libraries(${VSOMEIP_NAME}-sd socket) + target_link_libraries(${VSOMEIP_NAME} PRIVATE socket) endif() ################################################################################ # Compatibility library @@ -622,24 +646,6 @@ else() add_dependencies(doc doxygen-doc) endif() -find_program(ASCIIDOC_PATH asciidoc) -find_program(SOURCE_HIGHLIGHT_PATH source-highlight) -if ("${ASCIIDOC_PATH}" STREQUAL "ASCIIDOC_PATH-NOTFOUND") - message(WARNING "asciidoc is not installed. Readme can not be built.") -elseif("${SOURCE_HIGHLIGHT_PATH}" STREQUAL "SOURCE_HIGHLIGHT_PATH-NOTFOUND") - message(WARNING "source-highlight is not installed. Readme can not be built.") -else() - message("asciidoc found") - message("source-highlight found") - add_custom_command(TARGET doc - POST_BUILD - COMMAND asciidoc - -a version=${VSOMEIP_VERSION} - -b html - -o documentation/vsomeipUserGuide.html - ${PROJECT_SOURCE_DIR}/documentation/vsomeipUserGuide) -endif() - ############################################################################## # create pkg-config file if(NOT WIN32) @@ -655,7 +661,7 @@ endif() # build tools add_custom_target( tools ) -add_subdirectory( tools ) +add_subdirectory( tools/vsomeip_ctrl ) # build examples add_custom_target( examples ) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 000000000..f2056bf01 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,74 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 13 + }, + "configurePresets": [ + { + "name": "ci-network-tests", + "displayName": "Network tests (CI)", + "description": "Preset for network tests on CI", + "generator": "Ninja", + "binaryDir": "/home/build", + "cacheVariables": { + "CMAKE_CXX_FLAGS_INIT": { + "type": "STRING", + "value": "--coverage -Wno-error=tsan" + }, + "TEST_IP_SLAVE_SECOND": { + "type": "STRING", + "value": "$penv{IP_SLAVE_2ND}" + }, + "TEST_GID": { + "type": "STRING", + "value": "0" + }, + "TEST_UID": { + "type": "STRING", + "value": "0" + } + }, + "environment": { + "GTEST_ROOT": "/usr/src/googletest" + } + } + ], + "buildPresets": [ + { + "name": "ci-network-tests", + "displayName": "Network tests (CI)", + "description": "Preset for network tests on CI", + "configurePreset": "ci-network-tests", + "targets": "build_network_tests" + } + ], + "testPresets": [ + { + "name": "ci-network-tests", + "displayName": "Network tests (CI)", + "description": "Preset for network tests on CI", + "environment": { + "LD_LIBRARY_PATH": "/home/build", + "LXC_TEST_MASTER_IP": "master", + "LXC_TEST_SLAVE_IP": "slave", + "TSAN_OPTIONS": "suppressions=${sourceDir}/test/tsan-suppressions.txt", + "USE_LXC_TEST": "1" + }, + "configurePreset": "ci-network-tests", + "output": { + "maxFailedTestOutputSize": 1e6, + "maxPassedTestOutputSize": 1e6, + "outputOnFailure": true + }, + "execution": { + "timeout": 150 + }, + "filter": { + "exclude": { + "name": "^unit_" + } + } + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..d0a1b6acc --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,203 @@ +# Contributing to vsomeip-lib + +All types of contributions are encouraged and valued. + +## Did you find a bug? + +- **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/COVESA/vsomeip/issues). + +- If you cannot find an existing open issue addressing the problem, feel free to create a new one [here](https://github.com/COVESA/vsomeip/issues/new). Make sure to provide a descriptive **title, a clear explanation of the issue, relevant information**, and if possible, include a code sample or a test case demonstrating the expected behavior that is not occurring. + +## Styleguides + +We prioritize consistency and maintainability in our code bases. To achieve this, we have established comprehensive coding standards encompassing general style guidelines and specific configurations for Clang-Format integration. + +Explore the [Table of Contents](#table-of-contents) to discover various paths for assistance and comprehensive insights into our coding standards. + +### Table of Contents + +- [General Guidelines](#general-guidelines) + +- [Naming Conventions](#naming-conventions) + +- [Clang Format Integration](#clang-format-integration) + + - [Based Style](#based-style) + + - [Standard](#standard) + + - [Clang-Format Customization](#clang-format-customization) + + - [How to use Clang Format](#how-to-use-clang-format) + + - [Workflow Summary](#workflow-summary) + +- [Showcase of good and bad practice](#showcase-of-good-and-bad-practice) + +### General Guidelines + +Before submitting a pull request, please ensure that you adhere to the following coding guidelines. + +### Naming Conventions + +Maintaining a consistent naming convention enhances code readability and comprehension. Our naming conventions dictate the following: + - **Arguments:** Argument names should start with an underscore. + + - **Members:** Member variables should end with an underscore. + + - **Local Variables:** Local variables neither start nor end with an underscore. + + - **Static Variables:** Static variables should end with two underscores. + +### Clang Format Integration + +Incorporating Clang Format into our projects is integral to ensuring uniform and readable code formatting. Clang Format is a powerful tool that automatically formats C, C++, and Objective-C code based on predefined style guidelines. + +#### Based Style + +```yaml +BasedOnStyle: WebKit +``` +Our code style is based on the WebKit style, which is in turn influenced by the Qt style. + +Webkit style guidelines can be found here [Webkit.org](https://www.webkit.org/code-style-guidelines/) + +#### Standard + +```yaml +Standard: c++17 +``` +The C++ standard to be used, in this case, C++17. + +Below is the configuration option used in our Clang Format setup: + +#### Clang-Format Customization + +```yaml +BasedOnStyle: WebKit +Standard: c++17 +ColumnLimit: 100 +PointerAlignment: Left +SpaceAfterTemplateKeyword: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Attach +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: true +NamespaceIndentation: None +IndentPPDirectives: AfterHash +AlignAfterOpenBracket: true +AlwaysBreakTemplateDeclarations: true +AllowShortFunctionsOnASingleLine: Inline +SortIncludes: false +BreakConstructorInitializers: AfterColon +``` + +#### How to use Clang Format + +Formatting your code using Clang Format is seamlessly integrated into the development workflow through [pre-commit-hooks](https://github.com/pocc/pre-commit-hooks). Follow these steps to set it up: + +#### Step 1: Install `pre-commit` + +``` +pip install pre-commit +``` + +#### Step 2: Navigate to the project's root directory + +``` +cd vsomeip-lib +``` + +#### Step 3: Install the pre-commit hook + +``` +pre-commit install +``` + +Now, every time you commit staged changes, Clang Format will automatically be invoked to format your code. This is achieved through the pre-commit hook. + +#### Workflow Summary + +1. **Make your code changes** + - Implement the desired changes in your code. + +2. **Stage the changes using `git add`** + - Use `git add` to stage the modifications you want to commit. + +3. **Commit changes with `git commit`** + - When you run `git commit`, Clang Format will automatically be applied to the staged changes before the commit is finalized. + +This seamless integration ensures consistent code formatting as part of the development workflow. Developers can focus on writing code, and the pre-commit hook takes care of formatting during the commit process. + +### Showcase of good and bad practice + +This code snippet was taken from `vsomeip-lib/implementation/routing/src/routing_manager_impl.cpp `. + +#### Good Practice + +```c++ +void routing_manager_impl::init() { + routing_manager_base::init(ep_mgr_impl_); + if (configuration_->is_routing_enabled()) { + stub_ = std::make_shared(this, configuration_); + stub_->init(); + } else { + // Good Practice: Proper indentation and spacing. + VSOMEIP_INFO << "Internal message routing disabled!"; + } + // Good Practice: Proper spacing and indentation. + if (configuration_->is_sd_enabled()) { + // Good Practice: Proper spacing and alignment. + VSOMEIP_INFO << "Service Discovery enabled. Trying to load module."; + auto its_plugin = plugin_manager::get()->get_plugin( + plugin_type_e::SD_RUNTIME_PLUGIN, VSOMEIP_SD_LIBRARY); + if (its_plugin) { + // Good Practice: Braces attached to the preceding line, consistent spacing. + VSOMEIP_INFO << "Service Discovery module loaded."; + discovery_ = std::dynamic_pointer_cast(its_plugin) + ->create_service_discovery(this, configuration_); + discovery_->init(); + } else { + // Good Practice: Proper indentation and spacing. + VSOMEIP_ERROR << "Service Discovery module could not be loaded!"; + std::exit(EXIT_FAILURE); + } + } +} +``` + +#### Bad Practice + +```c++ +void routing_manager_impl::init() +{ + routing_manager_base::init(ep_mgr_impl_); + // Bad Practice: Inconsistent indentation and brace placement. + if (configuration_-> is_routing_enabled()) + { + stub_ = std::make_shared(this, configuration_); + stub_->init(); + } + else + { + // Bad Practice: Inconsistent indentation and lack of space after binary operators. + VSOMEIP_INFO + << "Internal message routing disabled!"; + } + // Bad Practice: Lack of proper spacing and alignment. + if (configuration_->is_sd_enabled()) + { + // Bad Practice: Inconsistent indentation and spacing. + VSOMEIP_INFO << "Service Discovery enabled. Trying to load module."; + auto its_plugin = plugin_manager::get()->get_plugin( + plugin_type_e::SD_RUNTIME_PLUGIN, VSOMEIP_SD_LIBRARY); if (its_plugin) {VSOMEIP_INFO + << "Service Discovery module loaded."; + discovery_ = std::dynamic_pointer_cast(its_plugin)->create_service_discovery(this, configuration_);discovery_->init(); + } + else {VSOMEIP_ERROR + << "Service Discovery module could not be loaded!"; + std::exit(EXIT_FAILURE);} + } +} +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..0f131fc08 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM ubuntu:jammy +SHELL ["/bin/bash", "-xec"] +RUN export DEBIAN_FRONTEND=noninteractive;\ + apt-get update;\ + apt-get dist-upgrade --no-install-recommends --purge --yes\ + clang-12\ + cmake\ + g++\ + googletest\ + libbenchmark-dev\ + libboost-{{file,}system,thread}-dev\ + make\ + python3-pip\ + ;\ + apt-get autoremove --purge --yes;\ + apt-get clean;\ + pip3 install gcovr;\ + ln -s /usr/bin/clang-12 /usr/bin/clang;\ + ln -s /usr/bin/clang++-12 /usr/bin/clang++;\ + ln -s /usr/bin/lld-12 /usr/bin/lld;\ + ln -s /usr/bin/clang-tidy-12 /usr/bin/clang-tidy + +ENV GTEST_ROOT=/usr/src/googletest + +WORKDIR /home/source +VOLUME ["/home/source"] diff --git a/LICENSE_boost b/LICENSE_boost deleted file mode 100644 index eff5f980f..000000000 --- a/LICENSE_boost +++ /dev/null @@ -1,25 +0,0 @@ -This license applies to all files in directory implementation/helper/boost: - -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 70be2290d..908c9d6f4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -### vsomeip +### vSomeIP ##### Copyright -Copyright (C) 2015-2022, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +Copyright (C) 2015-2024, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) ##### License @@ -9,9 +9,13 @@ 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/. +##### Contributing Guidelines + +For comprehensive details on how to contribute effectively to the project, please refer to our [CONTRIBUTING.md](./CONTRIBUTING.md) file. + ##### vsomeip Overview ---------------- -The vsomeip stack implements the http://some-ip.com/ (Scalable service-Oriented +The vSomeIP stack implements the http://some-ip.com/ (Scalable service-Oriented MiddlewarE over IP (SOME/IP)) protocol. The stack consists out of: * a shared library for SOME/IP (`libvsomeip3.so`) @@ -27,15 +31,15 @@ Optional: ###### Dependencies -- A C++14 enabled compiler is needed (default for gcc >= v6.1). -- vsomeip uses CMake as buildsystem. -- vsomeip uses Boost >= 1.55.0: +- A C++17 enabled compiler is needed. +- vSomeIP uses CMake as buildsystem. +- vSomeIP uses Boost >= 1.66.0: For the tests Google's test framework https://code.google.com/p/googletest/[gtest] is needed. -- URL: https://googletest.googlecode.com/files/gtest-.zip -To build the documentation asciidoc, source-highlight, doxygen and graphviz is needed: ---`sudo apt-get install asciidoc source-highlight doxygen graphviz` +To build the documentation doxygen and graphviz are needed: +--`sudo apt-get install doxygen graphviz` ###### Compilation @@ -83,27 +87,27 @@ The default configuration file is /etc/vsomeip.json. ###### Compilation with signal handling -To compile vsomeip with signal handling (SIGINT/SIGTERM) enabled, call cmake like: +To compile vSomeIP with signal handling (SIGINT/SIGTERM) enabled, call cmake like: ```bash cmake -DENABLE_SIGNAL_HANDLING=1 .. ``` -In the default setting, the application has to take care of shutting down vsomeip in case these signals are received. +In the default setting, the application has to take care of shutting down vSomeIP in case these signals are received. ##### Build Instructions for Android ###### Dependencies -- vsomeip uses Boost >= 1.55. The boost libraries (system, thread and log) must be included in the Android source tree and integrated into the build process with an appropriate Android.bp file. +- vSomeIP uses Boost >= 1.66. The boost libraries (system, thread and log) must be included in the Android source tree and integrated into the build process with an appropriate Android.bp file. ###### Compilation In general for building the Android source tree the instructions found on the pages from the Android Open Source Project (AOSP) apply (https://source.android.com/setup/build/requirements). -To integrate the vsomeip library into the build process, the source code together with the Android.bp file has to be inserted into the Android source tree (by simply copying or by fetching with a custom platform manifest). +To integrate the vSomeIP library into the build process, the source code together with the Android.bp file has to be inserted into the Android source tree (by simply copying or by fetching with a custom platform manifest). When building the Android source tree, the Android.bp file is automatically found and considered by the build system. -In order that the vsomeip library is also included in the Android image, the library has to be added to the PRODUCT_PACKAGES variable in one of a device/target specific makefile: +In order that the vSomeIP library is also included in the Android image, the library has to be added to the PRODUCT_PACKAGES variable in one of a device/target specific makefile: ``` PRODUCT_PACKAGES += \ diff --git a/build_qnx/common.mk b/build_qnx/common.mk index 12dacf8fc..c7905f681 100644 --- a/build_qnx/common.mk +++ b/build_qnx/common.mk @@ -37,9 +37,14 @@ ALL_DEPENDENCIES = vsomeip_all FLAGS += -g -D_QNX_SOURCE LDFLAGS += -Wl,--build-id=md5 -lang-c++ -lsocket +INCVPATH+=$(USE_ROOT_INCLUDE) +EXTRA_INCVPATH = $(USE_ROOT_INCLUDE)/io-sock +LIBVPATH=$(QNX_TARGET)/usr/lib +EXTRA_LIBVPATH = $(USE_ROOT_LIB)/io-sock + CMAKE_ARGS = -DCMAKE_TOOLCHAIN_FILE=$(PROJECT_ROOT)/qnx.nto.toolchain.cmake \ -DCMAKE_INSTALL_PREFIX=$(VSOMEIP_INSTALL_ROOT)/$(CPUVARDIR)/usr \ - -DCMAKE_CXX_STANDARD=14 \ + -DCMAKE_CXX_STANDARD=17 \ -DCMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE \ -DVSOMEIP_EXTERNAL_DEPS_INSTALL=$(VSOMEIP_EXTERNAL_DEPS_INSTALL) \ -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \ @@ -86,7 +91,7 @@ install: vsomeip_all clean iclean spotless: @rm -fr build - + endif #everything down below deals with the generation of the PINFO diff --git a/build_qnx/qnx.nto.toolchain.cmake b/build_qnx/qnx.nto.toolchain.cmake index 6df87db28..f87ed7218 100644 --- a/build_qnx/qnx.nto.toolchain.cmake +++ b/build_qnx/qnx.nto.toolchain.cmake @@ -39,5 +39,5 @@ set(CMAKE_FIND_ROOT_PATH ${VSOMEIP_EXTERNAL_DEPS_INSTALL};${VSOMEIP_EXTERNAL_DEP set(CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries.") set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) diff --git a/documentation/.gitignore b/documentation/.gitignore new file mode 100644 index 000000000..1e9a582d8 --- /dev/null +++ b/documentation/.gitignore @@ -0,0 +1,2 @@ +*.qea +asciidoctor diff --git a/documentation/diagrams/offer_service.drawio.svg b/documentation/diagrams/offer_service.drawio.svg new file mode 100644 index 000000000..716d0cc32 --- /dev/null +++ b/documentation/diagrams/offer_service.drawio.svg @@ -0,0 +1,142 @@ + + + + + + + + +
+
+
+ Offer service +
+
+
+
+ + Offer service + +
+
+ + + + +
+
+
+ Read static +
+ configuration data +
+
+
+
+ + Read static... + +
+
+ + + + +
+
+
+ Read dynamic +
+ configuration data +
+
+
+
+ + Read dynamic... + +
+
+ + + + +
+
+
+ Write dynamic +
+ configuration data +
+
+
+
+ + Write dynamic... + +
+
+ + + + + +
+
+
+ include +
+
+
+
+ + include + +
+
+ + + + + +
+
+
+ include +
+
+
+
+ + include + +
+
+ + + + + +
+
+
+ include +
+
+
+
+ + include + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/documentation/diagrams/sequence_offer_service.puml b/documentation/diagrams/sequence_offer_service.puml new file mode 100644 index 000000000..d6e29dabf --- /dev/null +++ b/documentation/diagrams/sequence_offer_service.puml @@ -0,0 +1,17 @@ +@startuml +actor "User application " as User +participant application +participant routing_manager +participant endpoint_manager +participant configuration + +User -> application : offer_service(service_t, instance_t, major_version_t, minor_version_t): bool +application -> routing_manager : offer_service(client_t, service_t, instance_t, major_version_t, minor_version_t):bool +routing_manager -> endpoint_manager : find_or_create_server_endpoint(service_t, instance_t): bool +endpoint_manager -> endpoint_manager : find_server_endpoint(service_t, instance_t) + +endpoint_manager --> routing_manager +routing_manager --> application +application --> User + +@enduml diff --git a/documentation/diagrams/sequence_offer_service.puml.svg b/documentation/diagrams/sequence_offer_service.puml.svg new file mode 100644 index 000000000..52859f144 --- /dev/null +++ b/documentation/diagrams/sequence_offer_service.puml.svg @@ -0,0 +1 @@ +User applicationUser applicationapplicationapplicationrouting_managerrouting_managerendpoint_managerendpoint_managerconfigurationconfigurationoffer_service(service_t, instance_t, major_version_t, minor_version_t): booloffer_service(client_t, service_t, instance_t, major_version_t, minor_version_t):boolfind_or_create_server_endpoint(service_t, instance_t): boolfind_server_endpoint(service_t, instance_t) \ No newline at end of file diff --git a/documentation/diagrams/usecases_overview.drawio.svg b/documentation/diagrams/usecases_overview.drawio.svg new file mode 100644 index 000000000..ba6bbcce7 --- /dev/null +++ b/documentation/diagrams/usecases_overview.drawio.svg @@ -0,0 +1,266 @@ + + + + + + + + + +
+
+
+ Application +
+
+
+
+ + Appli... + +
+
+ + + + + +
+
+
+ Offer service +
+
+
+
+ + Offer service + +
+
+ + + + + +
+
+
+ Stop to offer a service +
+
+
+
+ + Stop to offer a service + +
+
+ + + + + +
+
+
+ Publish eventgroup +
+
+
+
+ + Publish eventgroup + +
+
+ + + + + +
+
+
+ Stop to publish a service +
+
+
+
+ + Stop to publish a servi... + +
+
+ + + + + +
+
+
+ Send request +
+
+
+
+ + Send request + +
+
+ + + + + +
+
+
+ Send response +
+
+
+
+ + Send response + +
+
+ + + + + +
+
+
+ Trigger event +
+
+
+
+ + Trigger event + +
+
+ + + + + +
+
+
+ Update field +
+
+
+
+ + Update field + +
+
+ + + + + +
+
+
+ Receive message +
+
+
+
+ + Receive message + +
+
+ + + + + +
+
+
+ Request service +
+
+
+
+ + Request service + +
+
+ + + + + +
+
+
+ Release service +
+
+
+
+ + Release service + +
+
+ + + + + +
+
+
+ Subscribe eventgroup +
+
+
+
+ + Subscribe eventgroup + +
+
+ + + + + +
+
+
+ Unsubscribe eventgroup +
+
+
+
+ + Unsubscribe eventgroup + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/documentation/diagrams/usecases_overview.puml b/documentation/diagrams/usecases_overview.puml new file mode 100644 index 000000000..1e432f36c --- /dev/null +++ b/documentation/diagrams/usecases_overview.puml @@ -0,0 +1,20 @@ +@startuml + +left to right direction +:Application: as User + +(Offer service) <-- User +(Stop to offer a service) <-- User +(Publish eventgroup) <-- User +(Stop to publish a service) <-- User +User -> (Send request) +User -> (Send response) +User -> (Trigger event) +User -> (Update field) +User -> (Receiv message) +User --> (Request service) +User --> (Release service) +User --> (Subscribe eventgroup) +User --> (Unsubscribe service) + +@enduml diff --git a/documentation/multicast.txt b/documentation/multicast.txt deleted file mode 100644 index 4b9c3241e..000000000 --- a/documentation/multicast.txt +++ /dev/null @@ -1,6 +0,0 @@ -To use IP multicast, the route must be added. In Linux this can be done -by: - -# route add -net 224.0.0.0/4 dev eth0 - -Other OSes may have different ways to do this. diff --git a/documentation/network-tests.md b/documentation/network-tests.md new file mode 100644 index 000000000..e40ed7b43 --- /dev/null +++ b/documentation/network-tests.md @@ -0,0 +1,69 @@ +# vSomeIP - Run Network-Tests locally + +The network-tests can be run on your laptop using the Docker Compose setup designed for Zuul. +This page will guide you to accomplish that goal. + + +## Prerequisites + +1. Up-to-date clone of vsomeip, checked out on maintain/3.5 or on a branch recently created from it. +2. Recent Docker version with Compose plugin installed + + a. Check Docker version with docker info, must be at least 23.x.y or 24.x.y, otherwise follow the official instructions to install a newer version: https://docs.docker.com/engine/install/ubuntu/ + + $ docker info + Client: Docker Engine - Community + Version: 24.0.2 + (...) + b. Check if the Docker Compose plugin is installed with docker compose version. If the command fails, follow the official instructions to rectify your Docker installation: https://docs.docker.com/engine/install/ubuntu/ + + $ docker compose version + Docker Compose version v2.18.1 + +## Main steps + +1. Clone dlt-daemon to the same Project folder as vsomeip. + + git clone https://github.com/COVESA/dlt-daemon.git + + $ ls + dlt-daemon vsomeip + +2. Set the sanitizer type you'd like to use (use LEAK if you don't know or care which one gets used) + + export SANITIZER_TYPE=
+ + Example: + + export SANITIZER_TYPE=LEAK + + +3. Create the containers (you must be inside the vsomeip repo to run this step). This will first build the Docker image used by both that contains everything needed to build and run the network-tests (CMake, GCC, Boost, etc.) + + docker compose --project-directory zuul/network-tests build + +4. Start the containers (same as above, you must be inside the repo directory). This will build vsomeip-lib and then run the network-tests + + docker compose --project-directory zuul/network-tests up + + +## FAQ + +**Question**: I get a strange CMake error when I start the containers + + This occurs if you have recently rebuilt vsomeip-lib outside the Docker Compose setup. + It can also occur when rebuilding vsomeip-lib after pulling new changes from upstream. + + You can fix it by removing the build directory located inside the repo directory. + + +**Question**: I'd like to run only a subset of the network-tests + + Locate the CMakePresets.json file and add a "filter" entry inside the preset named ci-network-tests below "execution", like so: + + "filter": { + "include": { + "name": "" + } +} + diff --git a/documentation/readme.md b/documentation/readme.md new file mode 100644 index 000000000..ad42f8989 --- /dev/null +++ b/documentation/readme.md @@ -0,0 +1,26 @@ +# Multicast +To use IP multicast, the route must be added. In Linux this can be done +by: + +``` +# route add -net 224.0.0.0/4 dev eth0 +``` + +Other OSes may have different ways to do this. + +# Diagrams +## Use cases Overview + +![Use cases Overview](./diagrams/usecases_overview.drawio.svg) + +## Use case Offer service + +![Offer service](./diagrams/offer_service.drawio.svg) + +## Sequence Offer service + +![Seq Offer service](./diagrams/sequence_offer_service.puml.svg) + +# Support and review +## Open and closed points +- [ ] update the EA model to match the current implementation diff --git a/documentation/todo.txt b/documentation/todo.txt deleted file mode 100644 index 1933fd858..000000000 --- a/documentation/todo.txt +++ /dev/null @@ -1,3 +0,0 @@ -TODO: - -- update the EA model to match the current implementation diff --git a/documentation/vsomeipProtocol b/documentation/vsomeipProtocol deleted file mode 100644 index 2fc905ed0..000000000 --- a/documentation/vsomeipProtocol +++ /dev/null @@ -1,372 +0,0 @@ -vSomeIP command documentation -============================= - -VSOMEIP_ASSIGN_CLIENT (0x00) - -Command 00 -Version xx xx -Client xx xx -Size xx xx xx xx -Name xx ... xx ;#xx = Size - - -VSOMEIP_ASSIGN_CLIENT_ACK (0x01) - -Command 01 -Version xx xx -Client xx xx -Size 02 00 00 00 -Assigned xx xx - - -VSOMEIP_REGISTER_APPLICATION (0x02) - -Command 02 -Version xx xx -Client xx xx -Size 00 00 00 00 - - -VSOMEIP_DEREGISTER_APPLICATION (0x03) - -Command 03 -Version xx xx -Client xx xx -Size 00 00 00 00 - - -VSOMEIP_APPLICATION_LOST (0x04) - - - - -VSOMEIP_ROUTING_INFO (0x05) - -Command 05 -Version xx xx -Client xx xx -Size xx xx xx xx -Entries - SubCommand xx ; RIE_ADD_CLIENT (0x0) or RIE_DEL_CLIENT (0x1) - Size xx xx xx xx - Client xx xx - [Address] xx .. xx ; Size - sizeof(Client) - sizeof(Port) - [Port] xx - - SubCommand xx ; RIE_ADD_SERVICE_INSTANCE (0x2) or RIE_DEL_SERVICE_INSTANCE (0x3) - Size xx xx xx xx ; Command size - Size xx xx xx xx ; Client info size - Client xx xx - [Address] xx .. xx ; Client info size - sizeof(Client) - sizeof(Port) - [Port] xx - Size xx xx xx xx ; Services size - Service xx xx - Instance xx xx - Major xx - Minor xx xx xx xx - - -VSOMEIP_REGISTERED_ACK (0x06) - -Command 06 -Version xx xx -Client xx xx -Size 00 00 00 00 - - -VSOMEIP_PING (0x07) - -Command 07 -Version xx xx -Client 00 00 -Size 00 00 00 00 - - -VSOMEIP_PONG (0x08) - -Command 08 -Version xx xx -Client xx xx -Size 00 00 00 00 - - -VSOMEIP_OFFER_SERVICE (0x10) - -Command 10 -Version xx xx -Client xx xx -Size 09 00 00 00 -Service xx xx -Instance xx xx -Major xx -Minor xx xx xx xx - - -VSOMEIP_STOP_OFFER_SERVICE (0x11) - -Command 11 -Version xx xx -Client xx xx -Size 09 00 00 00 -Service xx xx -Instance xx xx -Major xx -Minor xx xx xx xx - - -VSOMEIP_SUBSCRIBE (0x12) - -Command 12 -Version xx xx -Client xx xx -Size xx xx xx xx -Service xx xx -Instance xx xx -Eventgroup xx xx -Major xx -Event xx xx -Pending ID xx xx -Filter - OnChange xx - OnChangeResetsInterval xx - Interval xx xx xx xx xx xx xx xx - Ignore (per entry) - Key xx xx xx xx xx xx xx xx - Value xx - - -VSOMEIP_UNSUBSCRIBE (0x13) -VSOMEIP_EXPIRE (0x2A) - -Command 13/2A -Version xx xx -Client xx xx -Size 0a 00 00 00 -Service xx xx -Instance xx xx -Eventgroup xx xx -Event xx xx -Pending ID xx xx - - -VSOMEIP_REQUEST_SERVICE (0x14) - -Command 14 -Version xx xx -Client xx xx -Size xx xx xx xx -Entries - Service xx xx - Instance xx xx - Major xx - Minor xx xx xx xx - - -VSOMEIP_RELEASE_SERVICE (0x15) - -Command 15 -Version xx xx -Client xx xx -Size 04 00 00 00 -Service xx xx -Instance xx xx - - -VSOMEIP_SUBSCRIBE_NACK (0x16) - -Command 16 -Version xx xx -Client xx xx -Size 0c 00 00 00 -Service xx xx -Instance xx xx -Eventgroup xx xx -Subscriber xx xx -Event xx xx -ID xx xx - - -VSOMEIP_SUBSCRIBE_ACK (0x17) - -Command 17 -Version xx xx -Client xx xx -Size 0c 00 00 00 -Service xx xx -Instance xx xx -Eventgroup xx xx -Subscriber xx xx -Event xx xx -ID xx xx - - -VSOMEIP_SEND (0x18) -VSOMEIP_NOTIFY (0x19) -VSOMEIP_NOTIFY_ONE (0x1A) - -Command 18|19|1a -Version xx xx -Client xx xx -Size xx xx xx xx -Instance xx xx -Reliable xx ; UDP (00) or TCP (01) -Status xx ; CRC of E2E - protected messages -Destination xx xx ; Client ID of the receiver -Payload xx ... xx - - -VSOMEIP_REGISTER_EVENT (0x1B) - -Command 1b -Version xx xx -Client xx xx -Size xx xx xx xx ; 10 + #eventgroups * 2 -Entries - Service xx xx - Instance xx xx - Notifier xx xx - Type xx ; ET_EVENT (00), ET_SELECTIVE_EVENT(01) or ET_FIELD(02) - Provided xx ; False (00) or True (01) - Reliability xx ; UDP (00) or TCP (01) - IsCyclic xx - Num Eventgroups xx xx - Entries - Eventgroup xx xx - - -VSOMEIP_UNREGISTER_EVENT (0x1C) - -Command 1c -Version xx xx -Client xx xx -Size 07 00 00 00 -Service xx xx -Instance xx xx -Notifier xx xx -Provided xx - - -VSOMEIP_ID_RESPONSE (0x1D) - - - - -VSOMEIP_ID_REQUEST (0x1E) - - - - -VSOMEIP_OFFERED_SERVICES_REQUEST (0x1F) - -Command 1f -Version xx xx -Client xx xx -Size 01 00 00 00 -OfferType xx (00 = LOCAL, 01 = REMOTE, 02 = ALL) - - -VSOMEIP_OFFERED_SERVICES_RESPONSE (0x20) - -Command 20 -Version xx xx -Client xx xx -Size xx xx xx xx -OfferedServices - Subcommand xx (00 = ADD CLIENT, 01 = ADD SERVICE INSTANCE, 02 = DELETE SERVICE INSTANCE, 03 = DELETE CLIENT) - Size xx xx xx xx - ServiceInstances - Service xx xx - Instance xx xx - Major xx xx - Minor xx xx - - -VSOMEIP_UNSUBSCRIBE_ACK (0x21) - -Command 21 -Version xx xx -Client xx xx -Size 08 00 00 00 -Service xx xx -Instance xx xx -Eventgroup xx xx -Id xx xx - - -VSOMEIP_RESEND_PROVIDED_EVENTS (0x22) - -Command 22 -Version xx xx -Client xx xx -Size 04 00 00 00 -PendingOfferId xx xx xx xx - - -VSOMEIP_UPDATE_SECURITY_POLICY (0x23) -VSOMEIP_UPDATE_SECURITY_POLICY_INT (0x29) - -Command 23/29 -Version xx xx -Client xx xx -Size xx xx xx xx -UpdateId xx xx xx xx -Policy xx ... xx - - -VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE (0x24) - -Command 24 -Version xx xx -Client xx xx -Size 04 00 00 00 -UpdateId xx xx xx xx - - -VSOMEIP_REMOVE_SECURITY_POLICY (0x25) - -Command 25 -Version xx xx -Client xx xx -Size 0c 00 00 00 -UpdateId xx xx xx xx -Uid xx xx xx xx -Gid xx xx xx xx - - -VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE (0x26) - -Command 26 -Version xx xx -Client xx xx -Size 04 00 00 00 -UpdateId xx xx xx xx - - -VSOMEIP_UPDATE_SECURITY_CREDENTIALS (0x27) - -Command 27 -Version xx xx -Client xx xx -Size xx xx xx xx -Credentials - Uid xx xx xx xx - Gid xx xx xx xx - - -VSOMEIP_DISTRIBUTE_SECURITY_POLICIES (0x28) - -Command 28 -Version xx xx -Client xx xx xx xx -Size xx xx xx xx -PoliciesCount xx xx xx xx -Policies - Size xx xx xx xx - Data xx ... xx - - -VSOMEIP_SUSPEND (0x30) - -Command 30 -Version xx xx -Size xx xx xx xx \ No newline at end of file diff --git a/documentation/vsomeipProtocol.md b/documentation/vsomeipProtocol.md new file mode 100644 index 000000000..e3a896961 --- /dev/null +++ b/documentation/vsomeipProtocol.md @@ -0,0 +1,385 @@ +# vSomeIP command documentation + +## VSOMEIP_ASSIGN_CLIENT (0x00) + + Command 00 + Version xx xx + Client xx xx + Size xx xx xx xx + Name xx ... xx ;#xx = Size + +## VSOMEIP_ASSIGN_CLIENT_ACK (0x01) + + Command 01 + Version xx xx + Client xx xx + Size 02 00 00 00 + Assigned xx xx + +## VSOMEIP_REGISTER_APPLICATION (0x02) + + Command 02 + Version xx xx + Client xx xx + Size 00 00 00 00 + +## VSOMEIP_DEREGISTER_APPLICATION (0x03) + + Command 03 + Version xx xx + Client xx xx + Size 00 00 00 00 + + +## VSOMEIP_APPLICATION_LOST (0x04) + +`` + + +## VSOMEIP_ROUTING_INFO (0x05) + + Command 05 + Version xx xx + Client xx xx + Size xx xx xx xx + Entries + SubCommand xx ; RIE_ADD_CLIENT (0x0) or RIE_DEL_CLIENT (0x1) + Size xx xx xx xx + Client xx xx + [Address] xx .. xx ; Size - sizeof(Client) - sizeof(Port) + [Port] xx + + SubCommand xx ; RIE_ADD_SERVICE_INSTANCE (0x2) or RIE_DEL_SERVICE_INSTANCE (0x3) + Size xx xx xx xx ; Command size + Size xx xx xx xx ; Client info size + Client xx xx + [Address] xx .. xx ; Client info size - sizeof(Client) - sizeof(Port) + [Port] xx + Size xx xx xx xx ; Services size + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +## VSOMEIP_REGISTERED_ACK (0x06) + + Command 06 + Version xx xx + Client xx xx + Size 00 00 00 00 + + +## VSOMEIP_PING (0x07) + + Command 07 + Version xx xx + Client 00 00 + Size 00 00 00 00 + + +## VSOMEIP_PONG (0x08) + + Command 08 + Version xx xx + Client xx xx + Size 00 00 00 00 + + +## VSOMEIP_OFFER_SERVICE (0x10) + + Command 10 + Version xx xx + Client xx xx + Size 09 00 00 00 + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +## VSOMEIP_STOP_OFFER_SERVICE (0x11) + + Command 11 + Version xx xx + Client xx xx + Size 09 00 00 00 + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +## VSOMEIP_SUBSCRIBE (0x12) + + Command 12 + Version xx xx + Client xx xx + Size xx xx xx xx + Service xx xx + Instance xx xx + Eventgroup xx xx + Major xx + Event xx xx + Pending ID xx xx + Filter + OnChange xx + OnChangeResetsInterval xx + Interval xx xx xx xx xx xx xx xx + Ignore (per entry) + Key xx xx xx xx xx xx xx xx + Value xx + + +## VSOMEIP_UNSUBSCRIBE (0x13) + +## VSOMEIP_EXPIRE (0x2A) + + Command 13/2A + Version xx xx + Client xx xx + Size 0a 00 00 00 + Service xx xx + Instance xx xx + Eventgroup xx xx + Event xx xx + Pending ID xx xx + + +## VSOMEIP_REQUEST_SERVICE (0x14) + + Command 14 + Version xx xx + Client xx xx + Size xx xx xx xx + Entries + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +## VSOMEIP_RELEASE_SERVICE (0x15) + + Command 15 + Version xx xx + Client xx xx + Size 04 00 00 00 + Service xx xx + Instance xx xx + + +## VSOMEIP_SUBSCRIBE_NACK (0x16) + + Command 16 + Version xx xx + Client xx xx + Size 0c 00 00 00 + Service xx xx + Instance xx xx + Eventgroup xx xx + Subscriber xx xx + Event xx xx + ID xx xx + + +## VSOMEIP_SUBSCRIBE_ACK (0x17) + + Command 17 + Version xx xx + Client xx xx + Size 0c 00 00 00 + Service xx xx + Instance xx xx + Eventgroup xx xx + Subscriber xx xx + Event xx xx + ID xx xx + + +## VSOMEIP_SEND (0x18) + +## VSOMEIP_NOTIFY (0x19) + +## VSOMEIP_NOTIFY_ONE (0x1A) + + Command 18|19|1a + Version xx xx + Client xx xx + Size xx xx xx xx + Instance xx xx + Reliable xx ; UDP (00) or TCP (01) + Status xx ; CRC of E2E - protected messages + Destination xx xx ; Client ID of the receiver + Payload xx ... xx + + +## VSOMEIP_REGISTER_EVENT (0x1B) + + Command 1b + Version xx xx + Client xx xx + Size xx xx xx xx ; 10 + #eventgroups * 2 + Entries + Service xx xx + Instance xx xx + Notifier xx xx + Type xx ; ET_EVENT (00), ET_SELECTIVE_EVENT(01) or ET_FIELD(02) + Provided xx ; False (00) or True (01) + Reliability xx ; UDP (00) or TCP (01) + IsCyclic xx + Num Eventgroups xx xx + Entries + Eventgroup xx xx + + +## VSOMEIP_UNREGISTER_EVENT (0x1C) + + Command 1c + Version xx xx + Client xx xx + Size 07 00 00 00 + Service xx xx + Instance xx xx + Notifier xx xx + Provided xx + + +## VSOMEIP_ID_RESPONSE (0x1D) + +`` + + +## VSOMEIP_ID_REQUEST (0x1E) + +`` + + +## VSOMEIP_OFFERED_SERVICES_REQUEST (0x1F) + + Command 1f + Version xx xx + Client xx xx + Size 01 00 00 00 + OfferType xx (00 = LOCAL, 01 = REMOTE, 02 = ALL) + + +## VSOMEIP_OFFERED_SERVICES_RESPONSE (0x20) + + Command 20 + Version xx xx + Client xx xx + Size xx xx xx xx + OfferedServices + Subcommand xx (00 = ADD CLIENT, 01 = ADD SERVICE INSTANCE, 02 = DELETE SERVICE INSTANCE, 03 = DELETE CLIENT) + Size xx xx xx xx + ServiceInstances + Service xx xx + Instance xx xx + Major xx xx + Minor xx xx + + +## VSOMEIP_UNSUBSCRIBE_ACK (0x21) + + Command 21 + Version xx xx + Client xx xx + Size 08 00 00 00 + Service xx xx + Instance xx xx + Eventgroup xx xx + Id xx xx + + +## VSOMEIP_RESEND_PROVIDED_EVENTS (0x22) + + Command 22 + Version xx xx + Client xx xx + Size 04 00 00 00 + PendingOfferId xx xx xx xx + + +## VSOMEIP_UPDATE_SECURITY_POLICY (0x23) + +## VSOMEIP_UPDATE_SECURITY_POLICY_INT (0x29) + + Command 23/29 + Version xx xx + Client xx xx + Size xx xx xx xx + UpdateId xx xx xx xx + Policy xx ... xx + + +## VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE (0x24) + + Command 24 + Version xx xx + Client xx xx + Size 04 00 00 00 + UpdateId xx xx xx xx + + +## VSOMEIP_REMOVE_SECURITY_POLICY (0x25) + + Command 25 + Version xx xx + Client xx xx + Size 0c 00 00 00 + UpdateId xx xx xx xx + Uid xx xx xx xx + Gid xx xx xx xx + + +## VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE (0x26) + + Command 26 + Version xx xx + Client xx xx + Size 04 00 00 00 + UpdateId xx xx xx xx + + +## VSOMEIP_UPDATE_SECURITY_CREDENTIALS (0x27) + + Command 27 + Version xx xx + Client xx xx + Size xx xx xx xx + Credentials + Uid xx xx xx xx + Gid xx xx xx xx + + +## VSOMEIP_DISTRIBUTE_SECURITY_POLICIES (0x28) + + Command 28 + Version xx xx + Client xx xx xx xx + Size xx xx xx xx + PoliciesCount xx xx xx xx + Policies + Size xx xx xx xx + Data xx ... xx + + +## VSOMEIP_SUSPEND (0x30) + + Command 30 + Version xx xx + Size xx xx xx xx + + +## VSOMEIP_CONFIG (0x31) + + Command 31 + Version 00 00 + Client xx xx + Size xx xx xx xx + Configurations + Key Size xx xx xx xx + Key (string) xx ... xx + Value Size xx xx xx xx + Value (string) xx ... xx diff --git a/documentation/vsomeipUserGuide b/documentation/vsomeipUserGuide deleted file mode 100644 index 6ef3e116a..000000000 --- a/documentation/vsomeipUserGuide +++ /dev/null @@ -1,2452 +0,0 @@ -vsomeip -======= -// This enables a nice TOC as a sidebar -:toc2: -// Show all headings in TOC -:toclevels: 4 -// Show icons if e.g. TIP: or IMPORTANT is used -:icons: -// Set the directory where the default icons can be found -:iconsdir: {asciidoc-confdir}/{iconsdir} -// number all headings -:numbered: -// this embeds images (e.g. the icons for TIP: $TEXT) into the html file -:data-uri: - -Copyright -+++++++ -Copyright (C) 2015-2022, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - -License -+++++++ -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/. - -Version -+++++++ -// set the version to the one we get from cmake -// or pass it via -a version=$VSOMEIP_VERSION to asciidoc -This documentation was generated for version {version} of vsomeip. - -vsomeip Overview ----------------- -The vsomeip stack implements the http://some-ip.com/[Scalable service-Oriented -MiddlewarE over IP (SOME/IP)] protocol. The stack consists out of: - -* a shared library for SOME/IP (`libvsomeip.so`) -* a second shared library for SOME/IP's service discovery (`libvsomeip-sd.so`) - which is loaded during runtime if the service discovery is enabled. - -Build Instructions ------------------- -Dependencies -~~~~~~~~~~~~ -* A C++14 enabled compiler is needed (default for gcc >= v6.1) -* vsomeip uses cmake as buildsystem. -* vsomeip uses Boost >= 1.55: -** Ubuntu 14.04: -*** `sudo apt-get install libboost-system1.55-dev libboost-thread1.55-dev - libboost-log1.55-dev` -** Ubuntu 12.04: a PPA is necessary to use version 1.54 of Boost: -*** URL: https://launchpad.net/~boost-latest/+archive/ubuntu/ppa -*** `sudo add-apt-repository ppa:boost-latest/ppa` -*** `sudo apt-get install libboost-system1.55-dev libboost-thread1.55-dev - libboost-log1.55-dev` -* For the tests Google's test framework - https://code.google.com/p/googletest/[gtest] in version 1.7.0 is needed -** URL: https://googletest.googlecode.com/files/gtest-1.7.0.zip[direct link, - version 1.7.0] -* To build the documentation asciidoc, source-highlight, doxygen and graphviz is needed: -** `sudo apt-get install asciidoc source-highlight doxygen graphviz` - -Compilation -~~~~~~~~~~~ -anchor:Compilation[] -For compilation call: -[source, bash] ----- -mkdir build -cd build -cmake .. -make ----- - -To specify a installation directory (like `--prefix=` if you're used to -autotools) call cmake like: -[source, bash] ----- -cmake -DCMAKE_INSTALL_PREFIX:PATH=$YOUR_PATH .. -make -make install ----- - -Compilation with predefined base path -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To predefine the base path, the path that is used to create the local sockets, -call cmake like: -[source,bash] ----- -cmake -DBASE_PATH= .. ----- -The default base path is /tmp. - -Compilation with predefined unicast and/or diagnosis address -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To predefine the unicast address, call cmake like: -[source,bash] ----- -cmake -DUNICAST_ADDRESS= .. ----- - -To predefine the diagnosis address, call cmake like: -[source,bash] ----- -cmake -DDIAGNOSIS_ADDRESS= .. ----- -The diagnosis address is a single byte value. - -Compilation with custom default configuration folder -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To change the default configuration folder, call cmake like: -[source,bash] ----- -cmake -DDEFAULT_CONFIGURATION_FOLDER= .. ----- -The default configuration folder is /etc/vsomeip. - -Compilation with custom default configuration file -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To change the default configuration file, call cmake like: -[source,bash] ----- -cmake -DDEFAULT_CONFIGURATION_FILE= .. ----- -The default configuration file is /etc/vsomeip.json. - -Compilation with changed (maximimum) wait times for local TCP ports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If local communication is done via TCP, we depend on the availability -of the network. Therefore, server port creation and therefore port -assignment might fail. If the failure is causes by the port already -being in use, we use the next available port. For all other failure, -we wait for a wait time until we retry with the same port. If the -overall wait time of all retries exceeds the maximum wait time, -the endpoint creation is aborted. To configure wait time and maximum -wait time, call cmake with: -[source,bash] ------ -cmake -DLOCAL_TCP_PORT_WAIT_TIME=50 -DLOCAL_TCP_PORT_MAX_WAIT_TIME=2000 .. ------ -The default values are a wait time of 100ms and a maximum wait time of 10000ms. -These configurations have no effect if local communication uses UDS (default). - -Compilation with signal handling -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To compile vsomeip with signal handling (SIGINT/SIGTERM) enabled, -call cmake like: -[source,bash] ----- -cmake -DENABLE_SIGNAL_HANDLING=1 .. ----- -In the default setting, the application has to take care of shutting -down vsomeip in case these signals are received. - -Compilation with user defined "READY" message -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To compile vsomeip with a user defined message signal the IP routing -to be ready to send/receive messages, call cmake like: -[source,bash] ----- -cmake -DROUTING_READY_MESSAGE= .. ----- - -Compilation with vSomeIP 2 compatibility layer -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To compile vsomeip with enabled vSomeIP 2 compatibility layer, call -cmake like: -[source,bash] ----- -cmake -DENABLE_COMPAT=1 .. ----- - -Compilation of examples -^^^^^^^^^^^^^^^^^^^^^^^ -For compilation of the examples call: -[source, bash] ----- -mkdir build -cd build -cmake .. -make examples ----- - -Compilation of tests -^^^^^^^^^^^^^^^^^^^^ -To compile the tests, first unzip gtest to location of your desire. -Some of the tests require a second node on the same network. There are two cmake -variables which are used to automatically adapt the json files to the used -network setup: - -* `TEST_IP_MASTER`: The IP address of the interface which will act as test - master. -* `TEST_IP_SLAVE`: The IP address of the interface of the second node which will - act as test slave. - -If one of this variables isn't specified, only the tests using local -communication exclusively will be runnable. - -Additionally the unit tests require enabled signal handling which can be enabled -via the `ENABLE_SIGNAL_HANDLING` cmake variable. - -Example, compilation of tests: -[source, bash] ----- -mkdir build -cd build -export GTEST_ROOT=$PATH_TO_GTEST/gtest-1.7.0/ -cmake -DENABLE_SIGNAL_HANDLING=1 -DTEST_IP_MASTER=10.0.3.1 -DTEST_IP_SLAVE=10.0.3.125 .. -make check ----- - -Additional make targets for the tests: - -* Call `make build_tests` to only compile the tests -* Call `ctest` in the build directory to execute the tests without a verbose - output -* To run single tests call `ctest --verbose --tests-regex $TESTNAME` short - form: `ctest -V -R $TESTNAME` -* To list all available tests run `ctest -N`. -* For further information about the tests please have a look at the - `readme.txt` in the `test` subdirectory. - -For development purposes two cmake variables exist which control if the -json files and test scripts are copied (default) or symlinked into the build -directory. These settings are ignored on Windows. - -* `TEST_SYMLINK_CONFIG_FILES`: Controls if the json and scripts needed - to run the tests are copied or symlinked into the build directory. (Default: - OFF, ignored on Windows) -* `TEST_SYMLINK_CONFIG_FILES_RELATIVE`: Controls if the json and scripts needed - to run the tests are symlinked relatively into the build directory. - (Default: OFF, ignored on Windows) - -Example cmake call: -[source, bash] ----- -cmake -DTEST_SYMLINK_CONFIG_FILES=ON -DTEST_SYMLINK_CONFIG_FILES_RELATIVE=ON .. ----- - -For compilation of only a subset of tests (for a quick -functionality check) the cmake variable `TESTS_BAT` has -to be set: - -Example cmake call: -[source, bash] ----- -cmake -DTESTS_BAT=ON .. ----- - -Compilation of vsomeip_ctrl -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -For compilation of the <> utility call: -[source, bash] ----- -mkdir build -cd build -cmake .. -make vsomeip_ctrl ----- - -Generating the documentation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To generate the documentation call cmake as described in <> and -then call `make doc`. -This will generate: - -* The README file in html: `$BUILDDIR/documentation/README.html` -* A doxygen documentation in `$BUILDDIR/documentation/html/index.html` - -Starting vsomeip Applications / Used environment variables ----------------------------------------------------------- -On startup the following environment variables are read out: - -* `VSOMEIP_APPLICATION_NAME`: This environment variable is used to specify the - name of the application. This name is later used to map a client id to the - application in the configuration file. It is independent from the - application's binary name. -* `VSOMEIP_CONFIGURATION`: vsomeip uses the default configuration file `/etc/vsomeip.json` - and/or the default configuration folder `/etc/vsomeip`. This can be overridden by a - local configuration file `./vsomeip.json` and/or a local configuration folder `./vsomeip`. - If `VSOMEIP_CONFIGURATION` is set to a valid file or directory path, this is used instead - of the standard configuration (thus neither default nor local file/folder will be parsed). -* `VSOMEIP_CONFIGURATION_`: Application-specific version of `VSOMEIP_CONFIGURATION`. - Please note that must be valid as part of an environment variable. -* `VSOMEIP_MANDATORY_CONFIGURATION_FILES`: vsomeip allows to specify mandatory configuration - files to speed-up application startup. While mandatory configuration files are read by all - applications, all other configuration files are only read by the application that is - responsible for connections to external devices. If this configuration variable is not set, - the default mandatory files vsomeip_std.json, vsomeip_app.json and vsomeip_plc.json are used. -* `VSOMEIP_CLIENTSIDELOGGING`: Set this variable to an empty string to enable logging of - any received messages to DLT in all applications acting as routing manager proxies. For - example add the following line to the application's systemd service file: - `Environment=VSOMEIP_CLIENTSIDELOGGING=""` - To enable service-specific logs, provide a space- or colon-separated list of ServiceIDs (using - 4-digit hexadecimal notation, optionally followed by dot-separted InstanceID). For example: - `Environment=VSOMEIP_CLIENTSIDELOGGING="b003.0001 f013.000a 1001 1002"` - `Environment=VSOMEIP_CLIENTSIDELOGGING="b003.0001:f013.000a:1001:1002"` - -NOTE: If the file/folder that is configured by `VSOMEIP_CONFIGURATION` does _not_ exist, -the default configuration locations will be used. - -NOTE: vsomeip will parse and use the configuration from all files in a configuration folder -but will _not_ consider directories within the configuration folder. - -In the following example the application `my_vsomeip_application` is started. -The settings are read from the file `my_settings.json` in the current working -directory. The client id for the application can be found under the name -`my_vsomeip_client` in the configuration file. - -[source, bash] ----- -#!/bin/bash -export VSOMEIP_APPLICATION_NAME=my_vsomeip_client -export VSOMEIP_CONFIGURATION=my_settings.json -./my_vsomeip_application ----- - -Configuration File Structure ----------------------------- -The configuration files for vsomeip are http://www.json.org/[JSON]-Files and are -composed out of multiple key value pairs and arrays. - -[quote, , json.org] -____ -* An object is an unordered set of name/value pairs. An object begins with `{ -(left brace)` and ends with `} (right brace)`. Each name is followed by `: -(colon)` and the name/value pairs are separated by `, (comma)`. - -* An array is an ordered collection of values. An array begins with `[ (left -bracket)` and ends with `] (right bracket)`. Values are separated by `, -(comma)`. - -* A value can be a _string_ in double quotes, or a _number_, or `true` or `false` -or `null`, or an _object_ or an _array_. These structures can be nested. -____ - -Configuration file element explanation: - - -* 'unicast' -+ -The IP address of the host system. -+ -* 'netmask' -+ -The netmask to specify the subnet of the host system. -+ -* 'device' (optional) -+ -If specified, IP endpoints will be bound to this device. -+ -* 'diagnosis' -+ -The diagnosis address (byte) that will be used to build client identifiers. The -diagnosis address is assigned to the most significant byte in all client -identifiers if not specified otherwise (for example through a predefined client -ID). -+ -* 'diagnosis_mask' -+ -The diagnosis mask (2 byte) is used to control the maximum amount of allowed -concurrent vsomeip clients on an ECU and the start value of the client IDs. -+ -The default value is `0xFF00` meaning -the most significant byte of the client ID is reserved for the diagnosis -address and the client IDs will start with the diagnosis address as specified. -The maximum number of clients is 255 as the Hamming weight of the inverted mask -is 8 (2^8 = 256 - 1 (for the routing manager) = 255). The resulting client ID -range with a diagnosis address of for example 0x45 would be 0x4501 to 0x45ff. -+ -Setting the mask to `0xFE00` doubles client ID range to 511 clients as the -Hamming weight of the inverted mask is greater by one. With a diagnosis address -of 0x45 the start value of client IDs is 0x4401 as bit 8 in 0x4500 is masked -out. This then yields a client ID range of 0x4400 to 0x45ff. - -* 'network' -+ -Network identifier used to support multiple routing managers on one host. This -setting changes the name of the shared memory segment in `/dev/shm` and the name -of the unix domain sockets in `/tmp/`. Defaults to `vsomeip` meaning the shared -memory will be named `/dev/shm/vsomeip` and the unix domain sockets will be -named `/tmp/vsomeip-$CLIENTID` -+ -//Logging -* 'logging' -+ -** 'level' -+ -Specifies the log level (valid values: _trace_, _debug_, _info_, _warning_, -_error_, _fatal_). -+ -** 'console' -+ -Specifies whether logging via console is enabled (valid values: _true, false_). -+ -** 'file' -+ -*** 'enable' -+ -Specifies whether a log file should be created (valid values: _true, false_). -+ -*** 'path' -+ -The absolute path of the log file. -+ -** 'dlt' -+ -Specifies whether Diagnostic Log and Trace (DLT) is enabled (valid values: -_true, false_). -+ -** 'version' -+ -Configures logging of the vsomeip version -+ -*** 'enable' -+ -Enable or disable cyclic logging of vsomeip version, defaults to true (valid -values: _true, false_) -+ -*** 'interval' -+ -Configures interval in seconds to log the vsomeip version. Default value is 10. -+ -** 'memory_log_interval' -+ -Configures interval in seconds in which the routing manager logs its used -memory. Setting a value greater than zero enables the logging. -+ -** 'status_log_interval' -+ -Configures interval in seconds in which the routing manager logs its internal -status. Setting a value greater than zero enables the logging. -+ -//Tracing -* anchor:config-tracing[]'tracing' (optional) -+ -** 'enable' -+ -Specifies whether the tracing of the SOME/IP messages is enabled -(valid values: _true, false_). Default value is _false_. -If tracing is enabled, the messages will be forwarded to DLT by -the <> -+ -** 'sd_enable' -+ -Specifies whether the tracing of the SOME/IP service discovery messages is -enabled (valid values: _true, false_). Default value is _false_. -+ -** 'channels (array)' (optional) -+ -Contains the channels to DLT. -+ -NOTE: You can set up multiple channels to DLT over that you can forward the -messages. -+ -*** 'name' -+ -The name of the channel. -+ -*** 'id' -+ -The id of the channel. -+ -** 'filters (array)' (optional) -+ -Contains the filters that are applied on the messages. -+ -NOTE: You can apply filters respectively filter rules on the messages with -specific criterias and expressions. So only the filtered messages are forwarded -to DLT. -+ -*** 'channel' (optional) -+ -The id of the channel over that the filtered messages are forwarded to DLT. If -no channel is specified the default channel (TC) is used. If you want to use a -filter in several different channels, you can provide an array of channel ids. -+ -NOTE: If you use a positive filter with multiple channels, the same message -will be forwared multiple times to DLT. -+ -*** 'matches' (optional) -+ -Specification of the criteria to include/exclude a message into/from the trace. -You can either specify lists (array) or ranges of matching elements. -+ -A list may contain single identifiers which match all messages from/to all -instances of the corresponding service or tuples consisting of service-, -instance- and method-identifier. 'any' may be used as a wildcard for matching -all services, instances or methods. -+ -A range is specified by two tuples "from" and "to", each consisting of -service-, instance-and method-identifier. All messages with service-, -instance-and method-identifiers that are greater than or equal to "from" -and less than or equal to "to" are matched. -+ -*** 'type' (optional) -+ -Specifies the filter type (valid values: "positive", "negative", "header-only"). -When a positive filter is used and a message matches one of the filter rules, -the message will be traced/forwarded to DLT. With a negative filter messages -can be excluded. So when a message matches one of the filter rules, the message -will not be traced/forwarded to DLT. Default value is "positive". The value -"header-only" implies the filter is also considered "positive". - -+ -//Applications -* 'applications (array)' -+ -Contains the applications of the host system that use this config file. -+ -** 'name' -+ -The name of the application. -+ -** 'id' -+ -The id of the application. Usually its high byte is equal to the diagnosis address. In this -case the low byte must be different from zero. Thus, if the diagnosis address is 0x63, valid -values range from 0x6301 until 0x63FF. It is also possible to use id values with a high byte -different from the diagnosis address. -+ -** 'max_dispatchers' (optional) -+ -The maximum number of threads that shall be used to execute the application callbacks. Default is 10. -+ -** 'max_dispatch_time' (optional) -+ -The maximum time in ms that an application callback may consume before the callback is -considered to be blocked (and an additional thread is used to execute pending -callbacks if max_dispatchers is configured greater than 0). The default value if not specified is 100ms. -+ -** 'threads' (optional) -+ -The number of internal threads to process messages and events within an application. -Valid values are 1-255. Default is 2. -+ -** 'io_thread_nice' (optional) -+ -The nice level for internal threads processing messages and events. POSIX/Linux only. -For actual values refer to nice() documentation. -+ -** 'request_debounce_time' (optional) -+ -Specifies a debounce-time interval in ms in which request-service messages are sent to -the routing manager. If an application requests many services in short same time -the load of sent messages to the routing manager and furthermore the replies from the -routing manager (which contains the routing info for the requested service if available) -can be heavily reduced. The default value if not specified is 10ms. -+ -** 'plugins' (optional array) -+ -Contains the plug-ins that should be loaded to extend the functionality of vsomeip. -+ -*** 'name' -+ -The name of the plug-in. -+ -*** 'type' -+ -The plug-in type (valid values: _application_plugin_). -+ -An application plug-in extends the functionality on application level. It gets informed -by vsomeip over the basic application states (INIT/START/STOP) and can, based on these -notifications, access the standard "application"-API via the runtime. -+ -* `services` (array) -+ -Contains the services of the service provider. - -** `service` -+ -The id of the service. - -** `instance` -+ -The id of the service instance. - -** `protocol` (optional) -+ -The protocol that is used to implement the service instance. The default setting -is _someip_. If a different setting is provided, vsomeip does not open the specified -port (server side) or does not connect to the specified port (client side). Thus, -this option can be used to let the service discovery announce a service that is -externally implemented. - -** `unicast` (optional) -+ -The unicast that hosts the service instance. -+ -NOTE: The unicast address is needed if external service instances shall be used, -but service discovery is disabled. In this case, the provided unicast address -is used to access the service instance. - -** `reliable` -+ -Specifies that the communication with the service is reliable respectively the -TCP protocol is used for communication. - -*** `port` -+ -The port of the TCP endpoint. - -*** `enable-magic-cookies` -+ -Specifies whether magic cookies are enabled (valid values: _true_, _false_). - -** `unreliable` -+ -Specifies that the communication with the service is unreliable respectively the -UDP protocol is used for communication (valid values: the _port_ of the UDP -endpoint). - -** `events` (array) -+ -Contains the events of the service. - -*** `event` -+ -The id of the event. - -*** `is_field` -+ -Specifies whether the event is of type field. -+ -NOTE: A field is a combination of getter, setter and notification event. It -contains at least a getter, a setter, or a notifier. The notifier sends an event -message that transports the current value of a field on change. - -*** `is_reliable` -+ -Specifies whether the communication is reliable respectively whether the event -is sent with the TCP protocol (valid values: _true_,_false_). -+ -If the value is _false_ the UDP protocol will be used. - -** `eventgroups` (array) -+ -Events can be grouped together into on event group. For a client it is thus -possible to subscribe for an event group and to receive the appropriate events -within the group. - -*** `eventgroup` -+ -The id of the event group. - -*** `events` (array) -+ -Contains the ids of the appropriate events. - -*** `multicast` -+ -Specifies the multicast that is used to publish the eventgroup. - -**** `address` -+ -The multicast address. - -**** `port` -+ -The multicast port. - -*** `threshold` -+ -Specifies when to use multicast and when to use unicast to send a notification event. -Must be set to a non-negative number. If it is set to zero, all events of the eventgroup -will be sent by unicast. Otherwise, the events will be sent by unicast as long as the -number of subscribers is lower than the threshold and by multicast if the number -of subscribers is greater or equal. This means, a threshold of 1 will lead to all events -being sent by multicast. The default value is _0_. - -** `debounce-times` (object) -+ -Used to configure the nPDU feature. This is described in detail in -<>. - -** `someip-tp` (object) -+ -Used to configure the SOME/IP-TP feature. There's an example available at -<>. - -*** `service-to-client` (array) -+ -Contains the IDs for responses, fields and events which are sent from the node -to a remote client which can be segmented via SOME/IP-TP if they exceed the -maximum message size for UDP communication. If an ID isn't listed here the -message will otherwise be dropped if the maximum message size is exceeded. - -*** `client-to-service` (array) -+ -Contains the IDs for requests, which are sent from the node -to a remote service which can be segmented via SOME/IP-TP if they exceed the -maximum message size for UDP communication. If an ID isn't listed here the -message will otherwise be dropped if the maximum message size is exceeded. -Please note that the unicast key has to be set to the remote IP address of the -offering node for this setting to take effect. - - -* `clients` (array) -+ -The client-side ports that shall be used to connect to a specific service. -For each service, an array of ports to be used for reliable / unreliable -communication can be specified. vsomeip will take the first free port of -the list. If no free port can be found, the connection will fail. If -vsomeip is asked to connect to a service instance without specified port(s), -the port will be selected by the system. This implies that the user has -to ensure that the ports configured here do not overlap with the ports -automatically selected by the IP stack. - -** `service` -** `instance` -+ -Together they specify the service instance the port configuration shall be applied to. - -** `reliable` (array) -+ -The list of client ports to be used for reliable (TCP) communication to the given -service instance. - -** `unreliable` (array) -+ -The list of client ports to be used for unreliable (UDP) communication to the given -service instance. - -+ -Additionally there is the possibility to configure mappings between ranges of client -ports and ranges of remote service ports. -(If a client port is configured for a specific service / instance, the port range mapping is ignored) - -** `reliable_remote_ports` -+ -Specifies a range of reliable remote service ports - -** `unreliable_remote_ports` -+ -Specifies a range of unreliable remote service ports - -** `reliable_client_ports` -+ -Specifies the range of reliable client ports to be mapped to the reliable_remote_ports range - -** `unreliable_client_ports` -+ -Specifies the range of unreliable client ports to be mapped to the unreliable_remote_ports range - - -** `first` -+ -Specifies the lower bound of a port range - -** `last` -+ -Specifies the upper bound of a port range - -* `payload-sizes` (array) -+ -Array to limit the maximum allowed payload sizes per IP and port. If not -specified otherwise the allowed payload sizes are unlimited. The settings in -this array only affect communication over TCP. To limit the local payload size -`max-payload-size-local` can be used. - -** `unicast` -+ -On client side: the IP of the remote service for which the payload size should -be limited. -+ -On service side: the IP of the offered service for which the payload size for -receiving and sending should be limited. - -** `ports` (array) -+ -Array which holds pairs of port and payload size statements. - -*** `port` -+ -On client side: the port of the remote service for which the payload size should -be limited. -+ -On service side: the port of the offered service for which the payload size for -receiving and sending should be limited. - -*** `max-payload-size` -+ -On client side: the payload size limit in bytes of a message sent to the -remote service hosted on beforehand specified IP and port. -+ -On service side: the payload size limit in bytes of messages received and sent -by the service offered on previously specified IP and port. -+ -If multiple services are hosted on the same port they all share the limit -specified. - -* `max-payload-size-local` -+ -The maximum allowed payload size for node internal communication in bytes. By -default the payload size for node internal communication is unlimited. It can be -limited via this setting. - -* `max-payload-size-reliable` -+ -The maximum allowed payload size for TCP communication in -bytes. By default the payload size for TCP communication is -unlimited. It can be limited via this setting. - -* `max-payload-size-unreliable` -+ -The maximum allowed payload size for UDP communication via SOME/IP-TP in -bytes. By default the payload size for UDP via SOME/IP-TP communication is -unlimited. It can be limited via this setting. This setting only applies for -SOME/IP-TP enabled methods/events/fields (otherwise the UDP default of 1400 -bytes applies). See <> for an example configuration. - -* `endpoint-queue-limits` (array) -+ -Array to limit the maximum allowed size in bytes of cached outgoing messages per -IP and port (message queue size per endpoint). If not specified otherwise the -allowed queue size is unlimited. The settings in this array only affect external -communication. To limit the local queue size `endpoint-queue-limit-local` can -be used. - -** `unicast` -+ -On client side: the IP of the remote service for which the queue size of sent -requests should be limited. -+ -On service side: the IP of the offered service for which the queue size for -sent responses should be limited. This IP address is therefore -identical to the IP address specified via `unicast` setting on top level of the -json file. - -** `ports` (array) -+ -Array which holds pairs of port and queue size statements. - -*** `port` -+ -On client side: the port of the remote service for which the queue size of sent -requests should be limited. -+ -On service side: the port of the offered service for which the queue size for -send responses should be limited. - -*** `queue-size-limit` -+ -On client side: the queue size limit in bytes of messages sent to the -remote service hosted on beforehand specified IP and port. -+ -On service side: the queue size limit in bytes for responses sent by the service -offered on previously specified IP and port. -+ -If multiple services are hosted on the same port they all share the limit -specified. - -* `endpoint-queue-limit-external` -+ -Setting to limit the maximum allowed size in bytes of cached outgoing messages -for external communication (message queue size per endpoint). By default the -queue size for external communication is unlimited. It can be limited via this -setting. Settings done in the `endpoint-queue-limits` array override this -setting. - -* `endpoint-queue-limit-local` -+ -Setting to limit the maximum allowed size in bytes of cached outgoing messages -for local communication (message queue size per endpoint). By default the queue -size for node internal communication is unlimited. It can be limited via this -setting. - -* `buffer-shrink-threshold` -+ -The number of processed messages which are half the size or smaller than the -allocated buffer used to process them before the memory for the buffer is -released and starts to grow dynamically again. This setting can be useful in -scenarios where only a small number of the overall messages are a lot bigger -then the rest and the memory allocated to process them should be released in a -timely manner. If the value is set to zero the buffer sizes aren't reseted and -are as big as the biggest processed message. (default is 5) -+ -Example: `buffer-shrink-threshold` is set to 50. A message with 500 bytes has to -be processed and the buffers grow accordingly. After this message 50 consecutive -messages smaller than 250 bytes have to be processed before the buffer size is -reduced and starts to grow dynamically again. - -* `tcp-restart-aborts-max` -+ -Setting to limit the number of TCP client endpoint restart aborts due to unfinished TCP handshake. -After the limit is reached, a forced restart of the TCP client endpoint is done if the connection attempt is still pending. - -* `tcp-connect-time-max` -+ -Setting to define the maximum time until the TCP client endpoint connection attempt should be finished. -If `tcp-connect-time-max` is elapsed, the TCP client endpoint is forcely restarted if the connection attempt is still pending. - -* `udp-receive-buffer-size` -+ -Specifies the size of the socket receive buffer (`SO_RCVBUF`) used for -UDP client and server endpoints in bytes. (default: 1703936) - -* `internal_services` (optional array) -+ -Specifies service/instance ranges for pure internal service-instances. -This information is used by vsomeip to avoid sending Find-Service messages -via the Service-Discovery when a client is requesting a not available service- -instance. Its can either be done on service/instance level or on service level -only which then includes all instance from 0x0000-0xffff. - -** `first` -+ -The lowest entry of the internal service range. - -*** `service` -+ -The lowest Service-ID in hex of the internal service range. - -*** `instance` (optional) -+ -The lowest Instance-ID in hex of a internal service-instance range. -If not specified the lowest Instance-ID is 0x0000. - -** `last` -+ -The highest entry of the internal service range. - -*** `service` -+ -The highest Service-ID in hex of a internal service range. - -*** `instance` (optional) -+ -The highest Instance-ID in hex of a internal service-instance range. -If not specified the highest Instance-ID is 0xFFFF. - -* `debounce` (optional array) -+ -Events/fields sent by external devices will be forwarded to the -applications only if a configurable function evaluates to true. The -function checks whether the event/field payload has changed and whether -a specified interval has been elapsed since the last forwarding. - -** `service` -+ -Service ID which hosts the events to be debounced. - -** `instance` -+ -Instance ID which hosts the events to be debounced. - -** `events` -+ -Array of events which shall be debounced based on the following -configuration options. - -*** `event` -+ -Event ID. - -*** `on_change` -+ -Specifies whether the event is forwarded on -payload change or not. (valid values: _true_, _false_). -Default is _false_. - -*** `ignore` -+ -Array of payload indexes with given bit mask (optional) -to be ignored in payload change evaluation. -Instead of specifying an index / bitmask pair, one can only define the payload index -which shall be ignored in the evaluation. - -**** `index` -+ -Payload index to be checked with given bitmask. - -**** `mask` -+ -1Byte bitmask applied to byte at given payload index. -Example mask: 0x0f ignores payload changes in low nibble of the byte at given index. - -*** `interval` -+ -Specifies if the event shall be debounced based on elapsed time interval. -(valid values: _time in ms_, _never_). Default is _never_. - -*** `on_change_resets_interval` (optional) -Specifies if interval timer is reset when payload change was detected. -(valid values: _false_, _true_). Defaults to _false_. - -*** `send_current_value_after` (optional) -Specifies if last message should be sent after interval timeout. -(valid values: _false_, _true_). Defaults to _false_. - -* `routing` (optional) -+ -Specifies the properties of the routing. Either a string that specifies the application that hosts the -routing component or a structure that specifies all properties of the routing. If the routing is not -specified, the first started application will host the routing component. - -** `host` -+ -Properties of the routing manager. - -*** `name` -+ -Name if the application that hosts the routing component. - -*** `uid` -+ -User identifier of the process that runs the routing component. Must be specified if credential checks -are enabled by _check_credentials_ set to true. - -*** `gid` -+ -Group identifier of the process that runs the routing component. Must be specified if credential checks -are enabled by _check_credentials_ set to true. - -*** `unicast` (optional) -+ -The unicast address that shall be used by the routing manager, if the internal communication shall be done -by using TCP connections. - -*** `port` (optional) -+ -The port that shall be used by the routing manager, if the internal communication shall be done -by using TCP connections. - -** `guests` (optional) -+ -Properties of all applications that do not host the routing component, if the internal communication shall be -done using TCP connections. - -*** `unicast` -+ -The unicast address that shall be used by the applications to connect to the routing manager. - -*** `ports` -+ -A set of port ranges that shall be used to connect to the routing manager per user identifier/group identifier. -Either specify uid, gid and ranges, or only a set of port ranges. If uid and gid are not explicitly specified, -they default to any. Each client application requires two ports, one for receiving messages from other -applications and one to send messages to other applications. -+ -**** `uid` -+ -User identifier - -**** `gid` -+ -Group identifier - -**** `ranges` -+ -Set of port ranges. Each entry consists of a `first`, `last` pair that determines the first and the last port -of a port range. -+ -***** `first` -+ -First port of a port range -+ -***** `last` -+ -Last port of a port range -+ -NOTE: Each configured port range must contain an even number of ports. If an even port number is configured -to be the routing host port, the first port in the range must also be even. If an uneven port number is -configured to be the routing host port, the first port in the range must also be uneven. - -* `routing-credentials` (deprecated) -+ -The UID / GID of the application acting as routing manager. -(Must be specified if credentials checks are enabled using _check_credentials_ set to _true_ in order to successfully check the routing managers credentials passed on connect) - -** `uid` -+ -The routing managers UID. - -** `gid` -+ -The routing managers GID. - -* `shutdown_timeout` -+ -Configures the time in milliseconds local clients wait for acknowledgement of -their deregistration from the routing manager during shutdown. Defaults to -5000ms. - -* `warn_fill_level` -+ -The routing manager regulary checks the fill level of the send buffers to its -clients. This variable defines the minimum fill level in percent that leads to -a warning being logged. Defaults to 67. - -* `service-discovery` -+ -Contains settings related to the Service Discovery of the host application. - -** `enable` -+ -Specifies whether the Service Discovery is enabled (valid values: _true_, -_false_). The default value is _true_. - -** `multicast` -+ -The multicast address which the messages of the Service Discovery will be sent -to. The default value is _224.0.0.1_. - -** `port` -+ -The port of the Service Discovery. The default setting is _30490_. - -** `protocol` -+ -The protocol that is used for sending the Service Discovery messages (valid -values: _tcp_, _udp_). The default setting is _udp_. - -** `initial_delay_min` -+ -Minimum delay before first offer message. - -** `initial_delay_max` -+ -Maximum delay before first offer message. - -** `repetitions_base_delay` -+ -Base delay sending offer messages within the repetition phase. - -** `repetitions_max` -+ -Maximum number of repetitions for provided services within the -repetition phase. - -** `ttl` -+ -Lifetime of entries for provided services as well as consumed services and eventgroups. - -** `ttl_factor_offers` (optional array) -+ -Array which holds correction factors for incoming remote offers. If a value -greater than one is specified for a service instance, the TTL field of the -corresponding service entry will be multiplied with the specified factor. + -Example: An offer of a service is received with a TTL of 3 sec and the TTL -factor is set to 5. The remote node stops offering the service w/o sending a -StopOffer message. The service will then expire (marked as unavailable) 15 seconds -after the last offer has been received. - -*** `service` -+ -The id of the service. - -*** `instance` -+ -The id of the service instance. - -*** `ttl_factor` -+ -TTL correction factor - -** `ttl_factor_subscriptions` (optional array) -+ -Array which holds correction factors for incoming remote subscriptions. If a -value greater than one is specified for a service instance, the TTL field of the -corresponding eventgroup entry will be multiplied with the specified factor. + -Example: A remote subscription to an offered service is received with a TTL of 3 -sec and the TTL factor is set to 5. The remote node stops resubscribing to the -service w/o sending a StopSubscribeEventgroup message. The subscription will -then expire 15 seconds after the last resubscription has been received. - -*** `service` -+ -The id of the service. - -*** `instance` -+ -The id of the service instance. - -*** `ttl_factor` -+ -TTL correction factor - -** `cyclic_offer_delay` -+ -Cycle of the OfferService messages in the main phase. - - -** `request_response_delay` -+ -Minimum delay of a unicast message to a multicast message for -provided services and eventgroups. -+ - -** `offer_debounce_time` -+ -Time which the stack collects new service offers before they enter the -repetition phase. This can be used to reduce the number of -sent messages during startup. The default setting is _500ms_. -+ -//Suppress Event Logs -+ -* 'suppress_missing_event_logs' -+ -Used to filter the log message `deliver_notification: Event [1234.5678.80f3] -is not registered. The message is dropped.` that occurs whenever vSomeIP -receives an event without having a corresponding object being registered. - -[source, bash] ----- -... -"suppress_missing_event_logs" : -[ - { - "service" : "0x0023", - "instance" : "0x0001", - "events" : [ "0x8001", "0x8002", - { - "first" : "0x8010", - "last" : "0x801f" - }, - "0x8020" ] - }, - { - "service" : "0x0023", - "instance" : "0x0002", - "events" : [ "0x8005", "0x8006" ] - }, - { - "service" : "0x0023", - "instance" : "0x0002", - "events" : [ "0x8105", "0x8106" ] - }, - { - // no "events" --> ignore all(!) events of these services - "service" : "any", - "instance" : "0x00f2" - }, - { - "service" : "0x0102", - "instance" : "any", - "events" : [ "0x8005", "0x8006" ] - } -] - -//Watchdog -* anchor:config-watchdog[]`watchdog` (optional) -+ -The Watchdog sends periodically pings to all known local clients. -If a client isn't responding within a configurred time/amount of pongs -the watchdog deregisters this application/client. -If not configured the watchdog isn't activated. -+ -** `enable` -+ -Specifies whether the watchdog is enabled or disabled. -(valid values: _true, false_), (default is _false_). -+ -** `timeout` -+ -Specifies the timeout in ms the watchdog gets activated if a ping -isn't answered with a pong by a local client within that time. -(valid values: _2 - 2^32_), (default is _5000_ ms). -+ -** `allowed_missing_pongs` -+ -Specifies the amount of allowed missing pongs. -(valid values: _1 - 2^32_), (default is _3_ pongs). -+ -//CAPI-Selective Broadcasts support -* anchor:config-supports_selective_broadcasts[]`supports_selective_broadcasts` (optional array) -+ -This nodes allow to add a list of IP addresses on which CAPI-Selective-Broadcasts feature is supported. -If not specified the feature can't be used and the subscription behavior of the stack is same as with -normal events. -+ -** `address` -+ -Specifies an IP-Address (in IPv4 or IPv6 notation) on which the "selective"-feature is supported. -Multiple addresses can be configured. - -Security --------- -vsomeip has a security implementation based on UNIX credentials. -If activated every local connection is authenticated during connect using the standard UNIX credential passing mechanism. -During authentication a client transfers its client identifier together with its credentials (UID / GID) to the server which is then matched against the configuration. -If received credentials don't match the policy the socket will be immediately closed by the server and an message is logged. -If accepted the client identifier is bound to the receiving socket and can therefore be used to do further security checks on incoming messages (vsomeip messages as well as internal commands). - -In general clients can be configured to be allowed/denied to request (means communicate with) and offer different service instances. -Every incoming vsomeip message (request/response/notification) as well as offer service requests or local subscriptions are then checked against the policy. -If an incoming vsomeip message or another operation (e.g. offer/subscribe) violates the configured policies it is skipped and a message is logged. - -Furthermore if an application receives informations about other clients/services in the system, it must be received from the authenticated routing manager. -This is to avoid malicious applications faking the routing manager and therefore being able to wrongly inform other clients about services running on the system. -Therefore, whenever the "security" tag is specified, the routing manager (e.g. routingmanagerd/vsomeipd) must be a configured application with a fixed client identifier. -See chapter "Configuration File Structure" on how to configure an application to use a specific client identifier. - -Credential passing is only possible via Unix-Domain-Sockets and therefore only available for local communication. -However if security is activated method calls from remote clients to local services are checked as well which means remote clients needs to be explicitly allowed. -Such a policy looks same in case for local clients except the _credentials_ tag can be skipped. - -Security configuration -~~~~~~~~~~~~~~~~~~~~~~ -The available configuration switches for the security feature are: - -// Security -* anchor:config-policy[]`security` (optional) -+ -NOTE: As long as no _security_ node exists, the security implementation is switched off. This also means, -no external security library will be loaded and used. -+ -If specified the credential passing mechanism is activated. However no credential or security checks are done as long as -_check_credentials_ isn't set to _true_, but the routing manager client ID must be configured if security tag is specified. -If _check_credentials_ is set to _true_, the routing managers UID and GID needs to be specified using _routing-credentials_ tag. - -** `check_credentials` (optional) -+ -Specifies whether security checks are active or not. This includes credentials checks on connect as well as all policies checks configured in follow. -(valid values: _true, false_), (default is _false_). - -** `allow_remote_clients` (optional) -+ -Specifies whether incoming remote requests / subscriptions are allowed to be sent to a local proxy / client. -If not specified, all remote requests / subscriptions are allowed to be received by default. -(valid values are 'true' and 'false') - -** `policies` (array) -+ -Specifies the security policies. Each policy at least needs to specify _allow_ or _deny_. - -*** `credentials` -+ -Specifies the credentials for which a security policy will be applied. -If _check_credentials_ is set to _true_ the credentials of a local application needs to be specified correctly to ensure local socket authentication can succeed. - -**** `uid` -+ -Specifies the LINUX user id of the client application as decimal number. -As a wildcard "any" can be used. - -**** `gid` -+ -Specifies the LINUX group id of the client application as decimal number. -As a wildcard "any" can be used. - -**** `allow` / `deny` (optional) -+ -Specifies whether the LINUX user and group ids are allowed or denied for the policy. - -. `uid` (array) -+ -Specifies a list of LINUX user ids. These may either be specified as decimal numbers or as ranges. Ranges -are specified by the first and the last valid id (see example below). - -. `gid` (array) -+ -Specifies a list of LINUX group ids. These may either be specified as decimal numbers or as ranges. Ranges -are specified by the first and the last valid id (see example below). - -*** `allow` / `deny` -+ -This tag specifies either _allow_ or _deny_ depending on white- or blacklisting is needed. Specifing _allow_ and _deny_ entries in one policy is therefore not allowed. -With _allow_ a whitelisting of what is allowed can be done which means an empty _allow_ tag implies everything is denied. -With _deny_ a blacklisting of what is allowed can be done which means an empty _deny_ tag implies everything is allowed. - -**** `requests` (array) -+ -Specifies a set of service instance pairs which the above client application using the credentials above is allowed/denied to communicate with. - -. `service` -+ -Specifies a service for the _requests_. - -. `instance` (deprecated) -+ -Specifies a instance for the _requests_ -As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF -which also implies a method ID range from 0x01 to 0xFFFF. - -. `instances` (array) -+ -Specifies a set of instance ID and method ID range pairs which are allowed/denied to communicate with. -If the `ids` tag below is not used to specify allowed/denied requests on method ID level one can also -only specify a a set of instance ID ranges which are allowed/denied to be requested analogous to the -allowed/denied `offers` section. -If no method IDs are specified, the allowed/denied methods are by default a range from 0x01 to 0xFFFF. - -.. `ids` -+ -Specifies a set of instance ID ranges which are allowed/denied to communicate with. -It is also possible to specify a single instance ID as array element without giving an upper / lower range bound. -As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF. -+ -`first` - The lower bound of the instance range. -+ -`last` - The upper bound of the instance range. - -.. `methods` -+ -Specifies a set of method ID ranges which are allowed/denied to communicate with. -It is also possible to specify a single method ID as array element without giving an upper / lower range bound. -As a wildcard "any" can be used which means a range from method ID 0x01 to 0xFFFF. -+ -`first` - The lower bound of the method range. -+ -`last` - The upper bound of the method range. - -**** `offers` (array) -+ -Specifies a set of service instance pairs which are allowed/denied to be offered by the client application using the credentials above. - -. `service` -+ -Specifies a service for the _offers_. - -. `instance` (deprecated) -+ -Specifies a instance for the _offers_ -As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF. - -. `instances` (array) -+ -Specifies a set of instance ID ranges which are allowed/denied to be offered by the client application using the credentials above. -It is also possible to specify a single instance ID as array element without giving an upper / lower range bound. -As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF. - -.. `first` -+ -The lower bound of the instance range. - -.. `last` -+ -The upper bound of the instance range. - -<<< - -Security configuration example -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -[source, bash] ----- -... -"security" : -{ - ... - "policies" : - [ - { - ... - "credentials" : - { - "uid" : "44", - "gid" : "any" - }, - "allow" : - [ - "requests" : - [ - { - "service" : "0x6731", - "instance" : "0x0001" - } - ] - ] - }, - { - "credentials" : - { - "deny" : - [ - { - "uid" : [ "1000", { "first" : "1002", "last" : "max" }], - "gid" : [ "0", { "first" : "100", "last" : "243" }, "300"] - }, - { - "uid" : ["55"], - "gid" : ["55"] - } - ] - }, - "allow" : - [ - "offers" : - [ - { - "service" : "0x6728", - "instances" : [ "0x0001", { "first" : "0x0003", "last" : "0x0007" }, "0x0009"] - }, - { - "service" : "0x6729", - "instances" : ["0x88"] - }, - { - "service" : "0x6730", - "instance" : "any" - } - ], - "requests" : - [ - { - "service" : "0x6732", - "instances" : - [ - { - "ids" : [ "0x0001", { "first" : "0x0003", "last" : "0x0007" }], - "methods" : [ "0x0001", "0x0003", { "first" : "0x8001", "last" : "0x8006" } ] - }, - { - "ids" : [ "0x0009" ], - "methods" : "any" - } - ] - }, - { - "service" : "0x6733", - "instance" : "0x1" - }, - { - "service" : "0x6733", - "instances" : [ "0x0002", { "first" : "0x0003", "last" : "0x0007" }, "0x0009"] - } - ] - ] - } - ] -} ----- - -The config/ folder contains some addition vsomeip configuration files to run the vsomeip -examples with activated security checks. -Additionally there's a security test in the `test/` subfolder which can be used -for further reference. + -They give a basic overview how to use the security related configuration tags described -in this chapter to run a simple request/response or subscribe/notify example locally or -remotely. - - -Security policy extensions -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -vsomeip policy extension configuration supports the definition of paths that contain additional -security policies to be loaded whenever a client with a yet unknown hostname connects to a local server endpoint. -The following configuration parameters are available and can be defined in a file named `vsomeip_policy_extensions.json`. - -// Security policy extension -* anchor:config-policy-extension[]`container_policies` (optional array) -+ -Specifies the additional configuration folders to be loaded for each container hostname / filesystem path pair. - -** `container` -+ -Specifies the linux hostname. - -** `path` -+ -Specifies a filesystem path (relative to vsomeip_policy_extensions.json or absolute) which contains -$UID_$GID subfolders that hold a `vsomeip_security.json` file. -+ -NOTE: ($UID / $GID is the UID /GID of the vsomeip client application -to which a client from hostname defined with `container`connetcs to. - - -Audit Mode -~~~~~~~~~~ -vsomeip's security implementation can be put in a so called 'Audit Mode' where -all security violations will be logged but allowed. This mode can be used to -build a security configuration. - -To activate the 'Audit Mode' the 'security' object has to be included in the -json file but the 'check_credentials' switch has to be set to false. For -example: - -[source, bash] ----- - [...] - "services" : - [ - [...] - ], - "security" : - { - "check_credentials" : "false" - }, - "routing" : "service-sample", - [...] ----- - -Autoconfiguration ------------------ -vsomeip supports the automatic configuration of client identifiers and the routing. -The first application that starts using vsomeip will automatically become the -routing manager if it is _not_ explicitly configured. The client identifiers -are generated from the diagnosis address that can be specified by defining -DIAGNOSIS_ADDRESS when compiling vsomeip. vsomeip will use the diagnosis address -as the high byte and enumerate the connecting applications within the low byte -of the client identifier. - -Autoconfiguration of client identifiers isn't meant to be used together with vsomeip Security. -Every client running locally needs to have at least its own credentials configured when security is activated to ensure the credential checks can pass. -Practically that means if a client requests its identifier over the autoconfiguration for which no credentials are configured (at least it isn't known which client identifier is used beforehand) it is impossible for that client to establish a connection to a server endpoint. -However if the credentials for all clients are same it's possible to configure them for the overall (or DIAGNOSIS_ADDRESS) client identifier range to mix autoconfiguration together with activated security. - -routingmanagerd ---------------- -The routingmanagerd is a minimal vsomeip application intended to offer routing -manager functionality on a node where one system wide configuration file is -present. It can be found in the examples folder. - -Example: Starting the daemon on a system where the system wide configuration is -stored under `/etc/vsomeip.json`: -[source, bash] ----- -VSOMEIP_CONFIGURATION=/etc/vsomeip.json ./routingmanagerd ----- - -When using the daemon it should be ensured that: - -* In the system wide configuration file the routingmanagerd is defined as - routing manager, meaning it contains the line `"routing" : "routingmanagerd"`. - If the default name is overridden the entry has to be adapted accordingly. - The system wide configuration file should contain the information about all - other offered services on the system as well. -* There's no other vsomeip configuration file used on the system which contains - a `"routing"` entry. As there can only be one routing manager per system. - - -vsomeip Hello World -------------------- -In this paragraph a Hello World program consisting out of a client and a service -is developed. The client sends a message containing a string to the service. -The service appends the received string to the string `Hello` and sends it back -to the client. -Upon receiving a response from the service the client prints the payload of the -response ("Hello World"). -This example is intended to be run on the same host. - -All files listed here are contained in the `examples\hello_world` subdirectory. - -Build instructions -~~~~~~~~~~~~~~~~~~ -The example can build with its own CMakeFile, please compile the vsomeip stack -before hand as described in <>. Then compile the example starting -from the repository root directory as followed: -[source, bash] ----- -cd examples/hello_world -mkdir build -cd build -cmake .. -make ----- - -Starting and expected output -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Starting and expected output of service -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -[source, bash] ----- -$ VSOMEIP_CONFIGURATION=../helloworld-local.json \ - VSOMEIP_APPLICATION_NAME=hello_world_service \ - ./hello_world_service -2015-04-01 11:31:13.248437 [info] Using configuration file: ../helloworld-local.json -2015-04-01 11:31:13.248766 [debug] Routing endpoint at /tmp/vsomeip-0 -2015-04-01 11:31:13.248913 [info] Service Discovery disabled. Using static routing information. -2015-04-01 11:31:13.248979 [debug] Application(hello_world_service, 4444) is initialized. -2015-04-01 11:31:22.705010 [debug] Application/Client 5555 got registered! ----- - -Starting and expected output of client -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -[source, bash] ----- -$ VSOMEIP_CONFIGURATION=../helloworld-local.json \ - VSOMEIP_APPLICATION_NAME=hello_world_client \ - ./hello_world_client -2015-04-01 11:31:22.704166 [info] Using configuration file: ../helloworld-local.json -2015-04-01 11:31:22.704417 [debug] Connecting to [0] at /tmp/vsomeip-0 -2015-04-01 11:31:22.704630 [debug] Listening at /tmp/vsomeip-5555 -2015-04-01 11:31:22.704680 [debug] Application(hello_world_client, 5555) is initialized. -Sending: World -Received: Hello World ----- - -CMakeFile -~~~~~~~~~ - -[source, bash] ----- -include::../examples/hello_world/CMakeLists.txt[] ----- - -Configuration File For Client and Service -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -[source, bash] ----- -include::../examples/hello_world/helloworld-local.json[] ----- - -Service -~~~~~~~ - -[source, bash] ----- -include::../examples/hello_world/hello_world_service_main.cpp[] ----- - -The service example results in the following program execution: - -:numbered!: - -[float] - -Main -^^^^^ - -. __main()__ -+ -First the application is initialized. After the initialization is -finished the application is started. - -[float] -Initialization -^^^^^^^^^^^^^^ - -[start=2] -. __init()__ -+ -The initialization contains the registration of a message -handler and an event handler. -+ -The message handler declares a callback (__on_message_cbk__) for messages that -are sent to the specific service (specifying the service id, the service -instance id and the service method id). -+ -The event handler declares a callback (__on_event_cbk__) for events that occur. -One event can be the successful registration of the application at the runtime. - -[float] -Start -^^^^^ - -[start=3] -. __start()__ -+ -The application will be started. This function only returns when the application -will be stopped. - -[float] -Callbacks -^^^^^^^^^ - -[start=4] -. __on_state_cbk()__ -+ -This function is called by the application when an state change occurred. If -the application was successfully registered at the runtime then the specific -service is offered. - -. __on_message_cbk()__ -+ -This function is called when a message/request from a client for the specified -service was received. -+ -First a response based upon the request is created. -Afterwards the string 'Hello' will be concatenated with the payload of the -client's request. -After that the payload of the response is created. The payload data is set with -the previously concatenated string. -Finally the response is sent back to the client and the application is stopped. - -[float] -Stop -^^^^ - -[start=6] -. __stop()__ -+ -This function stops offering the service, unregister the message and the event -handler and shuts down the application. - -:numbered: - -Client -~~~~~~ -[source, bash] ----- -include::../examples/hello_world/hello_world_client_main.cpp[] ----- - -The client example results in the following program execution: - -:numbered!: - -[float] -Main -^^^^^ - -. __main()__ -+ -First the application is initialized. After the initialization is finished the -application is started. - -[float] -Initialization -^^^^^^^^^^^^^^ - -[start=2] -. __init()__ -+ -The initialization contains the registration of a message handler, an event -handler and an availability handler. -+ -The event handler declares again a callback (__on_state_cbk__) for state changes -that occur. -+ -The message handler declares a callback (__on_message_cbk__) for messages that -are received from any service, any service instance and any method. -+ -The availability handler declares a callback (__on_availability_cbk__) which is -called when the specific service is available (specifying the service id and the -service instance id). - -[float] -Start -^^^^^ - -[start=3] -. __start()__ -+ -The application will be started. This function only returns when the application -will be stopped. - -[float] -Callbacks -^^^^^^^^^ - -[start=4] -. __on_state_cbk()__ -+ - -This function is called by the application when an state change occurred. If the -application was successfully registered at the runtime then the specific service -is requested. - -. __on_availability_cbk()__ -+ -This function is called when the requested service is available or no longer -available. -+ -First there is a check if the change of the availability is related to the -'hello world service' and the availability changed to true. -If the check is successful a service request is created and the appropriate -service information are set (service id, service instance id, service method -id). -After that the payload of the request is created. The data of the payload is -'World' and will be set afterwards. -Finally the request is sent to the service. - -. __on_message_cbk()__ -+ -This function is called when a message/response was received. -If the response is from the requested service, of type 'RESPONSE' and the return -code is 'OK' then the payload of the response is printed. Finally the -application is stopped. - -[float] -Stop -^^^^ - -[start=7] -. __stop()__ -+ -This function unregister the event and the message handler and shuts down the -application. - -:numbered: - -Trace Connector ---------------- -anchor:traceconnector[] - -Overview/Prerequisites -~~~~~~~~~~~~~~~~~~~~~~ - -The Trace Connector is used to forward the internal messages that are sent over -the Unix Domain Sockets to DLT. + -Thus, it requires that DLT is installed and the DLT module can be found in the -context of CMake. - -Configuration -~~~~~~~~~~~~~ - -Static Configuration -^^^^^^^^^^^^^^^^^^^^ - -The Trace Connector can be configured statically over the -<>. + - -[float] -Example 1 (Minimal Configuration) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -[source, bash] ----- -{ - ... - - "tracing" : - { - "enable" : "true" - }, - - ... ----- - -This is the minimal configuration of the Trace Connector. This just enables the -tracing and all of the sent internal messages will be traced/forwarded to DLT. - -[float] -Example 2 (Using Filters) -^^^^^^^^^^^^^^^^^^^^^^^^^ - -[source, bash] ----- -{ - ... - - "tracing" : - { - "enable" : "true", - "channels" : - [ - { - "name" : "My channel", - "id" : "MC" - } - ], - "filters" : [ - { - "channel" : "MC", - "matches" : [ { "service" : "0x1234", "instance" : "any", "method" : "0x80e8" } ], - "type" : "positive" - } - ] - }, - - ... ----- - -As it is a positive filter, the example filter ensures that only messages -representing method '0x80e8' from instances of service '0x1234' will be -forwarded to the DLT. If it was specified as a negative filter, all messages -except messages representing method '0x80e8' from instances of service -'0x1234' would be forwarded to the DLT. - -The general filter rules are: - -* The default filter is a positive filter for all messages. -* The default filter is active on a channel as long as no other positive -filter is specified. -* Negative filters block matching messages. Negative filters overrule -positive filters. Thus, as soon as a messages matches a negative filter it -will not be forwarded. -* The identifier '0xffff' is a wildcard that matches any service, instance or method. -The keyword 'any' can be used as a replacement for '0xffff'. -* Wildcards must not be used within range filters. - -Dynamic Configuration -^^^^^^^^^^^^^^^^^^^^^ - -The Trace Connector can also be configured dynamically over its interfaces. -You need to include '' to access its public interface. - -[float] -Example: -^^^^^^^^ - -[source, bash] ----- - // get trace connector - std::shared_ptr its_connector - = vsomeip::trace::connector::get(); - - // add channel - std::shared_ptr its_channel - = its_connector->create_channel("MC", "My channel"); - - // add filter rule - vsomeip::trace::match_t its_match - = std::make_tuple(0x1234, 0xffff, 0x80e8); - vsomeip::trace::filter_id_t its_filter_id - = its_channel->add_filter(its_match, true); - - // init trace connector - its_connector->init(); - - // enable trace connector - its_connector->set_enabled(true); - - // remove the filter - its_channel->remove_filter(its_filter_id); ----- - -anchor:npdu[] - -vsomeip nPDU feature ------------------- - -This is the add-on documentation for the nPDU feature, aka. _Zugverfahren_. - -The nPDU feature can be used to reduce network load as it enables the vsomeip -stack to combine multiple vsomeip messages in one single ethernet frame. - -Some general _important_ things regarding the nPDU feature first: - -* Due to its nature the nPDU feature trades lower network load for speed. -* As the nPDU feature requires some settings which are not transmitted -through the service discovery, it's *not* sufficient anymore to have an json -file without a "services" section on the client side. -* As the client- and server-endpoints of a node are managed by the routing - manager (which is the application entered at "routing" in the json file) - the nPDU feature settings *always* have to be defined in the json file used by - the application acting as routing manager. -* The nPDU feature timings are defined in milliseconds. -* Node internal communication over UNIX domain sockets is not affected by the - nPDU feature. -* If the debounce times configuration for a method in the json file is missing - or incomplete the default values are used: 2ms debounce time and 5ms max - retention time. The global default values can be overwritten via the - `npdu-default-timings` json object. - -Configuration -~~~~~~~~~~~~~ -There are two parameters specific for the nPDU feature: - -* *debounce time*: minimal time between sending a message to the same method of - a remote service over the same connection (src/dst address + src/dst port). -* *max retention time*: the maximum time which a message to the same method of a - remote service over the same connection (src/dst address + src/dst port) is - allowed to be buffered on sender side. - -For more information please see the corresponding requirement documents. - - -The nPDU feature specific settings are configured in the json file in the -"services" section on service level in a special _debounce-times_ section: - -[source, bash] ----- -[...] -"services": -[ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30509", - "debounce-times": - { - // nPDU feature configuration for this - // service here - } - } -], -[...] ----- - -Additionally nPDU default timings can be configured globally. - -The global default timings can be overwritten via the `npdu-default-timings` -json object. For example the following configuration snippet shows how to set -all default timings to zero: - -[source, bash] ----- -{ - "unicast":"192.168.1.9", - [...] - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing":"[...]", - "service-discovery": { [...] } -} ----- - - -Example 1: One service with one method offered over UDP -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* The service is hosted on IP: 192.168.1.9. -* The service is offered on port 30509 via UDP. -* The service has the ID 0x1000 -* The method has the ID 0x0001 -* The client accesses the service from IP: 192.168.1.77 - -Service side -++++++++++++ - -* Debounce time for responses should have a: -** debounce time of 10 milliseconds -** maximum retention time of 100 milliseconds - -[source, bash] ----- -{ - "unicast":"192.168.1.9", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30509", - "debounce-times": - { - "responses": { - "0x1001" : { - "debounce-time":"10", - "maximum-retention-time":"100" - } - } - } - } - ], - "routing":"[...]", - "service-discovery": { [...] } -} ----- -Client side -++++++++++++ - -* Debounce time for requests to the service on 192.168.1.9 should have a: -** debounce time of 20 milliseconds -** maximum retention time of 200 milliseconds - -[source, bash] ----- -{ - "unicast":"192.168.1.77", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unicast":"192.168.1.9", // required to mark service as external - "unreliable":"30509", - "debounce-times": - { - "requests": { - "0x1001" : { - "debounce-time":"20", - "maximum-retention-time":"200" - } - } - } - } - ], - "routing":"[...]", - "service-discovery": { [...] } -} ----- - -Example 2: One service with two methods offered over UDP -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* The service is hosted on IP: 192.168.1.9. -* The service is offered on port 30509 via UDP. -* The service has the ID 0x1000 -* The method has the ID 0x0001 -* The second method has the ID 0x0002 -* The client accesses the service from IP: 192.168.1.77 - -Service side -++++++++++++ - -* Debounce time for responses should have a: -** debounce time of 10 milliseconds for method 0x1001 and 20 for 0x1002 -** maximum retention time of 100 milliseconds for method 0x1001 and 200 for 0x1002 - -[source, bash] ----- -{ - "unicast":"192.168.1.9", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30509", - "debounce-times": - { - "responses": { - "0x1001" : { - "debounce-time":"10", - "maximum-retention-time":"100" - }, - "0x1002" : { - "debounce-time":"20", - "maximum-retention-time":"200" - } - } - } - } - ], - "routing":"[...]", - "service-discovery": { [...] } -} ----- -Client side -++++++++++++ - -* Debounce time for requests to the service on 192.168.1.9 should have a: -** debounce time of 20 milliseconds for method 0x1001 and 40 for 0x1002 -** maximum retention time of 200 milliseconds for method 0x1001 and 400 for 0x1002 - -[source, bash] ----- -{ - "unicast":"192.168.1.77", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unicast":"192.168.1.9", // required to mark service as external - "unreliable":"30509", - "debounce-times": - { - "requests": { - "0x1001" : { - "debounce-time":"20", - "maximum-retention-time":"200" - }, - "0x1002" : { - "debounce-time":"40", - "maximum-retention-time":"400" - } - } - } - } - ], - "routing":"[...]", - "service-discovery": { [...] } -} ----- - -Example 3: One service with one method offered over UDP and TCP -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* The service is hosted on IP: 192.168.1.9. -* The service is offered on port 30509 via UDP. -* The service is offered on port 30510 via TCP. -* The service has the ID 0x1000 -* The method has the ID 0x0001 -* The client accesses the service from IP: 192.168.1.77 - -Service side -++++++++++++ - -* Debounce time for responses should have a: -** debounce time of 10 milliseconds -** maximum retention time of 100 milliseconds -** TCP should use the same settings as UDP - -[source, bash] ----- -{ - "unicast":"192.168.1.9", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times": - { - "responses": { - "0x1001" : { - "debounce-time":"10", - "maximum-retention-time":"100", - } - } - } - } - ], - "routing":"[...]", - "service-discovery": { [...] } -} ----- -Client side -++++++++++++ - -* Debounce time for requests to the service on 192.168.1.9 should have a: -** debounce time of 20 milliseconds -** maximum retention time of 200 milliseconds -** TCP should use the same settings as UDP - -[source, bash] ----- -{ - "unicast":"192.168.1.77", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unicast":"192.168.1.9", // required to mark service as external - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times": - { - "requests": { - "0x1001" : { - "debounce-time":"20", - "maximum-retention-time":"200", - } - } - } - } - ], - "routing":"[...]", - "service-discovery": { [...] } -} ----- - - -anchor:someiptp[] - -SOME/IP TP ----------- -With SOME/IP Transport Protocol (TP) it is possible to transport messages which -exceed the UDP payload size limit of 1400 byte. If enabled the message is -segmented and send in multiple UDP datagrams. - -Example configuration: - -* Service 0x1111/0x1 is hosted on 192.168.0.1 on UDP port 40000 -* Client is running on 192.168.0.100 -* The service has two methods with ID: 0x1 and 0x2 which require large requests - and large responses. Additionally the service offers a field with ID 0x8001 - which requires a large payloads as well. -* The maximum payload size on service side should be limited to 5000 bytes. - -Configuration service side: -[source, bash] ----- -{ - "unicast":"192.168.0.1", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x1", - "unreliable":"40000", - "someip-tp": { - "service-to-client": [ - "0x1", "0x2", "0x8001" - ] - } - } - ], - "max-payload-size-unreliable" : "5000", - "routing":"[...]", - "service-discovery": { [...] } -} ----- - -Configuration client side: - -[source, bash] ----- -{ - "unicast":"192.168.0.100", - "logging": { [...] }, - "applications": [ [...] ], - "services": - [ - { - "service":"0x1000", - "instance":"0x1", - "unicast":"192.168.0.1", // required to mark service as external - "unreliable":"40000", // required to mark service as external - "someip-tp": { - "client-to-service": [ - "0x1", "0x2" - ] - } - } - ], - "routing":"[...]", - "service-discovery": { [...] } -} ----- - -Tools ------ - -vsomeip_ctrl -~~~~~~~~~~~~ -anchor:vsomeip_ctrl[] -`vsomeip_ctrl` is a small utility which can be used to send SOME/IP messages -from the commandline. If a response arrives within 5 seconds the response will -be printed. - -* It can be build via `vsomeip_ctrl` make target (`make vsomeip_ctrl`). -* The instance id of the target service has to be passed in hexadecimal - notation. -* The complete message has to be passed in hexadecimal notation. -* See the `--help` parameter for available options. -* If `vsomeip_ctrl` is used to send messages to a remote service and no - `routingmanagerd` is running on the local machine, make sure to pass a json - configuration file where `vsomeip_ctrl` is set as routing manager via - environment variable. -* If `vsomeip_ctrl` is used to send messages to a local service and no - `routingmanagerd` is running on the local machine, make sure to use the same json - configuration file as the local service. - -Example: Calling method with method id 0x80e8 on service with service id 0x1234, -instance id 0x5678: -[source, bash] ----- -./vsomeip_ctrl --instance 5678 --message 123480e800000015134300030100000000000009efbbbf576f726c6400 ----- - -Example: Sending a message to service with service id 0x1234, instance id -0x5678 and method id 0x0bb8 via TCP -[source, bash] ----- -./vsomeip_ctrl --tcp --instance 5678 --message 12340bb8000000081344000101010000 ----- diff --git a/documentation/vsomeipUserGuide.md b/documentation/vsomeipUserGuide.md new file mode 100644 index 000000000..e2a3cc0df --- /dev/null +++ b/documentation/vsomeipUserGuide.md @@ -0,0 +1,2314 @@ +# Legal notice + +## Copyright +Copyright (C) 2015-2024, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + +## License + +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/. + +## Version + +This documentation was generated for version 3.5 of vSomeIP. + +# vSomeIP Overview + +The vSomeIP stack implements the http://some-ip.com/[Scalable service-Oriented +MiddlewarE over IP (SOME/IP)] protocol. The stack consists out of: + +* a shared library for SOME/IP (`libvsomeip.so`) +* a second shared library for SOME/IP's service discovery (`libvsomeip-sd.so`) + which is loaded during runtime if the service discovery is enabled. + +# Build Instructions + +## Dependencies + +* A C++17 enabled compiler is needed +* vSomeIP uses cmake as buildsystem. +* vSomeIP uses Boost >= 1.66: + * Ubuntu 22.04: + * `sudo apt-get install libboost-system1.74-dev libboost-thread1.74-dev libboost-log1.74-dev` +* For the tests Google's test framework + https://github.com/google/googletest/releases +* To build the documentation doxygen and graphviz are needed: + * `sudo apt-get install doxygen graphviz` + +## Compilation + +For compilation call: + +```bash +mkdir build +cd build +cmake .. +make +``` + +To specify a installation directory (like `--prefix=` if you're used to +autotools) call cmake like: + +```bash +cmake -DCMAKE_INSTALL_PREFIX:PATH=$YOUR_PATH .. +make +make install +``` + +### Compilation with predefined base path + +To predefine the base path, the path that is used to create the local sockets, +call cmake like: + +```bash +cmake -DBASE_PATH= .. +``` + +The default base path is /tmp. + +### Compilation with predefined unicast and/or diagnosis address + +To predefine the unicast address, call cmake like: + +```bash +cmake -DUNICAST_ADDRESS= .. +``` + +To predefine the diagnosis address, call cmake like: + +```bash +cmake -DDIAGNOSIS_ADDRESS= .. +``` + +The diagnosis address is a single byte value. + +### Compilation with custom default configuration folder + +To change the default configuration folder, call cmake like: + +```bash +cmake -DDEFAULT_CONFIGURATION_FOLDER= .. +``` + +The default configuration folder is /etc/vsomeip. + +### Compilation with custom default configuration file + +To change the default configuration file, call cmake like: + +```bash +cmake -DDEFAULT_CONFIGURATION_FILE= .. +``` + +The default configuration file is /etc/vsomeip.json. + +### Compilation with changed (maximimum) wait times for local TCP ports + +If local communication is done via TCP, we depend on the availability +of the network. Therefore, server port creation and therefore port +assignment might fail. If the failure is causes by the port already +being in use, we use the next available port. For all other failure, +we wait for a wait time until we retry with the same port. If the +overall wait time of all retries exceeds the maximum wait time, +the endpoint creation is aborted. To configure wait time and maximum +wait time, call cmake with: + +```bash +cmake -DLOCAL_TCP_PORT_WAIT_TIME=50 -DLOCAL_TCP_PORT_MAX_WAIT_TIME=2000 .. +``` + +The default values are a wait time of 100ms and a maximum wait time of 10000ms. +These configurations have no effect if local communication uses UDS (default). + +### Compilation with signal handling + +To compile vsomeip with signal handling (SIGINT/SIGTERM) enabled, +call cmake like: + +```bash +cmake -DENABLE_SIGNAL_HANDLING=1 .. +``` + +In the default setting, the application has to take care of shutting +down vsomeip in case these signals are received. + +### Compilation with user defined "READY" message + +To compile vsomeip with a user defined message signal the IP routing +to be ready to send/receive messages, call cmake like: + +```bash +cmake -DROUTING_READY_MESSAGE= .. +``` + + +### Compilation with vSomeIP 2 compatibility layer + +To compile vsomeip with enabled vSomeIP 2 compatibility layer, call +cmake like: + +```bash +cmake -DENABLE_COMPAT=1 .. +``` + +### Compilation of examples + +For compilation of the examples call: + +```bash +mkdir build +cd build +cmake .. +make examples +``` + +### Compilation of tests + +To compile the tests, first unzip gtest to location of your desire. +Some of the tests require a second node on the same network. There are two cmake +variables which are used to automatically adapt the json files to the used +network setup: + +* `TEST_IP_MASTER`: The IP address of the interface which will act as test + master. +* `TEST_IP_SLAVE`: The IP address of the interface of the second node which will + act as test slave. + +If one of this variables isn't specified, only the tests using local +communication exclusively will be runnable. + +Additionally the unit tests require enabled signal handling which can be enabled +via the `ENABLE_SIGNAL_HANDLING` cmake variable. + +Example, compilation of tests: + +```bash +mkdir build +cd build +export GTEST_ROOT=$PATH_TO_GTEST/gtest-1.7.0/ +cmake -DENABLE_SIGNAL_HANDLING=1 -DTEST_IP_MASTER=10.0.3.1 -DTEST_IP_SLAVE=10.0.3.125 .. +make check +``` + +Additional make targets for the tests: + +* Call `make build_tests` to only compile the tests +* Call `ctest` in the build directory to execute the tests without a verbose + output +* To run single tests call `ctest --verbose --tests-regex $TESTNAME` short + form: `ctest -V -R $TESTNAME` +* To list all available tests run `ctest -N`. +* For further information about the tests please have a look at the + `readme.txt` in the `test` subdirectory. + +For development purposes two cmake variables exist which control if the +json files and test scripts are copied (default) or symlinked into the build +directory. These settings are ignored on Windows. + +* `TEST_SYMLINK_CONFIG_FILES`: Controls if the json and scripts needed + to run the tests are copied or symlinked into the build directory. (Default: + OFF, ignored on Windows) +* `TEST_SYMLINK_CONFIG_FILES_RELATIVE`: Controls if the json and scripts needed + to run the tests are symlinked relatively into the build directory. + (Default: OFF, ignored on Windows) + +Example cmake call: + +```bash +cmake -DTEST_SYMLINK_CONFIG_FILES=ON -DTEST_SYMLINK_CONFIG_FILES_RELATIVE=ON .. +``` + +For compilation of only a subset of tests (for a quick +functionality check) the cmake variable `TESTS_BAT` has +to be set: + +Example cmake call: +```bash +cmake -DTESTS_BAT=ON .. +``` + +### Compilation of vsomeip_ctrl + +For compilation of the [vsomeip_ctrl](#vsomeip_ctrl) utility call: + +```bash +mkdir build +cd build +cmake .. +make vsomeip_ctrl +``` + +### Generating the documentation + +To generate the documentation call cmake as described in [Compilation](#compilation) and +then call `make doc`. +This will generate: + +* The README file in html: `$BUILDDIR/documentation/README.html` +* A doxygen documentation in `$BUILDDIR/documentation/html/index.html` + +# Starting vsomeip Applications / Used environment variables + +On startup the following environment variables are read out: + +* `VSOMEIP_APPLICATION_NAME`: This environment variable is used to specify the + name of the application. This name is later used to map a client id to the + application in the configuration file. It is independent from the + application's binary name. +* `VSOMEIP_CONFIGURATION`: vsomeip uses the default configuration file `/etc/vsomeip.json` + and/or the default configuration folder `/etc/vsomeip`. This can be overridden by a + local configuration file `./vsomeip.json` and/or a local configuration folder `./vsomeip`. + If `VSOMEIP_CONFIGURATION` is set to a valid file or directory path, this is used instead + of the standard configuration (thus neither default nor local file/folder will be parsed). +* `VSOMEIP_CONFIGURATION_`: Application-specific version of `VSOMEIP_CONFIGURATION`. + Please note that must be valid as part of an environment variable. +* `VSOMEIP_MANDATORY_CONFIGURATION_FILES`: vsomeip allows to specify mandatory configuration + files to speed-up application startup. While mandatory configuration files are read by all + applications, all other configuration files are only read by the application that is + responsible for connections to external devices. If this configuration variable is not set, + the default mandatory files vsomeip_std.json, vsomeip_app.json and vsomeip_plc.json are used. +* `VSOMEIP_CLIENTSIDELOGGING`: Set this variable to an empty string to enable logging of + any received messages to DLT in all applications acting as routing manager proxies. For + example add the following line to the application's systemd service file: + `Environment=VSOMEIP_CLIENTSIDELOGGING=""` + To enable service-specific logs, provide a space- or colon-separated list of ServiceIDs (using + 4-digit hexadecimal notation, optionally followed by dot-separted InstanceID). For example: + `Environment=VSOMEIP_CLIENTSIDELOGGING="b003.0001 f013.000a 1001 1002"` + `Environment=VSOMEIP_CLIENTSIDELOGGING="b003.0001:f013.000a:1001:1002"` + +NOTE: If the file/folder that is configured by `VSOMEIP_CONFIGURATION` does _not_ exist, +the default configuration locations will be used. + +NOTE: vsomeip will parse and use the configuration from all files in a configuration folder +but will _not_ consider directories within the configuration folder. + +In the following example the application `my_vsomeip_application` is started. +The settings are read from the file `my_settings.json` in the current working +directory. The client id for the application can be found under the name +`my_vsomeip_client` in the configuration file. + +```bash +#!/bin/bash +export VSOMEIP_APPLICATION_NAME=my_vsomeip_client +export VSOMEIP_CONFIGURATION=my_settings.json +./my_vsomeip_application +``` + +# Configuration File Structure + +The configuration files for vsomeip are [JSON](http://www.json.org)-Files and are +composed out of multiple key value pairs and arrays. + +> * An object is an unordered set of name/value pairs. An object begins with `{ +> (left brace)` and ends with `} (right brace)`. Each name is followed by `: +> (colon)` and the name/value pairs are separated by `, (comma)`. +> +> * An array is an ordered collection of values. An array begins with `[ (left +> bracket)` and ends with `] (right bracket)`. Values are separated by `, +> (comma)`. +> +> * A value can be a _string_ in double quotes, or a _number_, or `true` or `false` +> or `null`, or an _object_ or an _array_. These structures can be nested. + +Configuration file element explanation: + +* 'unicast' + + The IP address of the host system. + +* 'netmask' + + The netmask to specify the subnet of the host system. + +* 'device' (optional) + + If specified, IP endpoints will be bound to this device. + +* 'diagnosis' + + The diagnosis address (byte) that will be used to build client identifiers. The + diagnosis address is assigned to the most significant byte in all client + identifiers if not specified otherwise (for example through a predefined client + ID). + +* 'diagnosis_mask' + + The diagnosis mask (2 byte) is used to control the maximum amount of allowed + concurrent vsomeip clients on an ECU and the start value of the client IDs. + + The default value is `0xFF00` meaning + the most significant byte of the client ID is reserved for the diagnosis + address and the client IDs will start with the diagnosis address as specified. + The maximum number of clients is 255 as the Hamming weight of the inverted mask + is 8 (2^8 = 256 - 1 (for the routing manager) = 255). The resulting client ID + range with a diagnosis address of for example 0x45 would be 0x4501 to 0x45ff. + + Setting the mask to `0xFE00` doubles client ID range to 511 clients as the + Hamming weight of the inverted mask is greater by one. With a diagnosis address + of 0x45 the start value of client IDs is 0x4401 as bit 8 in 0x4500 is masked + out. This then yields a client ID range of 0x4400 to 0x45ff. + +* 'network' + Network identifier used to support multiple routing managers on one host. This + setting changes the name of the shared memory segment in `/dev/shm` and the name + of the unix domain sockets in `/tmp/`. Defaults to `vsomeip` meaning the shared + memory will be named `/dev/shm/vsomeip` and the unix domain sockets will be + named `/tmp/vsomeip-$CLIENTID` + +* 'logging' + * 'level' + + Specifies the log level (valid values: _trace_, _debug_, _info_, _warning_, + _error_, _fatal_). + + * 'console' + + Specifies whether logging via console is enabled (valid values: _true, false_). + + * 'file' + + * 'enable' + + Specifies whether a log file should be created (valid values: _true, false_). + * 'path' + + The absolute path of the log file. + + * 'dlt' + + Specifies whether Diagnostic Log and Trace (DLT) is enabled (valid values: + _true, false_). + + * 'version' + + Configures logging of the vsomeip version + + * 'enable' + + Enable or disable cyclic logging of vsomeip version, defaults to true (valid + values: _true, false_) + + * 'interval' + + Configures interval in seconds to log the vsomeip version. Default value is 10. + + * 'memory_log_interval' + + Configures interval in seconds in which the routing manager logs its used + memory. Setting a value greater than zero enables the logging. + + * 'status_log_interval' + + Configures interval in seconds in which the routing manager logs its internal + status. Setting a value greater than zero enables the logging. + +* 'tracing' (optional) + * 'enable' + + Specifies whether the tracing of the SOME/IP messages is enabled + (valid values: _true, false_). Default value is _false_. + If tracing is enabled, the messages will be forwarded to DLT by + the [Trace Connector](#trace-connector) + + * 'sd_enable' + + Specifies whether the tracing of the SOME/IP service discovery messages is + enabled (valid values: _true, false_). Default value is _false_. + + * 'channels (array)' (optional) + + Contains the channels to DLT. + + NOTE: You can set up multiple channels to DLT over that you can forward the + messages. + + * 'name' + + The name of the channel. + + * 'id' + + The id of the channel. + + * 'filters (array)' (optional) + + Contains the filters that are applied on the messages. + + NOTE: You can apply filters respectively filter rules on the messages with + specific criterias and expressions. So only the filtered messages are forwarded + to DLT. + + * 'channel' (optional) + + The id of the channel over that the filtered messages are forwarded to DLT. If + no channel is specified the default channel (TC) is used. If you want to use a + filter in several different channels, you can provide an array of channel ids. + + NOTE: If you use a positive filter with multiple channels, the same message + will be forwared multiple times to DLT. + + * 'matches' (optional) + + Specification of the criteria to include/exclude a message into/from the trace. + You can either specify lists (array) or ranges of matching elements. + + A list may contain single identifiers which match all messages from/to all + instances of the corresponding service or tuples consisting of service-, + instance- and method-identifier. 'any' may be used as a wildcard for matching + all services, instances or methods. + + A range is specified by two tuples "from" and "to", each consisting of + service-, instance-and method-identifier. All messages with service-, + instance-and method-identifiers that are greater than or equal to "from" + and less than or equal to "to" are matched. + + * 'type' (optional) + + Specifies the filter type (valid values: "positive", "negative", "header-only"). + When a positive filter is used and a message matches one of the filter rules, + the message will be traced/forwarded to DLT. With a negative filter messages + can be excluded. So when a message matches one of the filter rules, the message + will not be traced/forwarded to DLT. Default value is "positive". The value + "header-only" implies the filter is also considered "positive". + +* 'applications (array)' + + Contains the applications of the host system that use this config file. + + * 'name' + + The name of the application. + + * 'id' + + The id of the application. Usually its high byte is equal to the diagnosis address. In this + case the low byte must be different from zero. Thus, if the diagnosis address is 0x63, valid + values range from 0x6301 until 0x63FF. It is also possible to use id values with a high byte + different from the diagnosis address. + + * 'max_dispatchers' (optional) + + The maximum number of threads that shall be used to execute the application callbacks. Default is 10. + + * 'max_dispatch_time' (optional) + + The maximum time in ms that an application callback may consume before the callback is + considered to be blocked (and an additional thread is used to execute pending + callbacks if max_dispatchers is configured greater than 0). The default value if not specified is 100ms. + + * 'max_detached_thread_wait_time' (optional) + + The maximum time in seconds that an application will wait for a detached dispatcher thread + to finish executing. The default value if not specified is 5s. + + * 'threads' (optional) + + The number of internal threads to process messages and events within an application. + Valid values are 1-255. Default is 2. + + * 'io_thread_nice' (optional) + + The nice level for internal threads processing messages and events. POSIX/Linux only. + For actual values refer to nice() documentation. + + * 'request_debounce_time' (optional) + + Specifies a debounce-time interval in ms in which request-service messages are sent to + the routing manager. If an application requests many services in short same time + the load of sent messages to the routing manager and furthermore the replies from the + routing manager (which contains the routing info for the requested service if available) + can be heavily reduced. The default value if not specified is 10ms. + + * 'plugins' (optional array) + + Contains the plug-ins that should be loaded to extend the functionality of vsomeip. + + * 'name' + + The name of the plug-in. + + * 'type' + + The plug-in type (valid values: _application_plugin_). + + An application plug-in extends the functionality on application level. It gets informed + by vsomeip over the basic application states (INIT/START/STOP) and can, based on these + notifications, access the standard "application"-API via the runtime. + +* `services` (array) + + Contains the services of the service provider. + + * `service` + + The id of the service. + + * `instance` + + The id of the service instance. + + * `protocol` (optional) + + The protocol that is used to implement the service instance. The default setting + is _someip_. If a different setting is provided, vsomeip does not open the specified + port (server side) or does not connect to the specified port (client side). Thus, + this option can be used to let the service discovery announce a service that is + externally implemented. + + * `unicast` (optional) + + The unicast that hosts the service instance. + + NOTE: The unicast address is needed if external service instances shall be used, + but service discovery is disabled. In this case, the provided unicast address + is used to access the service instance. + + * `reliable` + + Specifies that the communication with the service is reliable respectively the + TCP protocol is used for communication. + + * `port` + + The port of the TCP endpoint. + + * `enable-magic-cookies` + + Specifies whether magic cookies are enabled (valid values: _true_, _false_). + + * `unreliable` + + Specifies that the communication with the service is unreliable respectively the + UDP protocol is used for communication (valid values: the _port_ of the UDP + endpoint). + + * `events` (array) + + Contains the events of the service. + + * `event` + + The id of the event. + + * `is_field` + + Specifies whether the event is of type field. + + NOTE: A field is a combination of getter, setter and notification event. It + contains at least a getter, a setter, or a notifier. The notifier sends an event + message that transports the current value of a field on change. + + * `is_reliable` + + Specifies whether the communication is reliable respectively whether the event + is sent with the TCP protocol (valid values: _true_,_false_). + + If the value is _false_ the UDP protocol will be used. + + * `eventgroups` (array) + + Events can be grouped together into on event group. For a client it is thus + possible to subscribe for an event group and to receive the appropriate events + within the group. + + * `eventgroup` + + The id of the event group. + + * `events` (array) + + Contains the ids of the appropriate events. + + * `multicast` + + Specifies the multicast that is used to publish the eventgroup. + + * `address` + + The multicast address. + + * `port` + + The multicast port. + + * `threshold` + + Specifies when to use multicast and when to use unicast to send a notification event. + Must be set to a non-negative number. If it is set to zero, all events of the eventgroup + will be sent by unicast. Otherwise, the events will be sent by unicast as long as the + number of subscribers is lower than the threshold and by multicast if the number + of subscribers is greater or equal. This means, a threshold of 1 will lead to all events + being sent by multicast. The default value is _0_. + + * `debounce-times` (object) + + Used to configure the nPDU feature. This is described in detail in + [vSomeIP nPDU feature](#vsomeip-npdu-feature). + + * `someip-tp` (object) + + Used to configure the SOME/IP-TP feature. There's an example available at + [SOME/IP-TP](#someip-tp). + + * `service-to-client` (array) + + Contains the IDs for responses, fields and events which are sent from the node + to a remote client which can be segmented via SOME/IP-TP if they exceed the + maximum message size for UDP communication. If an ID isn't listed here the + message will otherwise be dropped if the maximum message size is exceeded. + + * `client-to-service` (array) + + Contains the IDs for requests, which are sent from the node + to a remote service which can be segmented via SOME/IP-TP if they exceed the + maximum message size for UDP communication. If an ID isn't listed here the + message will otherwise be dropped if the maximum message size is exceeded. + +* `clients` (array) + + The client-side ports that shall be used to connect to a specific service. + For each service, an array of ports to be used for reliable / unreliable + communication can be specified. vsomeip will take the first free port of + the list. If no free port can be found, the connection will fail. If + vsomeip is asked to connect to a service instance without specified port(s), + the port will be selected by the system. This implies that the user has + to ensure that the ports configured here do not overlap with the ports + automatically selected by the IP stack. + + * `service` + * `instance` + + Together they specify the service instance the port configuration shall be applied to. + + * `reliable` (array) + + The list of client ports to be used for reliable (TCP) communication to the given + service instance. + + * `unreliable` (array) + + The list of client ports to be used for unreliable (UDP) communication to the given + service instance. + + Additionally there is the possibility to configure mappings between ranges of client + ports and ranges of remote service ports. + (If a client port is configured for a specific service / instance, the port range mapping is ignored) + + * `reliable_remote_ports` + + Specifies a range of reliable remote service ports + + * `unreliable_remote_ports` + + Specifies a range of unreliable remote service ports + + * `reliable_client_ports` + + Specifies the range of reliable client ports to be mapped to the reliable_remote_ports range + + * `unreliable_client_ports` + + Specifies the range of unreliable client ports to be mapped to the unreliable_remote_ports range + + * `first` + + Specifies the lower bound of a port range + + * `last` + + Specifies the upper bound of a port range + +* `payload-sizes` (array) + + Array to limit the maximum allowed payload sizes per IP and port. If not + specified otherwise the allowed payload sizes are unlimited. The settings in + this array only affect communication over TCP. To limit the local payload size + `max-payload-size-local` can be used. + + * `unicast` (optional) + + On client side: the IP of the remote service for which the payload size should + be limited. + + On service side: the IP of the offered service for which the payload size for + receiving and sending should be limited. + + * `ports` (array) + + Array which holds pairs of port and payload size statements. + + * `port` + + On client side: the port of the remote service for which the payload size should + be limited. + + On service side: the port of the offered service for which the payload size for + receiving and sending should be limited. + + * `max-payload-size` + + On client side: the payload size limit in bytes of a message sent to the + remote service hosted on beforehand specified IP and port. + + On service side: the payload size limit in bytes of messages received and sent + by the service offered on previously specified IP and port. + + If multiple services are hosted on the same port they all share the limit + specified. + +* `max-payload-size-local` + + The maximum allowed payload size for node internal communication in bytes. By + default the payload size for node internal communication is unlimited. It can be + limited via this setting. + +* `max-payload-size-reliable` + + The maximum allowed payload size for TCP communication in + bytes. By default the payload size for TCP communication is + unlimited. It can be limited via this setting. + +* `max-payload-size-unreliable` + + The maximum allowed payload size for UDP communication via SOME/IP-TP in + bytes. By default the payload size for UDP via SOME/IP-TP communication is + unlimited. It can be limited via this setting. This setting only applies for + SOME/IP-TP enabled methods/events/fields (otherwise the UDP default of 1400 + bytes applies). See [SOME/IP-TP](#someip-tp) for an example configuration. + +* `endpoint-queue-limits` (array) + + Array to limit the maximum allowed size in bytes of cached outgoing messages per + IP and port (message queue size per endpoint). If not specified otherwise the + allowed queue size is unlimited. The settings in this array only affect external + communication. To limit the local queue size `endpoint-queue-limit-local` can + be used. + + * `unicast` + + On client side: the IP of the remote service for which the queue size of sent + requests should be limited. + + On service side: the IP of the offered service for which the queue size for + sent responses should be limited. This IP address is therefore + identical to the IP address specified via `unicast` setting on top level of the + json file. + + * `ports` (array) + + Array which holds pairs of port and queue size statements. + + * `port` + + On client side: the port of the remote service for which the queue size of sent + requests should be limited. + + On service side: the port of the offered service for which the queue size for + send responses should be limited. + + * `queue-size-limit` + + On client side: the queue size limit in bytes of messages sent to the + remote service hosted on beforehand specified IP and port. + + On service side: the queue size limit in bytes for responses sent by the service + offered on previously specified IP and port. + + If multiple services are hosted on the same port they all share the limit + specified. + +* `endpoint-queue-limit-external` + + Setting to limit the maximum allowed size in bytes of cached outgoing messages + for external communication (message queue size per endpoint). By default the + queue size for external communication is unlimited. It can be limited via this + setting. Settings done in the `endpoint-queue-limits` array override this + setting. + +* `endpoint-queue-limit-local` + + Setting to limit the maximum allowed size in bytes of cached outgoing messages + for local communication (message queue size per endpoint). By default the queue + size for node internal communication is unlimited. It can be limited via this + setting. + +* `buffer-shrink-threshold` + + The number of processed messages which are half the size or smaller than the + allocated buffer used to process them before the memory for the buffer is + released and starts to grow dynamically again. This setting can be useful in + scenarios where only a small number of the overall messages are a lot bigger + then the rest and the memory allocated to process them should be released in a + timely manner. If the value is set to zero the buffer sizes aren't reseted and + are as big as the biggest processed message. (default is 5) + + Example: `buffer-shrink-threshold` is set to 50. A message with 500 bytes has to + be processed and the buffers grow accordingly. After this message 50 consecutive + messages smaller than 250 bytes have to be processed before the buffer size is + reduced and starts to grow dynamically again. + +* `tcp-restart-aborts-max` + + Setting to limit the number of TCP client endpoint restart aborts due to unfinished TCP handshake. + After the limit is reached, a forced restart of the TCP client endpoint is done if the connection attempt is still pending. + +* `tcp-connect-time-max` + + Setting to define the maximum time until the TCP client endpoint connection attempt should be finished. + If `tcp-connect-time-max` is elapsed, the TCP client endpoint is forcely restarted if the connection attempt is still pending. + +* `udp-receive-buffer-size` + + Specifies the size of the socket receive buffer (`SO_RCVBUF`) used for + UDP client and server endpoints in bytes. (default: 1703936) + +* `internal_services` (optional array) + + Specifies service/instance ranges for pure internal service-instances. + This information is used by vsomeip to avoid sending Find-Service messages + via the Service-Discovery when a client is requesting a not available service- + instance. Its can either be done on service/instance level or on service level + only which then includes all instance from 0x0000-0xffff. + + * `first` + + The lowest entry of the internal service range. + + * `service` + + The lowest Service-ID in hex of the internal service range. + + * `instance` (optional) + + The lowest Instance-ID in hex of a internal service-instance range. + If not specified the lowest Instance-ID is 0x0000. + + * `last` + + The highest entry of the internal service range. + + * `service` + + The highest Service-ID in hex of a internal service range. + + * `instance` (optional) + + The highest Instance-ID in hex of a internal service-instance range. + If not specified the highest Instance-ID is 0xFFFF. + +* `debounce` (optional array) + + Events/fields sent by external devices will be forwarded to the + applications only if a configurable function evaluates to true. The + function checks whether the event/field payload has changed and whether + a specified interval has been elapsed since the last forwarding. + +* `service` + + Service ID which hosts the events to be debounced. + + * `instance` + + Instance ID which hosts the events to be debounced. + + * `events` + + Array of events which shall be debounced based on the following + configuration options. + + * `event` + + Event ID. + + * `on_change` + + Specifies whether the event is forwarded on + payload change or not. (valid values: _true_, _false_). + Default is _false_. + + * `ignore` + + Array of payload indexes with given bit mask (optional) + to be ignored in payload change evaluation. + Instead of specifying an index / bitmask pair, one can only define the payload index + which shall be ignored in the evaluation. + + * `index` + + Payload index to be checked with given bitmask. + + * `mask` + + 1Byte bitmask applied to byte at given payload index. + Example mask: 0x0f ignores payload changes in low nibble of the byte at given index. + + * `interval` + + Specifies if the event shall be debounced based on elapsed time interval. + (valid values: _time in ms_, _never_). Default is _never_. + + * `on_change_resets_interval` (optional) + + Specifies if interval timer is reset when payload change was detected. + (valid values: _false_, _true_). Defaults to _false_. + + * `send_current_value_after` (optional) + + Specifies if last message should be sent after interval timeout. + (valid values: _false_, _true_). Defaults to _false_. + +* `routing` (optional) + + Specifies the properties of the routing. Either a string that specifies the application that hosts the + routing component or a structure that specifies all properties of the routing. If the routing is not + specified, the first started application will host the routing component. + + * `host` + + Properties of the routing manager. + + * `name` + + Name if the application that hosts the routing component. + + * `uid` + + User identifier of the process that runs the routing component. Must be specified if credential checks + are enabled by _check_credentials_ set to true. + + * `gid` + + Group identifier of the process that runs the routing component. Must be specified if credential checks + are enabled by _check_credentials_ set to true. + + * `unicast` (optional) + + The unicast address that shall be used by the routing manager, if the internal communication shall be done + by using TCP connections. + + * `port` (optional) + + The port that shall be used by the routing manager, if the internal communication shall be done + by using TCP connections. + + * `guests` (optional) + + Properties of all applications that do not host the routing component, if the internal communication shall be + done using TCP connections. + + * `unicast` + + The unicast address that shall be used by the applications to connect to the routing manager. + + * `ports` + + A set of port ranges that shall be used to connect to the routing manager per user identifier/group identifier. + Either specify uid, gid and ranges, or only a set of port ranges. If uid and gid are not explicitly specified, + they default to any. Each client application requires two ports, one for receiving messages from other + applications and one to send messages to other applications. + + * `uid` + + User identifier + + * `gid` + + Group identifier + + * `ranges` + + Set of port ranges. Each entry consists of a `first`, `last` pair that determines the first and the last port + of a port range. + + * `first` + + First port of a port range + + * `last` + + Last port of a port range + + NOTE: Each configured port range must contain an even number of ports. If an even port number is configured + to be the routing host port, the first port in the range must also be even. If an uneven port number is + configured to be the routing host port, the first port in the range must also be uneven. + +* `routing-credentials` (deprecated) + + The UID / GID of the application acting as routing manager. + (Must be specified if credentials checks are enabled using _check_credentials_ set to _true_ in order to successfully check the routing managers credentials passed on connect) + + * `uid` + + The routing managers UID. + + * `gid` + + The routing managers GID. + +* `shutdown_timeout` + + Configures the time in milliseconds local clients wait for acknowledgement of + their deregistration from the routing manager during shutdown. Defaults to + 5000ms. + +* `warn_fill_level` + + The routing manager regulary checks the fill level of the send buffers to its + clients. This variable defines the minimum fill level in percent that leads to + a warning being logged. Defaults to 67. + +* `service-discovery` + + Contains settings related to the Service Discovery of the host application. + + * `enable` + + Specifies whether the Service Discovery is enabled (valid values: _true_, + _false_). The default value is _true_. + + * `multicast` + + The multicast address which the messages of the Service Discovery will be sent + to. The default value is _224.0.0.1_. + + * `port` + + The port of the Service Discovery. The default setting is _30490_. + + * `protocol` + + The protocol that is used for sending the Service Discovery messages (valid + values: _tcp_, _udp_). The default setting is _udp_. + + * `initial_delay_min` + + Minimum delay before first offer message. + + * `initial_delay_max` + + Maximum delay before first offer message. + + * `repetitions_base_delay` + + Base delay sending offer messages within the repetition phase. + + * `repetitions_max` + + Maximum number of repetitions for provided services within the + repetition phase. + + * `ttl` + + Lifetime of entries for provided services as well as consumed services and eventgroups. + + * `ttl_factor_offers` (optional array) + + Array which holds correction factors for incoming remote offers. If a value + greater than one is specified for a service instance, the TTL field of the + corresponding service entry will be multiplied with the specified factor. + + Example: An offer of a service is received with a TTL of 3 sec and the TTL + factor is set to 5. The remote node stops offering the service w/o sending a + StopOffer message. The service will then expire (marked as unavailable) 15 seconds + after the last offer has been received. + + * `service` + + The id of the service. + + * `instance` + + The id of the service instance. + + * `ttl_factor` + + TTL correction factor + + * `ttl_factor_subscriptions` (optional array) + + Array which holds correction factors for incoming remote subscriptions. If a + value greater than one is specified for a service instance, the TTL field of the + corresponding eventgroup entry will be multiplied with the specified factor. + + Example: A remote subscription to an offered service is received with a TTL of 3 + sec and the TTL factor is set to 5. The remote node stops resubscribing to the + service w/o sending a StopSubscribeEventgroup message. The subscription will + then expire 15 seconds after the last resubscription has been received. + + * `service` + + The id of the service. + + * `instance` + + The id of the service instance. + + * `ttl_factor` + + TTL correction factor + + * `cyclic_offer_delay` + + Cycle of the OfferService messages in the main phase. + + + * `request_response_delay` + + Minimum delay of a unicast message to a multicast message for + provided services and eventgroups. + + + * `offer_debounce_time` + + Time which the stack collects new service offers before they enter the + repetition phase. This can be used to reduce the number of + sent messages during startup. The default setting is _500ms_. + +* 'suppress_missing_event_logs' + + Used to filter the log message `deliver_notification: Event [1234.5678.80f3] + is not registered. The message is dropped.` that occurs whenever vSomeIP + receives an event without having a corresponding object being registered. + +```json +... +"suppress_missing_event_logs" : +[ + { + "service" : "0x0023", + "instance" : "0x0001", + "events" : [ "0x8001", "0x8002", + { + "first" : "0x8010", + "last" : "0x801f" + }, + "0x8020" ] + }, + { + "service" : "0x0023", + "instance" : "0x0002", + "events" : [ "0x8005", "0x8006" ] + }, + { + "service" : "0x0023", + "instance" : "0x0002", + "events" : [ "0x8105", "0x8106" ] + }, + { + // no "events" --> ignore all(!) events of these services + "service" : "any", + "instance" : "0x00f2" + }, + { + "service" : "0x0102", + "instance" : "any", + "events" : [ "0x8005", "0x8006" ] + } +] +``` + +* `watchdog` (optional) + + The Watchdog sends periodically pings to all known local clients. + If a client isn't responding within a configurred time/amount of pongs + the watchdog deregisters this application/client. + If not configured the watchdog isn't activated. + + * `enable` + + Specifies whether the watchdog is enabled or disabled. + (valid values: _true, false_), (default is _false_). + + * `timeout` + + Specifies the timeout in ms the watchdog gets activated if a ping + isn't answered with a pong by a local client within that time. + (valid values: _2 - 2^32_), (default is _5000_ ms). + + * `allowed_missing_pongs` + + Specifies the amount of allowed missing pongs. + (valid values: _1 - 2^32_), (default is _3_ pongs). + + +* `supports_selective_broadcasts` (optional array) + + This nodes allow to add a list of IP addresses on which CAPI-Selective-Broadcasts feature is supported. + If not specified the feature can't be used and the subscription behavior of the stack is same as with + normal events. + + * `address` + + Specifies an IP-Address (in IPv4 or IPv6 notation) on which the "selective"-feature is supported. + Multiple addresses can be configured. + +# Security + +vsomeip has a security implementation based on UNIX credentials. +If activated every local connection is authenticated during connect using the standard UNIX credential passing mechanism. +During authentication a client transfers its client identifier together with its credentials (UID / GID) to the server which is then matched against the configuration. +If received credentials don't match the policy the socket will be immediately closed by the server and an message is logged. +If accepted the client identifier is bound to the receiving socket and can therefore be used to do further security checks on incoming messages (vsomeip messages as well as internal commands). + +In general clients can be configured to be allowed/denied to request (means communicate with) and offer different service instances. +Every incoming vsomeip message (request/response/notification) as well as offer service requests or local subscriptions are then checked against the policy. +If an incoming vsomeip message or another operation (e.g. offer/subscribe) violates the configured policies it is skipped and a message is logged. + +Furthermore if an application receives informations about other clients/services in the system, it must be received from the authenticated routing manager. +This is to avoid malicious applications faking the routing manager and therefore being able to wrongly inform other clients about services running on the system. +Therefore, whenever the "security" tag is specified, the routing manager (e.g. routingmanagerd/vsomeipd) must be a configured application with a fixed client identifier. +See chapter "Configuration File Structure" on how to configure an application to use a specific client identifier. + +Credential passing is only possible via Unix-Domain-Sockets and therefore only available for local communication. +However if security is activated method calls from remote clients to local services are checked as well which means remote clients needs to be explicitly allowed. +Such a policy looks same in case for local clients except the _credentials_ tag can be skipped. + +## Security configuration + +The available configuration switches for the security feature are: + +* `security` (optional) + + NOTE: As long as no _security_ node exists, the security implementation is switched off. This also means, + no external security library will be loaded and used. + + If specified the credential passing mechanism is activated. However no credential or security checks are done as long as + _check_credentials_ isn't set to _true_, but the routing manager client ID must be configured if security tag is specified. + If _check_credentials_ is set to _true_, the routing managers UID and GID needs to be specified using _routing-credentials_ tag. + + * `check_credentials` (optional) + + Specifies whether security checks are active or not. This includes credentials checks on connect as well as all policies checks configured in follow. + (valid values: _true, false_), (default is _false_). + + * `allow_remote_clients` (optional) + + Specifies whether incoming remote requests / subscriptions are allowed to be sent to a local proxy / client. + If not specified, all remote requests / subscriptions are allowed to be received by default. + (valid values are 'true' and 'false') + + * `policies` (array) + + Specifies the security policies. Each policy at least needs to specify _allow_ or _deny_. + + * `credentials` + + Specifies the credentials for which a security policy will be applied. + If _check_credentials_ is set to _true_ the credentials of a local application needs to be specified correctly to ensure local socket authentication can succeed. + + * `uid` + + Specifies the LINUX user id of the client application as decimal number. + As a wildcard "any" can be used. + + * `gid` + + Specifies the LINUX group id of the client application as decimal number. + As a wildcard "any" can be used. + + * `allow` / `deny` (optional) + + Specifies whether the LINUX user and group ids are allowed or denied for the policy. + + 1. `uid` (array) + + Specifies a list of LINUX user ids. These may either be specified as decimal numbers or as ranges. Ranges + are specified by the first and the last valid id (see example below). + + 2. `gid` (array) + + Specifies a list of LINUX group ids. These may either be specified as decimal numbers or as ranges. Ranges + are specified by the first and the last valid id (see example below). + + * `allow` / `deny` + + This tag specifies either _allow_ or _deny_ depending on white- or blacklisting is needed. Specifing _allow_ and _deny_ entries in one policy is therefore not allowed. + With _allow_ a whitelisting of what is allowed can be done which means an empty _allow_ tag implies everything is denied. + With _deny_ a blacklisting of what is allowed can be done which means an empty _deny_ tag implies everything is allowed. + + * `requests` (array) + + Specifies a set of service instance pairs which the above client application using the credentials above is allowed/denied to communicate with. + + 1. `service` + + Specifies a service for the _requests_. + + 2. `instance` (deprecated) + + Specifies a instance for the _requests_ + As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF + which also implies a method ID range from 0x01 to 0xFFFF. + + 3. `instances` (array) + + Specifies a set of instance ID and method ID range pairs which are allowed/denied to communicate with. + If the `ids` tag below is not used to specify allowed/denied requests on method ID level one can also + only specify a a set of instance ID ranges which are allowed/denied to be requested analogous to the + allowed/denied `offers` section. + If no method IDs are specified, the allowed/denied methods are by default a range from 0x01 to 0xFFFF. + + 1. `ids` + + Specifies a set of instance ID ranges which are allowed/denied to communicate with. + It is also possible to specify a single instance ID as array element without giving an upper / lower range bound. + As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF. + + `first` - The lower bound of the instance range. + + `last` - The upper bound of the instance range. + + 2. `methods` + + Specifies a set of method ID ranges which are allowed/denied to communicate with. + It is also possible to specify a single method ID as array element without giving an upper / lower range bound. + As a wildcard "any" can be used which means a range from method ID 0x01 to 0xFFFF. + + `first` - The lower bound of the method range. + + `last` - The upper bound of the method range. + + * `offers` (array) + + Specifies a set of service instance pairs which are allowed/denied to be offered by the client application using the credentials above. + + 1. `service` + + Specifies a service for the _offers_. + + 2. `instance` (deprecated) + + Specifies a instance for the _offers_ + As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF. + + 3. `instances` (array) + + Specifies a set of instance ID ranges which are allowed/denied to be offered by the client application using the credentials above. + It is also possible to specify a single instance ID as array element without giving an upper / lower range bound. + As a wildcard "any" can be used which means a range from instance ID 0x01 to 0xFFFF. + + 1. `first` + + The lower bound of the instance range. + + 2. `last` + + The upper bound of the instance range. + +--- + +## Security configuration example + +```json +... +"security" : +{ + ... + "policies" : + [ + { + ... + "credentials" : + { + "uid" : "44", + "gid" : "any" + }, + "allow" : + [ + "requests" : + [ + { + "service" : "0x6731", + "instance" : "0x0001" + } + ] + ] + }, + { + "credentials" : + { + "deny" : + [ + { + "uid" : [ "1000", { "first" : "1002", "last" : "max" }], + "gid" : [ "0", { "first" : "100", "last" : "243" }, "300"] + }, + { + "uid" : ["55"], + "gid" : ["55"] + } + ] + }, + "allow" : + [ + "offers" : + [ + { + "service" : "0x6728", + "instances" : [ "0x0001", { "first" : "0x0003", "last" : "0x0007" }, "0x0009"] + }, + { + "service" : "0x6729", + "instances" : ["0x88"] + }, + { + "service" : "0x6730", + "instance" : "any" + } + ], + "requests" : + [ + { + "service" : "0x6732", + "instances" : + [ + { + "ids" : [ "0x0001", { "first" : "0x0003", "last" : "0x0007" }], + "methods" : [ "0x0001", "0x0003", { "first" : "0x8001", "last" : "0x8006" } ] + }, + { + "ids" : [ "0x0009" ], + "methods" : "any" + } + ] + }, + { + "service" : "0x6733", + "instance" : "0x1" + }, + { + "service" : "0x6733", + "instances" : [ "0x0002", { "first" : "0x0003", "last" : "0x0007" }, "0x0009"] + } + ] + ] + } + ] +} +``` + +The config/ folder contains some addition vsomeip configuration files to run the vsomeip +examples with activated security checks. +Additionally there's a security test in the `test/` subfolder which can be used +for further reference. + +They give a basic overview how to use the security related configuration tags described +in this chapter to run a simple request/response or subscribe/notify example locally or +remotely. + +## Security policy extensions + +vsomeip policy extension configuration supports the definition of paths that contain additional +security policies to be loaded whenever a client with a yet unknown hostname connects to a local server endpoint. +The following configuration parameters are available and can be defined in a file named `vsomeip_policy_extensions.json`. + +* `container_policies` (optional array) + + Specifies the additional configuration folders to be loaded for each container hostname / filesystem path pair. + + * `container` + + Specifies the linux hostname. + + * `path` + + Specifies a filesystem path (relative to vsomeip_policy_extensions.json or absolute) which contains + $UID_$GID subfolders that hold a `vsomeip_security.json` file. + + NOTE: ($UID / $GID) is the UID /GID of the vsomeip client application + to which a client from hostname defined with `container`connetcs to. + +## Audit Mode + +vsomeip's security implementation can be put in a so called 'Audit Mode' where +all security violations will be logged but allowed. This mode can be used to +build a security configuration. + +To activate the 'Audit Mode' the 'security' object has to be included in the +json file but the 'check_credentials' switch has to be set to false. For +example: + + +```json + [...] + "services" : + [ + [...] + ], + "security" : + { + "check_credentials" : "false" + }, + "routing" : "service-sample", + [...] +``` + +# Autoconfiguration + +vsomeip supports the automatic configuration of client identifiers and the routing. +The first application that starts using vsomeip will automatically become the +routing manager if it is _not_ explicitly configured. The client identifiers +are generated from the diagnosis address that can be specified by defining +DIAGNOSIS_ADDRESS when compiling vsomeip. vsomeip will use the diagnosis address +as the high byte and enumerate the connecting applications within the low byte +of the client identifier. + +Autoconfiguration of client identifiers isn't meant to be used together with vsomeip Security. +Every client running locally needs to have at least its own credentials configured when security is activated to ensure the credential checks can pass. +Practically that means if a client requests its identifier over the autoconfiguration for which no credentials are configured (at least it isn't known which client identifier is used beforehand) it is impossible for that client to establish a connection to a server endpoint. +However if the credentials for all clients are same it's possible to configure them for the overall (or DIAGNOSIS_ADDRESS) client identifier range to mix autoconfiguration together with activated security. + +# routingmanagerd + +The routingmanagerd is a minimal vsomeip application intended to offer routing +manager functionality on a node where one system wide configuration file is +present. It can be found in the examples folder. + +Example: Starting the daemon on a system where the system wide configuration is +stored under `/etc/vsomeip.json`: + +```bash +VSOMEIP_CONFIGURATION=/etc/vsomeip.json ./routingmanagerd +``` + +When using the daemon it should be ensured that: + +* In the system wide configuration file the routingmanagerd is defined as + routing manager, meaning it contains the line `"routing" : "routingmanagerd"`. + If the default name is overridden the entry has to be adapted accordingly. + The system wide configuration file should contain the information about all + other offered services on the system as well. +* There's no other vsomeip configuration file used on the system which contains + a `"routing"` entry. As there can only be one routing manager per system. + +# vsomeip Hello World + +In this paragraph a Hello World program consisting out of a client and a service +is developed. The client sends a message containing a string to the service. +The service appends the received string to the string `Hello` and sends it back +to the client. +Upon receiving a response from the service the client prints the payload of the +response ("Hello World"). +This example is intended to be run on the same host. + +All files listed here are contained in the `examples\hello_world` subdirectory. + +## Build instructions + +The example can build with its own CMakeFile, please compile the vsomeip stack +before hand as described in [Compilation](#compilation). Then compile the example starting +from the repository root directory as followed: + +```bash +cd examples/hello_world +mkdir build +cd build +cmake .. +make +``` + +## Starting and expected output +### Starting and expected output of service + +```bash +$ VSOMEIP_CONFIGURATION=../helloworld-local.json \ + VSOMEIP_APPLICATION_NAME=hello_world_service \ + ./hello_world_service +2015-04-01 11:31:13.248437 [info] Using configuration file: ../helloworld-local.json +2015-04-01 11:31:13.248766 [debug] Routing endpoint at /tmp/vsomeip-0 +2015-04-01 11:31:13.248913 [info] Service Discovery disabled. Using static routing information. +2015-04-01 11:31:13.248979 [debug] Application(hello_world_service, 4444) is initialized. +2015-04-01 11:31:22.705010 [debug] Application/Client 5555 got registered! +``` + +### Starting and expected output of client + +```bash +$ VSOMEIP_CONFIGURATION=../helloworld-local.json \ + VSOMEIP_APPLICATION_NAME=hello_world_client \ + ./hello_world_client +2015-04-01 11:31:22.704166 [info] Using configuration file: ../helloworld-local.json +2015-04-01 11:31:22.704417 [debug] Connecting to [0] at /tmp/vsomeip-0 +2015-04-01 11:31:22.704630 [debug] Listening at /tmp/vsomeip-5555 +2015-04-01 11:31:22.704680 [debug] Application(hello_world_client, 5555) is initialized. +Sending: World +Received: Hello World +``` + +## CMakeFile + +[examples/hello_world/CMakeLists.txt](../examples/hello_world/CMakeLists.txt) + +## Configuration File For Client and Service + +[examples/hello_world/helloworld-local.json](../examples/hello_world/helloworld-local.json) + +## Service + +[examples/hello_world/hello_world_service_main.cpp](../examples/hello_world/hello_world_service_main.cpp) + +The service example results in the following program execution: + +### Main + +1. *main()* + + First the application is initialized. After the initialization is + finished the application is started. + +### Initialization + +2. *init()* + + The initialization contains the registration of a message + handler and an event handler. + + The message handler declares a callback (__on_message_cbk__) for messages that + are sent to the specific service (specifying the service id, the service + instance id and the service method id). + + The event handler declares a callback (__on_event_cbk__) for events that occur. + One event can be the successful registration of the application at the runtime. + +### Start + +3. *start()* + + The application will be started. This function only returns when the application + will be stopped. + +### Callbacks + +4. *on_state_cbk()* + + This function is called by the application when an state change occurred. If + the application was successfully registered at the runtime then the specific + service is offered. + +5. *on_message_cbk()* + + This function is called when a message/request from a client for the specified + service was received. + + First a response based upon the request is created. + Afterwards the string 'Hello' will be concatenated with the payload of the + client's request. + After that the payload of the response is created. The payload data is set with + the previously concatenated string. + Finally the response is sent back to the client and the application is stopped. + +### Stop + +6. *stop()* + + This function stops offering the service, unregister the message and the event + handler and shuts down the application. + +## Client + +[examples/hello_world/hello_world_client_main.cpp](../examples/hello_world/hello_world_client_main.cpp) + +The client example results in the following program execution: + +### Main + +1. *main()* + + First the application is initialized. After the initialization is finished the + application is started. + +### Initialization + +2. *init()* + + The initialization contains the registration of a message handler, an event + handler and an availability handler. + + The event handler declares again a callback (__on_state_cbk__) for state changes + that occur. + + The message handler declares a callback (__on_message_cbk__) for messages that + are received from any service, any service instance and any method. + + The availability handler declares a callback (__on_availability_cbk__) which is + called when the specific service is available (specifying the service id and the + service instance id). + +### Start + +3. *start()* + + The application will be started. This function only returns when the application + will be stopped. + +### Callbacks + +4. *on_state_cbk()* + + This function is called by the application when an state change occurred. If the + application was successfully registered at the runtime then the specific service + is requested. + +5. *on_availability_cbk()* + + This function is called when the requested service is available or no longer + available. + + First there is a check if the change of the availability is related to the + 'hello world service' and the availability changed to true. + If the check is successful a service request is created and the appropriate + service information are set (service id, service instance id, service method + id). + After that the payload of the request is created. The data of the payload is + 'World' and will be set afterwards. + Finally the request is sent to the service. + +6. *on_message_cbk()* + + This function is called when a message/response was received. + If the response is from the requested service, of type 'RESPONSE' and the return + code is 'OK' then the payload of the response is printed. Finally the + application is stopped. + +### Stop + +7. *stop()* + +This function unregister the event and the message handler and shuts down the +application. + +# Trace Connector +## Overview/Prerequisites + +The Trace Connector is used to forward the internal messages that are sent over +the Unix Domain Sockets to DLT. + +Thus, it requires that DLT is installed and the DLT module can be found in the +context of CMake. + +## Configuration +### Static Configuration + +The Trace Connector can be configured statically over the *tracing* point of the +[Configuration File Structure](#tracing-anchor) + +### Example 1 (Minimal Configuration) + +```json +{ + ... + + "tracing" : + { + "enable" : "true" + }, + + ... +``` + +This is the minimal configuration of the Trace Connector. This just enables the +tracing and all of the sent internal messages will be traced/forwarded to DLT. + +### Example 2 (Using Filters) + +```json +{ + ... + + "tracing" : + { + "enable" : "true", + "channels" : + [ + { + "name" : "My channel", + "id" : "MC" + } + ], + "filters" : [ + { + "channel" : "MC", + "matches" : [ { "service" : "0x1234", "instance" : "any", "method" : "0x80e8" } ], + "type" : "positive" + } + ] + }, + + ... +``` + +As it is a positive filter, the example filter ensures that only messages +representing method '0x80e8' from instances of service '0x1234' will be +forwarded to the DLT. If it was specified as a negative filter, all messages +except messages representing method '0x80e8' from instances of service +'0x1234' would be forwarded to the DLT. + +The general filter rules are: + +* The default filter is a positive filter for all messages. +* The default filter is active on a channel as long as no other positive +filter is specified. +* Negative filters block matching messages. Negative filters overrule +positive filters. Thus, as soon as a messages matches a negative filter it +will not be forwarded. +* The identifier '0xffff' is a wildcard that matches any service, instance or method. +The keyword 'any' can be used as a replacement for '0xffff'. +* Wildcards must not be used within range filters. + +### Dynamic Configuration + +The Trace Connector can also be configured dynamically over its interfaces. +You need to include '' to access its public interface. + +### Example: + +```c++ + // get trace connector + std::shared_ptr its_connector + = vsomeip::trace::connector::get(); + + // add channel + std::shared_ptr its_channel + = its_connector->create_channel("MC", "My channel"); + + // add filter rule + vsomeip::trace::match_t its_match + = std::make_tuple(0x1234, 0xffff, 0x80e8); + vsomeip::trace::filter_id_t its_filter_id + = its_channel->add_filter(its_match, true); + + // init trace connector + its_connector->init(); + + // enable trace connector + its_connector->set_enabled(true); + + // remove the filter + its_channel->remove_filter(its_filter_id); +``` + +# vsomeip nPDU feature + +This is the add-on documentation for the nPDU feature, aka. _Zugverfahren_. + +The nPDU feature can be used to reduce network load as it enables the vsomeip +stack to combine multiple vsomeip messages in one single ethernet frame. + +Some general _important_ things regarding the nPDU feature first: + +* Due to its nature the nPDU feature trades lower network load for speed. +* As the nPDU feature requires some settings which are not transmitted +through the service discovery, it's *not* sufficient anymore to have an json +file without a "services" section on the client side. +* As the client- and server-endpoints of a node are managed by the routing + manager (which is the application entered at "routing" in the json file) + the nPDU feature settings *always* have to be defined in the json file used by + the application acting as routing manager. +* The nPDU feature timings are defined in milliseconds. +* Node internal communication over UNIX domain sockets is not affected by the + nPDU feature. +* If the debounce times configuration for a method in the json file is missing + or incomplete the default values are used: 2ms debounce time and 5ms max + retention time. The global default values can be overwritten via the + `npdu-default-timings` json object. + +## Configuration + +There are two parameters specific for the nPDU feature: + +* *debounce time*: minimal time between sending a message to the same method of + a remote service over the same connection (src/dst address + src/dst port). +* *max retention time*: the maximum time which a message to the same method of a + remote service over the same connection (src/dst address + src/dst port) is + allowed to be buffered on sender side. + +For more information please see the corresponding requirement documents. + + +The nPDU feature specific settings are configured in the json file in the +"services" section on service level in a special _debounce-times_ section: + + +```json +[...] +"services": +[ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30509", + "debounce-times": + { + // nPDU feature configuration for this + // service here + } + } +], +[...] +``` + +Additionally nPDU default timings can be configured globally. + +The global default timings can be overwritten via the `npdu-default-timings` +json object. For example the following configuration snippet shows how to set +all default timings to zero: + +```json +{ + "unicast":"192.168.1.9", + [...] + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +### Example 1: One service with one method offered over UDP + +* The service is hosted on IP: 192.168.1.9. +* The service is offered on port 30509 via UDP. +* The service has the ID 0x1000 +* The method has the ID 0x0001 +* The client accesses the service from IP: 192.168.1.77 + +### Service side + +* Debounce time for responses should have a: + * debounce time of 10 milliseconds + * maximum retention time of 100 milliseconds + +```json +{ + "unicast":"192.168.1.9", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30509", + "debounce-times": + { + "responses": { + "0x1001" : { + "debounce-time":"10", + "maximum-retention-time":"100" + } + } + } + } + ], + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +#### Client side + +* Debounce time for requests to the service on 192.168.1.9 should have a: + * debounce time of 20 milliseconds + * maximum retention time of 200 milliseconds + +```json +{ + "unicast":"192.168.1.77", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unicast":"192.168.1.9", // required to mark service as external + "unreliable":"30509", + "debounce-times": + { + "requests": { + "0x1001" : { + "debounce-time":"20", + "maximum-retention-time":"200" + } + } + } + } + ], + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +### Example 2: One service with two methods offered over UDP + +* The service is hosted on IP: 192.168.1.9. +* The service is offered on port 30509 via UDP. +* The service has the ID 0x1000 +* The method has the ID 0x0001 +* The second method has the ID 0x0002 +* The client accesses the service from IP: 192.168.1.77 + +#### Service side + +* Debounce time for responses should have a: + * debounce time of 10 milliseconds for method 0x1001 and 20 for 0x1002 + * maximum retention time of 100 milliseconds for method 0x1001 and 200 for 0x1002 + +```json +{ + "unicast":"192.168.1.9", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30509", + "debounce-times": + { + "responses": { + "0x1001" : { + "debounce-time":"10", + "maximum-retention-time":"100" + }, + "0x1002" : { + "debounce-time":"20", + "maximum-retention-time":"200" + } + } + } + } + ], + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +#### Client side + +* Debounce time for requests to the service on 192.168.1.9 should have a: + * debounce time of 20 milliseconds for method 0x1001 and 40 for 0x1002 + * maximum retention time of 200 milliseconds for method 0x1001 and 400 for 0x1002 + +```json +{ + "unicast":"192.168.1.77", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unicast":"192.168.1.9", // required to mark service as external + "unreliable":"30509", + "debounce-times": + { + "requests": { + "0x1001" : { + "debounce-time":"20", + "maximum-retention-time":"200" + }, + "0x1002" : { + "debounce-time":"40", + "maximum-retention-time":"400" + } + } + } + } + ], + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +### Example 3: One service with one method offered over UDP and TCP + +* The service is hosted on IP: 192.168.1.9. +* The service is offered on port 30509 via UDP. +* The service is offered on port 30510 via TCP. +* The service has the ID 0x1000 +* The method has the ID 0x0001 +* The client accesses the service from IP: 192.168.1.77 + +#### Service side + +* Debounce time for responses should have a: + * debounce time of 10 milliseconds + * maximum retention time of 100 milliseconds + * TCP should use the same settings as UDP + +```json +{ + "unicast":"192.168.1.9", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times": + { + "responses": { + "0x1001" : { + "debounce-time":"10", + "maximum-retention-time":"100", + } + } + } + } + ], + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +#### Client side + +* Debounce time for requests to the service on 192.168.1.9 should have a: + * debounce time of 20 milliseconds + * maximum retention time of 200 milliseconds + * TCP should use the same settings as UDP + +```json +{ + "unicast":"192.168.1.77", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unicast":"192.168.1.9", // required to mark service as external + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times": + { + "requests": { + "0x1001" : { + "debounce-time":"20", + "maximum-retention-time":"200", + } + } + } + } + ], + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +# SOME/IP TP + +With SOME/IP Transport Protocol (TP) it is possible to transport messages which +exceed the UDP payload size limit of 1400 byte. If enabled the message is +segmented and send in multiple UDP datagrams. + +Example configuration: + +* Service 0x1111/0x1 is hosted on 192.168.0.1 on UDP port 40000 +* Client is running on 192.168.0.100 +* The service has two methods with ID: 0x1 and 0x2 which require large requests + and large responses. Additionally the service offers a field with ID 0x8001 + which requires a large payloads as well. +* The maximum payload size on service side should be limited to 5000 bytes. + +Configuration service side: + +```json +{ + "unicast":"192.168.0.1", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x1", + "unreliable":"40000", + "someip-tp": { + "service-to-client": [ + "0x1", "0x2", "0x8001" + ] + } + } + ], + "max-payload-size-unreliable" : "5000", + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +Configuration client side: + +```json +{ + "unicast":"192.168.0.100", + "logging": { [...] }, + "applications": [ [...] ], + "services": + [ + { + "service":"0x1000", + "instance":"0x1", + "unicast":"192.168.0.1", // required to mark service as external + "unreliable":"40000", // required to mark service as external + "someip-tp": { + "client-to-service": [ + "0x1", "0x2" + ] + } + } + ], + "routing":"[...]", + "service-discovery": { [...] } +} +``` + +# Tools +## vsomeip_ctrl + +`vsomeip_ctrl` is a small utility which can be used to send SOME/IP messages +from the commandline. If a response arrives within 5 seconds the response will +be printed. + +* It can be build via `vsomeip_ctrl` make target (`make vsomeip_ctrl`). +* The instance id of the target service has to be passed in hexadecimal + notation. +* The complete message has to be passed in hexadecimal notation. +* See the `--help` parameter for available options. +* If `vsomeip_ctrl` is used to send messages to a remote service and no + `routingmanagerd` is running on the local machine, make sure to pass a json + configuration file where `vsomeip_ctrl` is set as routing manager via + environment variable. +* If `vsomeip_ctrl` is used to send messages to a local service and no + `routingmanagerd` is running on the local machine, make sure to use the same json + configuration file as the local service. + +Example: Calling method with method id 0x80e8 on service with service id 0x1234, +instance id 0x5678: + +```bash +./vsomeip_ctrl --instance 5678 --message 123480e800000015134300030100000000000009efbbbf576f726c6400 +``` + +Example: Sending a message to service with service id 0x1234, instance id +0x5678 and method id 0x0bb8 via TCP + +```bash +./vsomeip_ctrl --tcp --instance 5678 --message 12340bb8000000081344000101010000 +``` diff --git a/examples/hello_world/Android.bp b/examples/hello_world/Android.bp index c095dc128..39da095e5 100644 --- a/examples/hello_world/Android.bp +++ b/examples/hello_world/Android.bp @@ -3,7 +3,7 @@ cc_defaults { vendor: true, cppflags: [ - "-std=c++14", + "-std=c++17", "-Wno-unused-parameter", ], diff --git a/examples/notify-sample.cpp b/examples/notify-sample.cpp index 933b01652..a9306683b 100644 --- a/examples/notify-sample.cpp +++ b/examples/notify-sample.cpp @@ -78,10 +78,6 @@ class service_sample { app_->start(); } -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - /* - * Handle signal to shutdown - */ void stop() { running_ = false; blocked_ = true; @@ -105,7 +101,6 @@ class service_sample { } app_->stop(); } -#endif void offer() { std::lock_guard its_lock(notify_mutex_); @@ -260,6 +255,9 @@ int main(int argc, char **argv) { #endif if (its_sample.init()) { its_sample.start(); +#ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING + its_sample.stop(); +#endif return 0; } else { return 1; diff --git a/examples/request-sample.cpp b/examples/request-sample.cpp index 629af8527..dfebe6fb7 100644 --- a/examples/request-sample.cpp +++ b/examples/request-sample.cpp @@ -84,10 +84,6 @@ class client_sample { app_->start(); } -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - /* - * Handle signal to shutdown - */ void stop() { running_ = false; blocked_ = true; @@ -103,7 +99,6 @@ class client_sample { } app_->stop(); } -#endif void on_state(vsomeip::state_type_e _state) { if (_state == vsomeip::state_type_e::ST_REGISTERED) { @@ -237,6 +232,9 @@ int main(int argc, char **argv) { #endif if (its_sample.init()) { its_sample.start(); +#ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING + its_sample.stop(); +#endif return 0; } else { return 1; diff --git a/examples/response-sample.cpp b/examples/response-sample.cpp index 3cfd9641b..35b45b74b 100644 --- a/examples/response-sample.cpp +++ b/examples/response-sample.cpp @@ -51,10 +51,6 @@ class service_sample { app_->start(); } -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - /* - * Handle signal to shutdown - */ void stop() { running_ = false; blocked_ = true; @@ -70,7 +66,6 @@ class service_sample { } app_->stop(); } -#endif void offer() { app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); @@ -186,6 +181,9 @@ int main(int argc, char **argv) { #endif if (its_sample.init()) { its_sample.start(); +#ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING + its_sample.stop(); +#endif return 0; } else { return 1; diff --git a/examples/routingmanagerd/routingmanagerd.cpp b/examples/routingmanagerd/routingmanagerd.cpp index 65d9d016a..985dece00 100644 --- a/examples/routingmanagerd/routingmanagerd.cpp +++ b/examples/routingmanagerd/routingmanagerd.cpp @@ -137,7 +137,7 @@ int routingmanagerd_process(bool _is_quiet) { std::unique_lock its_lock(sighandler_mutex); stop_sighandler = true; sighandler_condition.notify_one(); - } + } if (std::this_thread::get_id() != sighandler_thread.get_id()) { if (sighandler_thread.joinable()) { sighandler_thread.join(); diff --git a/examples/subscribe-sample.cpp b/examples/subscribe-sample.cpp index 115003f49..11f0e1489 100644 --- a/examples/subscribe-sample.cpp +++ b/examples/subscribe-sample.cpp @@ -64,10 +64,6 @@ class client_sample { app_->start(); } -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - /* - * Handle signal to shutdown - */ void stop() { app_->clear_all_handler(); app_->unsubscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID); @@ -75,7 +71,6 @@ class client_sample { app_->release_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); app_->stop(); } -#endif void on_state(vsomeip::state_type_e _state) { if (_state == vsomeip::state_type_e::ST_REGISTERED) { @@ -178,6 +173,9 @@ int main(int argc, char **argv) { #endif if (its_sample.init()) { its_sample.start(); +#ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING + its_sample.stop(); +#endif return 0; } else { return 1; diff --git a/exportmap.gcc b/exportmap.gcc index 5939e6c4c..baedd348c 100644 --- a/exportmap.gcc +++ b/exportmap.gcc @@ -23,11 +23,15 @@ global: *vsomeip_v3::message_header_impl::*; *vsomeip_v3::payload_impl; *vsomeip_v3::payload_impl::*; + *vsomeip_v3::policy; + vsomeip_v3::policy::*; *vsomeip_v3::policy_manager; vsomeip_v3::policy_manager::*; *vsomeip_v3::policy_manager_impl; vsomeip_v3::policy_manager_impl::*; - vsomeip_v3::security::authenticate_router; + *vsomeip_v3::routing_manager_impl; + vsomeip_v3::routing_manager_impl::*; + vsomeip_v3::security::*; *vsomeip_v3::runtime; vsomeip_v3::runtime::get*; vsomeip_v3::runtime::set_property*; @@ -47,6 +51,8 @@ global: vsomeip_v3::utility::is*; vsomeip_v3::utility::data*; vsomeip_v3::utility::re*; + vsomeip_v3::utility::get_*; + vsomeip_v3::utility::exists*; *vsomeip_v3::plugin_manager; vsomeip_v3::plugin_manager::*; vsomeip_v3::tp::tp_reassembler::*; diff --git a/implementation/compat/runtime/src/runtime_impl.cpp b/implementation/compat/runtime/src/runtime_impl.cpp index b434e5ac8..b15533345 100644 --- a/implementation/compat/runtime/src/runtime_impl.cpp +++ b/implementation/compat/runtime/src/runtime_impl.cpp @@ -39,14 +39,9 @@ runtime_impl::~runtime_impl() { std::shared_ptr runtime_impl::create_application(const std::string &_name) { - + std::lock_guard its_lock(applications_mutex_); auto its_application = std::make_shared(_name); - - { - std::lock_guard its_lock(applications_mutex_); - applications_[its_application->get_name()] = its_application; - } - + applications_[its_application->get_name()] = its_application; return (its_application); } diff --git a/implementation/configuration/include/application_configuration.hpp b/implementation/configuration/include/application_configuration.hpp index e19d3df3a..81ab7aa6a 100644 --- a/implementation/configuration/include/application_configuration.hpp +++ b/implementation/configuration/include/application_configuration.hpp @@ -22,6 +22,7 @@ struct application_configuration { client_t client_; std::size_t max_dispatchers_; std::size_t max_dispatch_time_; + std::size_t max_detach_thread_wait_time_; std::size_t thread_count_; std::size_t request_debouncing_; std::map > plugins_; diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index 8b32a0c99..15fbc9c7d 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -39,6 +39,8 @@ namespace vsomeip_v3 { +class policy_manager_impl; +class security; class event; struct debounce_filter_impl_t; @@ -139,6 +141,7 @@ class configuration { virtual std::size_t get_max_dispatchers(const std::string &_name) const = 0; virtual std::size_t get_max_dispatch_time(const std::string &_name) const = 0; + virtual std::size_t get_max_detached_thread_wait_time(const std::string& _name) const = 0; virtual std::size_t get_io_thread_count(const std::string &_name) const = 0; virtual int get_io_thread_nice_level(const std::string &_name) const = 0; virtual std::size_t get_request_debouncing(const std::string &_name) const = 0; @@ -176,6 +179,7 @@ class configuration { virtual int32_t get_sd_cyclic_offer_delay() const = 0; virtual int32_t get_sd_request_response_delay() const = 0; virtual std::uint32_t get_sd_offer_debounce_time() const = 0; + virtual std::uint32_t get_sd_find_debounce_time() const = 0; // Trace configuration virtual std::shared_ptr get_trace() const = 0; @@ -276,10 +280,10 @@ class configuration { // SOME/IP-TP virtual bool is_tp_client( - service_t _service, const std::string &_address, std::uint16_t _port, + service_t _service, instance_t _instance, method_t _method) const = 0; virtual bool is_tp_service( - service_t _service, const std::string &_address, std::uint16_t _port, + service_t _service, instance_t _instance, method_t _method) const = 0; virtual void get_tp_configuration( service_t _service, instance_t _instance, method_t _method, bool _is_client, @@ -309,6 +313,8 @@ class configuration { virtual bool is_security_external() const = 0; virtual bool is_security_audit() const = 0; virtual bool is_remote_access_allowed() const = 0; + virtual std::shared_ptr get_policy_manager() const = 0; + virtual std::shared_ptr get_security() const = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index f30e0ecf5..d9ed9cbc0 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -140,6 +140,7 @@ class configuration_impl: VSOMEIP_EXPORT std::size_t get_max_dispatchers(const std::string &_name) const; VSOMEIP_EXPORT std::size_t get_max_dispatch_time(const std::string &_name) const; + VSOMEIP_EXPORT std::size_t get_max_detached_thread_wait_time(const std::string& _name) const; VSOMEIP_EXPORT std::size_t get_io_thread_count(const std::string &_name) const; VSOMEIP_EXPORT int get_io_thread_nice_level(const std::string &_name) const; VSOMEIP_EXPORT std::size_t get_request_debouncing(const std::string &_name) const; @@ -194,6 +195,7 @@ class configuration_impl: VSOMEIP_EXPORT int32_t get_sd_cyclic_offer_delay() const; VSOMEIP_EXPORT int32_t get_sd_request_response_delay() const; VSOMEIP_EXPORT std::uint32_t get_sd_offer_debounce_time() const; + VSOMEIP_EXPORT std::uint32_t get_sd_find_debounce_time() const; // Trace configuration VSOMEIP_EXPORT std::shared_ptr get_trace() const; @@ -261,11 +263,10 @@ class configuration_impl: VSOMEIP_EXPORT bool is_tp_client( service_t _service, - const std::string &_address, std::uint16_t _port, + instance_t _instance, method_t _method) const; VSOMEIP_EXPORT bool is_tp_service( - service_t _service, const std::string &_ip_service, - std::uint16_t _port_service, method_t _method) const; + service_t _service, instance_t _instance, method_t _method) const; VSOMEIP_EXPORT void get_tp_configuration( service_t _service, instance_t _instance, method_t _method, bool _is_client, std::uint16_t &_max_segment_length, std::uint32_t &_separation_time) const; @@ -297,6 +298,8 @@ class configuration_impl: VSOMEIP_EXPORT bool is_security_audit() const; VSOMEIP_EXPORT bool is_remote_access_allowed() const; + VSOMEIP_EXPORT std::shared_ptr get_policy_manager() const; + VSOMEIP_EXPORT std::shared_ptr get_security() const; private: void read_data(const std::set &_input, std::vector &_elements, @@ -479,6 +482,9 @@ class configuration_impl: std::set mandatory_; + std::shared_ptr policy_manager_; + std::shared_ptr security_; + protected: // Configuration data boost::asio::ip::address unicast_; @@ -488,9 +494,9 @@ class configuration_impl: diagnosis_t diagnosis_; diagnosis_t diagnosis_mask_; - bool has_console_log_; - bool has_file_log_; - bool has_dlt_log_; + std::atomic_bool has_console_log_; + std::atomic_bool has_file_log_; + std::atomic_bool has_dlt_log_; std::string logfile_; mutable std::mutex mutex_loglevel_; vsomeip_v3::logger::level_e loglevel_; @@ -531,6 +537,7 @@ class configuration_impl: int32_t sd_cyclic_offer_delay_; int32_t sd_request_response_delay_; std::uint32_t sd_offer_debounce_time_; + std::uint32_t sd_find_debounce_time_; std::map > magic_cookies_; @@ -580,6 +587,7 @@ class configuration_impl: ET_TRACING_ENABLE, ET_TRACING_SD_ENABLE, ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME, + ET_SERVICE_DISCOVERY_FIND_DEBOUNCE_TIME, ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS, ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS, ET_ENDPOINT_QUEUE_LIMITS, @@ -598,7 +606,7 @@ class configuration_impl: ET_PARTITIONS, ET_SECURITY_AUDIT_MODE, ET_SECURITY_REMOTE_ACCESS, - ET_MAX = 45 + ET_MAX = 46 }; bool is_configured_[ET_MAX]; diff --git a/implementation/configuration/include/configuration_plugin.hpp b/implementation/configuration/include/configuration_plugin.hpp index 3ffc9683b..e9835a763 100644 --- a/implementation/configuration/include/configuration_plugin.hpp +++ b/implementation/configuration/include/configuration_plugin.hpp @@ -20,6 +20,7 @@ class configuration_plugin { virtual ~configuration_plugin() = default; virtual std::shared_ptr get_configuration( const std::string &_name, const std::string &_path) = 0; + virtual bool remove_configuration(const std::string &_name) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/configuration_plugin_impl.hpp b/implementation/configuration/include/configuration_plugin_impl.hpp index 3fcfbefcd..79c47b63b 100644 --- a/implementation/configuration/include/configuration_plugin_impl.hpp +++ b/implementation/configuration/include/configuration_plugin_impl.hpp @@ -29,13 +29,11 @@ class configuration_plugin_impl std::shared_ptr get_configuration(const std::string &_name, const std::string &_path); + bool remove_configuration(const std::string &_name); private: std::mutex mutex_; - std::shared_ptr default_; -#if 0 std::map > configurations_; -#endif }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index 1fcc6b41f..7a188fef4 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -96,12 +96,14 @@ #define VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE 1703936 -#define VSOMEIP_IO_THREAD_COUNT 2 -#define VSOMEIP_IO_THREAD_NICE_LEVEL 255 +#define VSOMEIP_DEFAULT_IO_THREAD_COUNT 2 +#define VSOMEIP_DEFAULT_IO_THREAD_NICE_LEVEL 0 #define VSOMEIP_MAX_DISPATCHERS 10 #define VSOMEIP_MAX_DISPATCH_TIME 100 +#define VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS 5 + #define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 #define VSOMEIP_DEFAULT_STATISTICS_MAX_MSG 50 #define VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ 50 @@ -152,8 +154,8 @@ inline constexpr std::uint32_t QUEUE_SIZE_UNLIMITED = (std::numeric_limits::max)(); -const std::uint32_t ANY_UID = 0xFFFFFFFF; -const std::uint32_t ANY_GID = 0xFFFFFFFF; +const uid_t ANY_UID = 0xFFFFFFFF; +const gid_t ANY_GID = 0xFFFFFFFF; enum class port_type_e { PT_OPTIONAL, diff --git a/implementation/configuration/include/internal_android.hpp b/implementation/configuration/include/internal_android.hpp index c3e8993d3..b9631b041 100644 --- a/implementation/configuration/include/internal_android.hpp +++ b/implementation/configuration/include/internal_android.hpp @@ -23,7 +23,10 @@ #define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/vendor/run/etc/vsomeip.json" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" -#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json,vsomeip_policy_extensions.json,vsomeip_portcfg.json" +#define VSOMEIP_MANDATORY_CONFIGURATION_FILES \ + "vsomeip_std.json,vsomeip_app.json,vsomeip_events.json,vsomeip_plc.json,vsomeip_log.json," \ + "vsomeip_security.json,vsomeip_whitelist.json,vsomeip_policy_extensions.json,vsomeip_portcfg." \ + "json" #define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/vendor/run/etc/vsomeip" #define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/" @@ -78,12 +81,14 @@ #define VSOMEIP_DEFAULT_UDP_RCV_BUFFER_SIZE 1703936 -#define VSOMEIP_IO_THREAD_COUNT 2 -#define VSOMEIP_IO_THREAD_NICE_LEVEL 255 +#define VSOMEIP_DEFAULT_IO_THREAD_COUNT 2 +#define VSOMEIP_DEFAULT_IO_THREAD_NICE_LEVEL 0 #define VSOMEIP_MAX_DISPATCHERS 10 #define VSOMEIP_MAX_DISPATCH_TIME 100 +#define VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS 5 + #define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 #define VSOMEIP_DEFAULT_STATISTICS_MAX_MSG 50 #define VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ 50 diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 380b29060..4e8215100 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "../include/client.hpp" #include "../include/configuration_impl.hpp" @@ -37,7 +38,6 @@ #include "../../routing/include/event.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../utility/include/utility.hpp" -#include "../../plugin/include/plugin_manager.hpp" #include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" @@ -68,6 +68,7 @@ configuration_impl::configuration_impl(const std::string &_path) sd_cyclic_offer_delay_(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY), sd_request_response_delay_(VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY), sd_offer_debounce_time_(VSOMEIP_SD_DEFAULT_OFFER_DEBOUNCE_TIME), + sd_find_debounce_time_(VSOMEIP_SD_DEFAULT_FIND_DEBOUNCE_TIME), max_configured_message_size_(0), max_local_message_size_(0), max_reliable_message_size_(0), @@ -107,17 +108,15 @@ configuration_impl::configuration_impl(const std::string &_path) is_security_audit_(false), is_remote_access_allowed_(true) { + policy_manager_ = std::make_shared(); + security_ = std::make_shared(policy_manager_); unicast_ = unicast_.from_string(VSOMEIP_UNICAST_ADDRESS); netmask_ = netmask_.from_string(VSOMEIP_NETMASK); for (auto i = 0; i < ET_MAX; i++) is_configured_[i] = false; #ifdef _WIN32 -#if VSOMEIP_BOOST_VERSION < 106600 - routing_.host_.unicast_ = boost::asio::ip::address::from_string("127.0.0.1"); -#else routing_.host_.unicast_ = boost::asio::ip::make_address("127.0.0.1"); -#endif routing_.host_.port_ = 31490; routing_.guests_.unicast_ = routing_.host_.unicast_; routing_.guests_.ports_[{ ANY_UID, ANY_GID }].emplace(31492, 31999); @@ -130,6 +129,9 @@ configuration_impl::configuration_impl(const configuration_impl &_other) is_loaded_(_other.is_loaded_), is_logging_loaded_(_other.is_logging_loaded_), mandatory_(_other.mandatory_), + has_console_log_(_other.has_console_log_.load()), + has_file_log_(_other.has_file_log_.load()), + has_dlt_log_(_other.has_dlt_log_.load()), max_configured_message_size_(_other.max_configured_message_size_), max_local_message_size_(_other.max_local_message_size_), max_reliable_message_size_(_other.max_reliable_message_size_), @@ -159,9 +161,6 @@ configuration_impl::configuration_impl(const configuration_impl &_other) diagnosis_ = _other.diagnosis_; diagnosis_mask_ = _other.diagnosis_mask_; - has_console_log_ = _other.has_console_log_; - has_file_log_ = _other.has_file_log_; - has_dlt_log_ = _other.has_dlt_log_; logfile_ = _other.logfile_; loglevel_ = _other.loglevel_; @@ -181,6 +180,7 @@ configuration_impl::configuration_impl(const configuration_impl &_other) sd_cyclic_offer_delay_= _other.sd_cyclic_offer_delay_; sd_request_response_delay_= _other.sd_request_response_delay_; sd_offer_debounce_time_ = _other.sd_offer_debounce_time_; + sd_find_debounce_time_ = _other.sd_find_debounce_time_; trace_ = std::make_shared(*_other.trace_.get()); supported_selective_addresses = _other.supported_selective_addresses; @@ -314,23 +314,24 @@ bool configuration_impl::load(const std::string &_name) { std::vector its_mandatory_elements; std::vector its_optional_elements; - // Dummy initialization; maybe we'll find no logging configuration - logger::logger_impl::init(shared_from_this()); - // Look for the standard configuration file read_data(its_input, its_mandatory_elements, its_failed, true); load_data(its_mandatory_elements, true, false); // If the configuration is incomplete, this is the routing manager configuration or // the routing is yet unknown, read the full set of configuration files - if (its_mandatory_elements.empty() || - _name == get_routing_host_name() || - "" == get_routing_host_name()) { + if (its_mandatory_elements.empty() || _name == get_routing_host_name() + || "" == get_routing_host_name()) { read_data(its_input, its_optional_elements, its_failed, false); load_data(its_mandatory_elements, false, true); load_data(its_optional_elements, true, true); } + // Dummy initialization; if logger configs were not found use default + if (!is_logging_loaded_) { + logger::logger_impl::init(shared_from_this()); + } + // Tell, if reading of configuration file(s) failed. // (This may file if the logger configuration is incomplete/missing). for (const auto& f : its_failed) @@ -362,7 +363,7 @@ bool configuration_impl::load(const std::string &_name) { bool configuration_impl::lazy_load_security(const std::string &_client_host) { bool result(false); - std::string its_folder = policy_manager_impl::get()->get_policy_extension_path(_client_host); + std::string its_folder = policy_manager_->get_policy_extension_path(_client_host); if (!its_folder.empty()) { std::set its_input; std::set its_failed; @@ -370,7 +371,7 @@ bool configuration_impl::lazy_load_security(const std::string &_client_host) { its_input.insert(its_folder); // load security configuration files from UID_GID sub folder if existing - std::string its_security_config_folder = policy_manager_impl::get()->get_security_config_folder(its_folder); + std::string its_security_config_folder = policy_manager_->get_security_config_folder(its_folder); if (!its_security_config_folder.empty()) its_input.insert(its_security_config_folder); @@ -378,7 +379,7 @@ bool configuration_impl::lazy_load_security(const std::string &_client_host) { read_data(its_input, its_mandatory_elements, its_failed, true, true); for (const auto& e : its_mandatory_elements) { - policy_manager_impl::get()->load(e, true); + policy_manager_->load(e, true); } for (auto f : its_failed) @@ -387,7 +388,7 @@ bool configuration_impl::lazy_load_security(const std::string &_client_host) { result = (its_failed.empty() && !its_mandatory_elements.empty()); if (result) - policy_manager_impl::get()->set_is_policy_extension_loaded(_client_host, true); + policy_manager_->set_is_policy_extension_loaded(_client_host, true); } return result; @@ -399,7 +400,7 @@ configuration_impl::check_routing_credentials( client_t _client, const vsomeip_sec_client_t *_sec_client) const { return (_client != get_id(routing_.host_.name_) || - VSOMEIP_SEC_OK == security::authenticate_router(_sec_client)); + VSOMEIP_SEC_OK == security_->authenticate_router(_sec_client)); } bool configuration_impl::remote_offer_info_add(service_t _service, @@ -412,7 +413,7 @@ bool configuration_impl::remote_offer_info_add(service_t _service, VSOMEIP_ERROR << __func__ << " shall only be called after normal" "configuration has been parsed"; } else { - std::shared_ptr its_service(std::make_shared()); + auto its_service = std::make_shared(); its_service->service_ = _service; its_service->instance_ = _instance; its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT; @@ -534,8 +535,8 @@ void configuration_impl::load_policy_data(const std::string &_input, bool _mandatory_only) { if (is_mandatory(_input) == _mandatory_only) { #ifndef VSOMEIP_DISABLE_SECURITY - if (policy_manager_impl::get()->is_policy_extension(_input)) { - policy_manager_impl::get()->set_policy_extension_base_path(_input); + if (policy_manager_->is_policy_extension(_input)) { + policy_manager_->set_policy_extension_base_path(_input); } #endif boost::property_tree::ptree its_tree; @@ -583,6 +584,7 @@ bool configuration_impl::load_data(const std::vector &_el load_security(e); load_tracing(e); load_udp_receive_buffer_size(e); + load_services(e); } } @@ -593,7 +595,6 @@ bool configuration_impl::load_data(const std::vector &_el load_device(e); load_service_discovery(e); load_npdu_default_timings(e); - load_services(e); load_internal_services(e); load_clients(e); load_watchdog(e); @@ -828,13 +829,8 @@ configuration_impl::load_routing_host(const boost::property_tree::ptree &_tree, has_gid = true; } } else if (its_key == "unicast") { -#if VSOMEIP_BOOST_VERSION < 106600 - routing_.host_.unicast_ - = boost::asio::ip::address::from_string(its_value); -#else routing_.host_.unicast_ = boost::asio::ip::make_address(its_value); -#endif } else if (its_key == "port") { std::stringstream its_converter; if (its_value.find("0x") == 0) { @@ -847,7 +843,7 @@ configuration_impl::load_routing_host(const boost::property_tree::ptree &_tree, } if (has_uid && has_gid) { - policy_manager_impl::get()->set_routing_credentials(its_uid, its_gid, _name); + policy_manager_->set_routing_credentials(its_uid, its_gid, _name); } } catch (...) { @@ -865,13 +861,8 @@ configuration_impl::load_routing_guests(const boost::property_tree::ptree &_tree std::string its_key(i->first); if (its_key == "unicast") { std::string its_value(i->second.data()); -#if VSOMEIP_BOOST_VERSION < 106600 - routing_.guests_.unicast_ - = boost::asio::ip::address::from_string(its_value); -#else routing_.guests_.unicast_ = boost::asio::ip::make_address(its_value); -#endif } else if (its_key == "ports") { load_routing_guest_ports(i->second); } @@ -991,10 +982,11 @@ void configuration_impl::load_application_data( client_t its_id(VSOMEIP_CLIENT_UNSET); std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS); std::size_t its_max_dispatch_time(VSOMEIP_MAX_DISPATCH_TIME); - std::size_t its_io_thread_count(VSOMEIP_IO_THREAD_COUNT); + std::size_t its_max_detached_thread_wait_time(VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS); + std::size_t its_io_thread_count(VSOMEIP_DEFAULT_IO_THREAD_COUNT); std::size_t its_request_debounce_time(VSOMEIP_REQUEST_DEBOUNCE_TIME); std::map> plugins; - int its_io_thread_nice_level(VSOMEIP_IO_THREAD_NICE_LEVEL); + int its_io_thread_nice_level(VSOMEIP_DEFAULT_IO_THREAD_NICE_LEVEL); debounce_configuration_t its_debounces; bool has_session_handling(true); for (auto i = _tree.begin(); i != _tree.end(); ++i) { @@ -1016,6 +1008,9 @@ void configuration_impl::load_application_data( } else if (its_key == "max_dispatch_time") { its_converter << std::dec << its_value; its_converter >> its_max_dispatch_time; + } else if (its_key == "max_detached_thread_wait_time") { + its_converter << std::dec << its_value; + its_converter >> its_max_detached_thread_wait_time; } else if (its_key == "threads") { its_converter << std::dec << its_value; its_converter >> its_io_thread_count; @@ -1046,8 +1041,7 @@ void configuration_impl::load_application_data( } catch (...) { // intentionally empty } - } - else if (its_key == "has_session_handling") { + } else if (its_key == "has_session_handling") { has_session_handling = (its_value != "false"); } } @@ -1065,17 +1059,16 @@ void configuration_impl::load_application_data( } } - applications_[its_name] = { - its_id, - its_max_dispatchers, - its_max_dispatch_time, - its_io_thread_count, - its_request_debounce_time, - plugins, - its_io_thread_nice_level, - its_debounces - , has_session_handling - }; + applications_[its_name] = {its_id, + its_max_dispatchers, + its_max_dispatch_time, + its_max_detached_thread_wait_time, + its_io_thread_count, + its_request_debounce_time, + plugins, + its_io_thread_nice_level, + its_debounces, + has_session_handling}; } else { VSOMEIP_WARNING << "Multiple configurations for application " << its_name << ". Ignoring a configuration from " @@ -1225,7 +1218,7 @@ void configuration_impl::load_trace_channels( void configuration_impl::load_trace_channel( const boost::property_tree::ptree &_tree) { - std::shared_ptr its_channel = std::make_shared(); + auto its_channel = std::make_shared(); for(auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key = i->first; std::string its_value = i->second.data(); @@ -1251,7 +1244,7 @@ void configuration_impl::load_trace_filters( void configuration_impl::load_trace_filter( const boost::property_tree::ptree &_tree) { - std::shared_ptr its_filter = std::make_shared(); + auto its_filter = std::make_shared(); bool has_channel(false); for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key = i->first; @@ -1841,6 +1834,15 @@ void configuration_impl::load_service_discovery( its_converter >> sd_offer_debounce_time_; is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME] = true; } + } else if (its_key == "find_debounce_time") { + if (is_configured_[ET_SERVICE_DISCOVERY_FIND_DEBOUNCE_TIME]) { + VSOMEIP_WARNING << "Multiple definitions for service_discovery.find_debounce." + " Ignoring definition from " << _element.name_; + } else { + its_converter << its_value; + its_converter >> sd_find_debounce_time_; + is_configured_[ET_SERVICE_DISCOVERY_FIND_DEBOUNCE_TIME] = true; + } } else if (its_key == "ttl_factor_offers") { if (is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl_factor_offers." @@ -2009,7 +2011,7 @@ void configuration_impl::load_service( bool is_loaded(true); bool use_magic_cookies(false); - std::shared_ptr its_service(std::make_shared()); + auto its_service = std::make_shared(); its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT; its_service->unicast_address_ = _unicast_address; its_service->multicast_address_ = ""; @@ -2206,7 +2208,7 @@ void configuration_impl::load_event( ? "RT_RELIABLE" : "RT_UNRELIABLE"); } - std::shared_ptr its_event = std::make_shared( + auto its_event = std::make_shared( its_event_id, its_is_field, its_reliability, its_cycle, its_change_resets_cycle, its_update_on_change); @@ -2220,7 +2222,7 @@ void configuration_impl::load_eventgroup( std::shared_ptr &_service, const boost::property_tree::ptree &_tree) { for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::shared_ptr its_eventgroup = + auto its_eventgroup = std::make_shared(); for (auto j = i->second.begin(); j != i->second.end(); ++j) { std::stringstream its_converter; @@ -2378,7 +2380,7 @@ void configuration_impl::load_clients(const configuration_element &_element) { void configuration_impl::load_client(const boost::property_tree::ptree &_tree) { try { - std::shared_ptr its_client(std::make_shared()); + auto its_client = std::make_shared(); its_client->remote_ports_[true] = std::make_pair(ILLEGAL_PORT, ILLEGAL_PORT); its_client->remote_ports_[false] = std::make_pair(ILLEGAL_PORT, ILLEGAL_PORT); its_client->client_ports_[true] = std::make_pair(ILLEGAL_PORT, ILLEGAL_PORT); @@ -2531,7 +2533,7 @@ void configuration_impl::load_payload_sizes(const configuration_element &_elemen const std::string size_str(_element.tree_.get_child(s).data()); try { // add 16 Byte for the SOME/IP header - const std::uint32_t its_size = static_cast( + const auto its_size = static_cast( std::stoul(size_str.c_str(), NULL, 10) + 16); if (s == max_local_payload_size) { max_local_message_size_ = its_size; @@ -2701,7 +2703,7 @@ void configuration_impl::load_security(const configuration_element &_element) { #ifndef VSOMEIP_DISABLE_SECURITY if (!is_security_external()) - policy_manager_impl::get()->load(_element); + policy_manager_->load(_element); #endif // !VSOMEIP_DISABLE_SECURITY } @@ -3141,7 +3143,7 @@ std::size_t configuration_impl::get_request_debouncing(const std::string &_name) } std::size_t configuration_impl::get_io_thread_count(const std::string &_name) const { - std::size_t its_io_thread_count = VSOMEIP_IO_THREAD_COUNT; + std::size_t its_io_thread_count = VSOMEIP_DEFAULT_IO_THREAD_COUNT; auto found_application = applications_.find(_name); if (found_application != applications_.end()) { @@ -3152,7 +3154,7 @@ std::size_t configuration_impl::get_io_thread_count(const std::string &_name) co } int configuration_impl::get_io_thread_nice_level(const std::string &_name) const { - int its_io_thread_nice_level = VSOMEIP_IO_THREAD_NICE_LEVEL; + int its_io_thread_nice_level = VSOMEIP_DEFAULT_IO_THREAD_NICE_LEVEL; auto found_application = applications_.find(_name); if (found_application != applications_.end()) { @@ -3187,6 +3189,17 @@ std::size_t configuration_impl::get_max_dispatch_time( return its_max_dispatch_time; } +std::size_t configuration_impl::get_max_detached_thread_wait_time(const std::string& _name) const { + std::size_t its_max_detached_thread_wait_time = VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS; + + if (auto found_application = applications_.find(_name); + found_application != applications_.end()) { + its_max_detached_thread_wait_time = found_application->second.max_detach_thread_wait_time_; + } + + return its_max_detached_thread_wait_time; +} + bool configuration_impl::has_session_handling(const std::string &_name) const { bool its_value(true); @@ -3680,6 +3693,10 @@ std::uint32_t configuration_impl::get_sd_offer_debounce_time() const { return sd_offer_debounce_time_; } +std::uint32_t configuration_impl::get_sd_find_debounce_time() const { + return sd_find_debounce_time_; +} + // Trace configuration std::shared_ptr configuration_impl::get_trace() const { return trace_; @@ -4416,7 +4433,7 @@ void configuration_impl::load_someip_tp_for_service( // Segment length must be multiple of 16 // Ensure this by subtracting the rest - std::uint16_t its_rest = std::uint16_t(its_max_segment_length % 16); + auto its_rest = std::uint16_t(its_max_segment_length % 16); if (its_rest != 0) { VSOMEIP_WARNING << "SOMEIP/TP: max-segment-length must be multiple of 16. Corrected " << std::dec << its_max_segment_length << " to " @@ -4879,13 +4896,13 @@ int configuration_impl::get_udp_receive_buffer_size() const { bool configuration_impl::is_tp_client( service_t _service, - const std::string &_address, std::uint16_t _port, + instance_t _instance, method_t _method) const { bool ret(false); const auto its_service - = find_service(_service, _address, _port); + = find_service(_service, _instance); if (its_service) { ret = (its_service->tp_client_config_.find(_method) @@ -4897,12 +4914,12 @@ bool configuration_impl::is_tp_client( bool configuration_impl::is_tp_service( service_t _service, - const std::string &_address, std::uint16_t _port, + instance_t _instance, method_t _method) const { bool ret(false); const auto its_service - = find_service(_service, _address, _port); + = find_service(_service, _instance); if (its_service) { ret = (its_service->tp_service_config_.find(_method) != its_service->tp_service_config_.end()); @@ -5040,5 +5057,13 @@ configuration_impl::is_remote_access_allowed() const { return is_remote_access_allowed_; } +std::shared_ptr configuration_impl::get_policy_manager() const { + return policy_manager_; +} + +std::shared_ptr configuration_impl::get_security() const { + return security_; +} + } // namespace cfg } // namespace vsomeip_v3 diff --git a/implementation/configuration/src/configuration_plugin_impl.cpp b/implementation/configuration/src/configuration_plugin_impl.cpp index 89f47b6d0..cf84520b7 100644 --- a/implementation/configuration/src/configuration_plugin_impl.cpp +++ b/implementation/configuration/src/configuration_plugin_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2024 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/. @@ -25,15 +25,8 @@ std::shared_ptr configuration_plugin_impl::get_configuration(const std::string &_name, const std::string &_path) { - std::lock_guard its_lock(mutex_); - if (!default_) { - default_ = std::make_shared(_path); - default_->load(_name); - } - return default_; - -#if 0 std::shared_ptr its_configuration; + std::scoped_lock its_lock(mutex_); auto its_iterator = configurations_.find(_name); if (its_iterator != configurations_.end()) { its_configuration = its_iterator->second; @@ -44,7 +37,10 @@ configuration_plugin_impl::get_configuration(const std::string &_name, } return its_configuration; -#endif } +bool configuration_plugin_impl::remove_configuration(const std::string & _name) { + std::scoped_lock its_lock(mutex_); + return configurations_.erase(_name) > 0; +} } // namespace vsomeip_v3 diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp index 5e729766b..3e655f1d5 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp @@ -8,7 +8,7 @@ #include #include "../../../../include/e2e/profile/profile04/checker.hpp" -#include "../../../../../utility/include/byteorder.hpp" +#include "../../../../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace e2e { @@ -92,8 +92,7 @@ bool profile_04_checker::read_16(const e2e_buffer &_buffer, uint16_t &_data, size_t _index) const { - _data = VSOMEIP_BYTES_TO_WORD(_buffer[config_.offset_ + _index], - _buffer[config_.offset_ + _index + 1]); + _data = bithelper::read_uint16_be(&_buffer[config_.offset_ + _index]); return true; } @@ -101,10 +100,7 @@ bool profile_04_checker::read_32(const e2e_buffer &_buffer, uint32_t &_data, size_t _index) const { - _data = VSOMEIP_BYTES_TO_LONG(_buffer[config_.offset_ + _index], - _buffer[config_.offset_ + _index + 1], - _buffer[config_.offset_ + _index + 2], - _buffer[config_.offset_ + _index + 3]); + _data = bithelper::read_uint32_be(&_buffer[config_.offset_ + _index]); return true; } diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp index 2f9899c4c..e6abf84b9 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp @@ -7,7 +7,7 @@ #include #include "../../../../include/e2e/profile/profile04/protector.hpp" -#include "../../../../../utility/include/byteorder.hpp" +#include "../../../../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace e2e { @@ -27,20 +27,20 @@ protector::protect(e2e_buffer &_buffer, instance_t _instance) { if (verify_inputs(_buffer)) { /** @req [SWS_E2E_00364] */ - write_16(_buffer, static_cast(_buffer.size()), 0); + bithelper::write_uint16_be(static_cast(_buffer.size()), &_buffer[config_.offset_]); /** @req [SWS_E2E_00365] */ - write_16(_buffer, get_counter(_instance), 2); + bithelper::write_uint16_be(get_counter(_instance), &_buffer[config_.offset_ + 2]); /** @req [SWS_E2E_00366] */ uint32_t its_data_id(uint32_t(_instance) << 24 | config_.data_id_); - write_32(_buffer, its_data_id, 4); + bithelper::write_uint32_be(its_data_id, &_buffer[config_.offset_ + 4]); /** @req [SWS_E2E_00367] */ uint32_t its_crc = profile_04::compute_crc(config_, _buffer); /** @req [SWS_E2E_0368] */ - write_32(_buffer, its_crc, 8); + bithelper::write_uint32_be(its_crc, &_buffer[config_.offset_ + 8]); /** @req [SWS_E2E_00369] */ increment_counter(_instance); @@ -54,22 +54,6 @@ protector::verify_inputs(e2e_buffer &_buffer) { && _buffer.size() <= config_.max_data_length_); } -void -protector::write_16(e2e_buffer &_buffer, uint16_t _data, size_t _index) { - - _buffer[config_.offset_ + _index] = VSOMEIP_WORD_BYTE1(_data); - _buffer[config_.offset_ + _index + 1] = VSOMEIP_WORD_BYTE0(_data); -} - -void -protector::write_32(e2e_buffer &_buffer, uint32_t _data, size_t _index) { - - _buffer[config_.offset_ + _index] = VSOMEIP_LONG_BYTE3(_data); - _buffer[config_.offset_ + _index + 1] = VSOMEIP_LONG_BYTE2(_data); - _buffer[config_.offset_ + _index + 2] = VSOMEIP_LONG_BYTE1(_data); - _buffer[config_.offset_ + _index + 3] = VSOMEIP_LONG_BYTE0(_data); -} - uint16_t protector::get_counter(instance_t _instance) const { diff --git a/implementation/e2e_protection/src/e2e/profile/profile05/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile05/checker.cpp index bb943ba72..964b73ac5 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile05/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile05/checker.cpp @@ -8,7 +8,7 @@ #include #include "../../../../include/e2e/profile/profile05/checker.hpp" -#include "../../../../../utility/include/byteorder.hpp" +#include "../../../../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace e2e { @@ -78,8 +78,7 @@ bool profile_05_checker::read_16(const e2e_buffer &_buffer, uint16_t &_data, size_t _index) const { - _data = VSOMEIP_BYTES_TO_WORD(_buffer[config_.offset_ + _index + 1], - _buffer[config_.offset_ + _index]); + _data = bithelper::read_uint16_be(&_buffer[config_.offset_ + _index]); return true; } diff --git a/implementation/e2e_protection/src/e2e/profile/profile05/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile05/protector.cpp index f8ab9de4e..46843a6d4 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile05/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile05/protector.cpp @@ -7,7 +7,7 @@ #include #include "../../../../include/e2e/profile/profile05/protector.hpp" -#include "../../../../../utility/include/byteorder.hpp" +#include "../../../../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace e2e { @@ -30,8 +30,7 @@ void protector::protect(e2e_buffer &_buffer, instance_t _instance) { // compute the CRC uint16_t its_crc = profile_05::compute_crc(config_, _buffer); - - write_crc(_buffer, its_crc, 0); + bithelper::write_uint16_be(its_crc, &_buffer[config_.offset_]); // increment the Counter (new value will be used in the next invocation of E2E_P05Protect()), increment_counter(_instance); @@ -44,13 +43,6 @@ protector::write_counter(e2e_buffer &_buffer, uint8_t _data, size_t _index) { _buffer[config_.offset_ + _index] = _data; } -void -protector::write_crc(e2e_buffer &_buffer, uint16_t _data, size_t _index) { - - _buffer[config_.offset_ + _index] = VSOMEIP_WORD_BYTE0(_data); - _buffer[config_.offset_ + _index + 1] = VSOMEIP_WORD_BYTE1(_data); -} - uint8_t protector::get_counter(instance_t _instance) const { diff --git a/implementation/e2e_protection/src/e2e/profile/profile07/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile07/checker.cpp index f069046bc..eab7439e7 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile07/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile07/checker.cpp @@ -8,7 +8,7 @@ #include #include "../../../../include/e2e/profile/profile07/checker.hpp" -#include "../../../../../utility/include/byteorder.hpp" +#include "../../../../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace e2e { @@ -87,26 +87,16 @@ bool profile_07_checker::read_32(const e2e_buffer &_buffer, uint32_t &_data, size_t _index) const { - _data = VSOMEIP_BYTES_TO_LONG(_buffer[config_.offset_ + _index], - _buffer[config_.offset_ + _index + 1], - _buffer[config_.offset_ + _index + 2], - _buffer[config_.offset_ + _index + 3]); + _data = bithelper::read_uint32_be(&_buffer[config_.offset_ + _index]); return true; } // Read uint64_t as big-endian bool -profile_07_checker::read_64(const e2e_buffer &_buffer, +profile_07_checker::read_64(const e2e_buffer &_buffer, uint64_t &_data, size_t _index) const { - _data = VSOMEIP_BYTES_TO_LONG_LONG(_buffer[config_.offset_ + _index], - _buffer[config_.offset_ + _index + 1], - _buffer[config_.offset_ + _index + 2], - _buffer[config_.offset_ + _index + 3], - _buffer[config_.offset_ + _index + 4], - _buffer[config_.offset_ + _index + 5], - _buffer[config_.offset_ + _index + 6], - _buffer[config_.offset_ + _index + 7]); + _data = bithelper::read_uint64_be(&_buffer[config_.offset_ + _index]); return true; } diff --git a/implementation/e2e_protection/src/e2e/profile/profile07/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile07/protector.cpp index 311bc5ad5..b470245ac 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile07/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile07/protector.cpp @@ -7,7 +7,7 @@ #include #include "../../../../include/e2e/profile/profile07/protector.hpp" -#include "../../../../../utility/include/byteorder.hpp" +#include "../../../../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace e2e { @@ -22,19 +22,19 @@ protector::protect(e2e_buffer &_buffer, instance_t _instance) { if (verify_inputs(_buffer)) { /** @req [SWS_E2E_00489] */ - write_32(_buffer, static_cast(_buffer.size()), PROFILE_07_SIZE_OFFSET); + bithelper::write_uint32_be(static_cast(_buffer.size()), &_buffer[config_.offset_ + PROFILE_07_SIZE_OFFSET]); /** @req [SWS_E2E_00490] */ - write_32(_buffer, get_counter(_instance), PROFILE_07_COUNTER_OFFSET); + bithelper::write_uint32_be(get_counter(_instance), &_buffer[config_.offset_ + PROFILE_07_COUNTER_OFFSET]); /** @req [SWS_E2E_00491] */ - write_32(_buffer, config_.data_id_, PROFILE_07_DATAID_OFFSET); + bithelper::write_uint32_be(config_.data_id_, &_buffer[config_.offset_ + PROFILE_07_DATAID_OFFSET]); /** @req [SWS_E2E_00492] */ uint64_t its_crc = profile_07::compute_crc(config_, _buffer); /** @req [SWS_E2E_00493] */ - write_64(_buffer, its_crc, PROFILE_07_CRC_OFFSET); + bithelper::write_uint64_be(its_crc, &_buffer[config_.offset_ + PROFILE_07_CRC_OFFSET]); /** @req [SWS_E2E_00494] */ increment_counter(_instance); @@ -48,30 +48,6 @@ protector::verify_inputs(e2e_buffer &_buffer) { && _buffer.size() <= config_.max_data_length_); } -// Write uint32_t as big-endian -void -protector::write_32(e2e_buffer &_buffer, uint32_t _data, size_t _index) { - - _buffer[config_.offset_ + _index] = VSOMEIP_LONG_BYTE3(_data); - _buffer[config_.offset_ + _index + 1] = VSOMEIP_LONG_BYTE2(_data); - _buffer[config_.offset_ + _index + 2] = VSOMEIP_LONG_BYTE1(_data); - _buffer[config_.offset_ + _index + 3] = VSOMEIP_LONG_BYTE0(_data); -} - -// Write uint64_t as big-endian -void -protector::write_64(e2e_buffer &_buffer, uint64_t _data, size_t _index) { - - _buffer[config_.offset_ + _index] = VSOMEIP_LONG_LONG_BYTE7(_data); - _buffer[config_.offset_ + _index + 1] = VSOMEIP_LONG_LONG_BYTE6(_data); - _buffer[config_.offset_ + _index + 2] = VSOMEIP_LONG_LONG_BYTE5(_data); - _buffer[config_.offset_ + _index + 3] = VSOMEIP_LONG_LONG_BYTE4(_data); - _buffer[config_.offset_ + _index + 4] = VSOMEIP_LONG_LONG_BYTE3(_data); - _buffer[config_.offset_ + _index + 5] = VSOMEIP_LONG_LONG_BYTE2(_data); - _buffer[config_.offset_ + _index + 6] = VSOMEIP_LONG_LONG_BYTE1(_data); - _buffer[config_.offset_ + _index + 7] = VSOMEIP_LONG_LONG_BYTE0(_data); -} - uint32_t protector::get_counter(instance_t _instance) const { diff --git a/implementation/endpoints/include/buffer.hpp b/implementation/endpoints/include/buffer.hpp index 86d03bea6..32429be60 100644 --- a/implementation/endpoints/include/buffer.hpp +++ b/implementation/endpoints/include/buffer.hpp @@ -11,12 +11,7 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -#define io_context io_service -#else -# include -#endif +#include #include #include diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp index 92c69aa82..42cc53a36 100644 --- a/implementation/endpoints/include/client_endpoint_impl.hpp +++ b/implementation/endpoints/include/client_endpoint_impl.hpp @@ -25,7 +25,6 @@ #include "client_endpoint.hpp" #include "tp.hpp" - namespace vsomeip_v3 { class endpoint; @@ -42,8 +41,6 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, boost::asio::io_context &_io, - std::uint32_t _max_message_size, - configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); virtual ~client_endpoint_impl(); @@ -153,7 +150,8 @@ class client_endpoint_impl: public endpoint_impl, public client_endpoi virtual void set_local_port() = 0; virtual std::string get_remote_information() const = 0; virtual bool tp_segmentation_enabled(service_t _service, - method_t _method) const = 0; + instance_t _instance, + method_t _method) const; virtual std::uint32_t get_max_allowed_reconnects() const = 0; virtual void max_allowed_reconnects_reached() = 0; void send_segments(const tp::tp_split_messages_t &_segments, diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index 82347d9b3..550fa28e4 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -20,14 +20,16 @@ class endpoint_definition; class endpoint { public: typedef std::function error_handler_t; - typedef std::function&, service_t)> prepare_stop_handler_t; + typedef std::function &)> prepare_stop_handler_t; - virtual ~endpoint() {} + virtual ~endpoint() = default; virtual void start() = 0; + virtual void restart(bool _force = false) = 0; + virtual void stop() = 0; + virtual void prepare_stop(const prepare_stop_handler_t &_handler, service_t _service = ANY_SERVICE) = 0; - virtual void stop() = 0; virtual bool is_established() const = 0; virtual bool is_established_or_connected() const = 0; @@ -50,12 +52,6 @@ class endpoint { virtual bool is_reliable() const = 0; virtual bool is_local() const = 0; - virtual void increment_use_count() = 0; - virtual void decrement_use_count() = 0; - virtual uint32_t get_use_count() = 0; - - virtual void restart(bool _force = false) = 0; - virtual void register_error_handler(const error_handler_t &_error) = 0; virtual void print_status() = 0; diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index 685eba4e0..598174dd0 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -28,16 +28,11 @@ class endpoint_impl: public virtual endpoint { typedef typename Protocol::endpoint endpoint_type; endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_context &_io, - std::uint32_t _max_message_size, - configuration::endpoint_queue_limit_t _queue_limit, + const std::shared_ptr& _routing_host, boost::asio::io_context& _io, const std::shared_ptr& _configuration); endpoint_impl(endpoint_impl const&) = delete; endpoint_impl(endpoint_impl const&&) = delete; - - virtual ~endpoint_impl(); + virtual ~endpoint_impl() = default; void enable_magic_cookies(); @@ -49,10 +44,6 @@ class endpoint_impl: public virtual endpoint { virtual void set_local_port(uint16_t _port) = 0; virtual bool is_reliable() const = 0; - void increment_use_count(); - void decrement_use_count(); - uint32_t get_use_count(); - void register_error_handler(const error_handler_t &_error_handler); virtual void print_status() = 0; @@ -100,7 +91,7 @@ class endpoint_impl: public virtual endpoint { error_handler_t error_handler_; std::mutex error_handler_mutex_; - const configuration::endpoint_queue_limit_t queue_limit_; + configuration::endpoint_queue_limit_t queue_limit_; std::shared_ptr configuration_; diff --git a/implementation/endpoints/include/endpoint_manager_base.hpp b/implementation/endpoints/include/endpoint_manager_base.hpp index fec39cce0..295e25c13 100644 --- a/implementation/endpoints/include/endpoint_manager_base.hpp +++ b/implementation/endpoints/include/endpoint_manager_base.hpp @@ -12,13 +12,7 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif - +#include #include #include "endpoint.hpp" @@ -73,6 +67,9 @@ class endpoint_manager_base // Multicast options void add_multicast_option(const multicast_option_t &_option); + virtual void suspend(void); + virtual void resume(void); + protected: std::map> get_local_endpoints() const; diff --git a/implementation/endpoints/include/endpoint_manager_impl.hpp b/implementation/endpoints/include/endpoint_manager_impl.hpp index 56acc8993..403a709b1 100644 --- a/implementation/endpoints/include/endpoint_manager_impl.hpp +++ b/implementation/endpoints/include/endpoint_manager_impl.hpp @@ -112,6 +112,9 @@ class endpoint_manager_impl : public endpoint_manager_base { // add join/leave options void add_multicast_option(const multicast_option_t &_option); + void suspend(void); + void resume(void); + private: std::shared_ptr find_remote_client(service_t _service, instance_t _instance, @@ -126,6 +129,8 @@ class endpoint_manager_impl : public endpoint_manager_base { // process join/leave options void process_multicast_options(); + bool is_used_endpoint(endpoint* const _endpoint) const; + private: mutable std::recursive_mutex endpoint_mutex_; // Client endpoints for remote services @@ -136,16 +141,11 @@ class endpoint_manager_impl : public endpoint_manager_base { std::map>>> remote_services_t; remote_services_t remote_services_; - typedef std::map - > - > - > - > client_endpoints_by_ip_t; - client_endpoints_by_ip_t client_endpoints_by_ip_; + using client_endpoints_t = + std::map>>>>; + client_endpoints_t client_endpoints_; std::map > service_instances_; std::map > service_instances_multicast_; @@ -158,12 +158,11 @@ class endpoint_manager_impl : public endpoint_manager_base { std::mutex used_client_ports_mutex_; // Server endpoints for local services - typedef std::map>> server_endpoints_t; + using server_endpoints_t = std::map>>; server_endpoints_t server_endpoints_; // Multicast endpoint info (notifications) - std::map>> multicast_info; + std::map>> multicast_info_; // Socket option processing (join, leave) std::mutex options_mutex_; diff --git a/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp b/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp index b1d8991da..b911eb0cd 100644 --- a/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp +++ b/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp @@ -6,7 +6,6 @@ #ifndef VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ #define VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ -#if VSOMEIP_BOOST_VERSION >= 106600 #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) #include @@ -50,13 +49,13 @@ struct storage : }; inline -std::function +std::function receive_cb (std::shared_ptr _data) { return [_data](boost::system::error_code _error) { if (!_error) { if (!_data->socket_.native_non_blocking()) _data->socket_.native_non_blocking(true, _error); - + #if defined(__linux__) for (;;) { ssize_t its_result; int its_flags(0); @@ -77,7 +76,7 @@ receive_cb (std::shared_ptr _data) { control_un.cmh.cmsg_type = SCM_CREDENTIALS; // Build header with all informations to call ::recvmsg - msghdr its_header = msghdr(); + auto its_header = msghdr(); its_header.msg_iov = its_vec; its_header.msg_iovlen = 1; its_header.msg_control = control_un.control; @@ -126,6 +125,7 @@ receive_cb (std::shared_ptr _data) { break; } + #endif } // Call the handler @@ -137,6 +137,5 @@ receive_cb (std::shared_ptr _data) { } // namespace vsomeip #endif // __linux__ || ANDROID -#endif // VSOMEIP_BOOST_VERSION >= 106600 #endif // VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ diff --git a/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp index 9ea300756..413e88a17 100644 --- a/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp @@ -26,8 +26,7 @@ class local_tcp_client_endpoint_impl: public local_tcp_client_endpoint_base_impl const endpoint_type &_remote, boost::asio::io_context &_io, const std::shared_ptr &_configuration); - - virtual ~local_tcp_client_endpoint_impl(); + virtual ~local_tcp_client_endpoint_impl() = default; void start(); void stop(); @@ -60,7 +59,6 @@ class local_tcp_client_endpoint_impl: public local_tcp_client_endpoint_base_impl void set_local_port(); std::string get_remote_information() const; bool check_packetizer_space(std::uint32_t _size); - bool tp_segmentation_enabled(service_t _service, method_t _method) const; std::uint32_t get_max_allowed_reconnects() const; void max_allowed_reconnects_reached(); diff --git a/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp index 49b6fcb77..1008c1a7f 100644 --- a/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp @@ -30,12 +30,13 @@ class local_tcp_server_endpoint_impl public: local_tcp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, const std::shared_ptr& _configuration, bool _is_routing_endpoint); + virtual ~local_tcp_server_endpoint_impl() = default; - virtual ~local_tcp_server_endpoint_impl(); + void init(const endpoint_type& _local, boost::system::error_code& _error); + void deinit(); void start(); void stop(); @@ -149,6 +150,7 @@ class local_tcp_server_endpoint_impl const bool is_routing_endpoint_; private: + void init_unlocked(const endpoint_type& _local, boost::system::error_code& _error); bool add_connection(const client_t &_client, const std::shared_ptr &_connection); void remove_connection(const client_t &_client); @@ -162,7 +164,6 @@ class local_tcp_server_endpoint_impl bool check_packetizer_space(target_data_iterator_type _queue_iterator, message_buffer_ptr_t* _packetizer, std::uint32_t _size); - bool tp_segmentation_enabled(service_t _service, method_t _method) const; void send_client_identifier(const client_t &_client); }; diff --git a/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp b/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp index e1e1aaa23..0c218c040 100644 --- a/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp @@ -59,7 +59,6 @@ class local_uds_client_endpoint_impl: public local_uds_client_endpoint_base_impl void set_local_port(); std::string get_remote_information() const; bool check_packetizer_space(std::uint32_t _size); - bool tp_segmentation_enabled(service_t _service, method_t _method) const; std::uint32_t get_max_allowed_reconnects() const; void max_allowed_reconnects_reached(); diff --git a/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp b/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp index a4ed2eb57..a0d8bde1e 100644 --- a/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp @@ -11,12 +11,7 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -#else -# include -#endif - +#include #include #include @@ -25,33 +20,22 @@ namespace vsomeip_v3 { -typedef server_endpoint_impl< -#if VSOMEIP_BOOST_VERSION < 106600 - boost::asio::local::stream_protocol_ext -#else - boost::asio::local::stream_protocol -#endif - > local_uds_server_endpoint_base_impl; +typedef server_endpoint_impl + local_uds_server_endpoint_base_impl; class local_uds_server_endpoint_impl: public local_uds_server_endpoint_base_impl { public: local_uds_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_context &_io, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint); - - local_uds_server_endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, - int native_socket, const std::shared_ptr& _configuration, bool _is_routing_endpoint); - virtual ~local_uds_server_endpoint_impl() = default; + void init(const endpoint_type& _local, boost::system::error_code& _error); + void init(const endpoint_type& _local, const int _socket, boost::system::error_code& _error); + void deinit(); + void start(); void stop(); @@ -158,11 +142,7 @@ class local_uds_server_endpoint_impl: public local_uds_server_endpoint_base_impl }; std::mutex acceptor_mutex_; -#if VSOMEIP_BOOST_VERSION < 106600 - boost::asio::local::stream_protocol_ext::acceptor acceptor_; -#else boost::asio::local::stream_protocol::acceptor acceptor_; -#endif typedef std::map connections_t; std::mutex connections_mutex_; connections_t connections_; @@ -172,6 +152,7 @@ class local_uds_server_endpoint_impl: public local_uds_server_endpoint_base_impl const bool is_routing_endpoint_; private: + void init_helper(const endpoint_type& _local, boost::system::error_code& _error); bool add_connection(const client_t &_client, const std::shared_ptr &_connection); void remove_connection(const client_t &_client); @@ -185,7 +166,6 @@ class local_uds_server_endpoint_impl: public local_uds_server_endpoint_base_impl bool check_packetizer_space(target_data_iterator_type _queue_iterator, message_buffer_ptr_t* _packetizer, std::uint32_t _size); - bool tp_segmentation_enabled(service_t _service, method_t _method) const; void send_client_identifier(const client_t &_client); }; diff --git a/implementation/endpoints/include/server_endpoint_impl.hpp b/implementation/endpoints/include/server_endpoint_impl.hpp index b543d97b4..1037401e7 100644 --- a/implementation/endpoints/include/server_endpoint_impl.hpp +++ b/implementation/endpoints/include/server_endpoint_impl.hpp @@ -18,6 +18,9 @@ #include "buffer.hpp" #include "endpoint_impl.hpp" #include "tp.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif namespace vsomeip_v3 { @@ -35,17 +38,18 @@ class server_endpoint_impl: public endpoint_impl, queue_size_(0), is_sending_(false), sent_timer_(_io), - io_(_io) { + io_(_io) { } endpoint_data_type(const endpoint_data_type &&_source) - : train_(_source.train_), - dispatch_timer_(std::make_shared(_source.io_)), - has_last_departure_(_source.has_last_departure_), - queue_size_(_source.queue_size_), - is_sending_(_source.is_sending_), - sent_timer_(_source.io_), - io_(_source.io_) { + : train_(_source.train_), + dispatch_timer_(std::make_shared(_source.io_)), + has_last_departure_(_source.has_last_departure_), + queue_(_source.queue_), + queue_size_(_source.queue_size_), + is_sending_(_source.is_sending_), + sent_timer_(_source.io_), + io_(_source.io_) { } std::shared_ptr train_; @@ -69,11 +73,12 @@ class server_endpoint_impl: public endpoint_impl, server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - endpoint_type _local, boost::asio::io_context &_io, - std::uint32_t _max_message_size, - configuration::endpoint_queue_limit_t _queue_limit, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); - virtual ~server_endpoint_impl(); + virtual ~server_endpoint_impl() = default; + + virtual void init(const endpoint_type& _local, boost::system::error_code& _error) = 0; + virtual void stop(); bool is_client() const; void restart(bool _force); @@ -87,7 +92,6 @@ class server_endpoint_impl: public endpoint_impl, void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); - virtual void stop(); bool flush(endpoint_type _it); size_t get_queue_size() const; @@ -122,7 +126,7 @@ class server_endpoint_impl: public endpoint_impl, const std::uint8_t * const _data, std::uint32_t _size, const endpoint_type &_target); bool check_queue_limit(const uint8_t *_data, std::uint32_t _size, - std::size_t _current_queue_size) const; + endpoint_data_type &_endpoint_data) const; bool queue_train(const target_data_iterator_type _it, const std::shared_ptr &_train); @@ -147,7 +151,8 @@ class server_endpoint_impl: public endpoint_impl, virtual std::string get_remote_information( const endpoint_type& _remote) const = 0; virtual bool tp_segmentation_enabled(service_t _service, - method_t _method) const = 0; + instance_t _instance, + method_t _method) const; void schedule_train(endpoint_data_type &_target); void update_last_departure(endpoint_data_type &_data); @@ -155,6 +160,8 @@ class server_endpoint_impl: public endpoint_impl, void start_dispatch_timer(target_data_iterator_type _it, const std::chrono::steady_clock::time_point &_now); void cancel_dispatch_timer(target_data_iterator_type _it); + + void recalculate_queue_size(endpoint_data_type &_data) const; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp index 56b54e798..9820004cd 100644 --- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp @@ -13,6 +13,9 @@ #include #include "client_endpoint_impl.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif namespace vsomeip_v3 { @@ -30,6 +33,7 @@ class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl { const std::shared_ptr& _configuration); virtual ~tcp_client_endpoint_impl(); + void init(); void start(); void restart(bool _force); @@ -80,7 +84,6 @@ class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl { std::string get_remote_information() const; std::shared_ptr get_timing( const service_t& _service, const instance_t& _instance) const; - bool tp_segmentation_enabled(service_t _service, method_t _method) const; std::uint32_t get_max_allowed_reconnects() const; void max_allowed_reconnects_reached(); diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index 38834acfa..dd7b9554c 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -17,6 +17,10 @@ #include +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { typedef server_endpoint_impl< @@ -28,11 +32,11 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { public: tcp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, const std::shared_ptr& _configuration); - virtual ~tcp_server_endpoint_impl(); + virtual ~tcp_server_endpoint_impl() = default; + void init(const endpoint_type& _local, boost::system::error_code& _error); void start(); void stop(); @@ -59,6 +63,8 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { // TODO: think about a better design! void receive(); void print_status(); + + bool is_suspended() const; private: class connection: public std::enable_shared_from_this { @@ -138,7 +144,7 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { typedef std::map connections_t; connections_t connections_; const std::uint32_t buffer_shrink_threshold_; - const std::uint16_t local_port_; + std::uint16_t local_port_; const std::chrono::milliseconds send_timeout_; private: @@ -148,7 +154,6 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { std::string get_remote_information( const target_data_iterator_type _it) const; std::string get_remote_information(const endpoint_type& _remote) const; - bool tp_segmentation_enabled(service_t _service, method_t _method) const; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/tp_message.hpp b/implementation/endpoints/include/tp_message.hpp index 13aef2d0f..0f943b403 100644 --- a/implementation/endpoints/include/tp_message.hpp +++ b/implementation/endpoints/include/tp_message.hpp @@ -14,6 +14,9 @@ #include "buffer.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif namespace vsomeip_v3 { namespace tp { diff --git a/implementation/endpoints/include/tp_reassembler.hpp b/implementation/endpoints/include/tp_reassembler.hpp index 5e50c8c12..5c8936ae1 100644 --- a/implementation/endpoints/include/tp_reassembler.hpp +++ b/implementation/endpoints/include/tp_reassembler.hpp @@ -11,12 +11,7 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif +#include #include #include @@ -24,6 +19,9 @@ #include "tp_message.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif namespace vsomeip_v3 { namespace tp { diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp index 4d02ab27a..02d7cd028 100644 --- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp @@ -65,7 +65,10 @@ class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl { std::string get_address_port_remote() const; std::string get_address_port_local() const; std::string get_remote_information() const; - bool tp_segmentation_enabled(service_t _service, method_t _method) const; + bool tp_segmentation_enabled( + service_t _service, + instance_t _instance, + method_t _method) const; std::uint32_t get_max_allowed_reconnects() const; void max_allowed_reconnects_reached(); diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index b9b68fbc0..9cddac1dc 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -6,39 +6,34 @@ #ifndef VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_ -#if VSOMEIP_BOOST_VERSION < 106600 -#include -#else #include -#endif - #include #include "server_endpoint_impl.hpp" #include "tp_reassembler.hpp" namespace vsomeip_v3 { - -#if VSOMEIP_BOOST_VERSION < 106600 -typedef server_endpoint_impl< - boost::asio::ip::udp_ext - > udp_server_endpoint_base_impl; -#else typedef server_endpoint_impl< boost::asio::ip::udp > udp_server_endpoint_base_impl; -#endif + +// callback type to sent messages (SD) +using on_unicast_sent_cbk_t = + std::function; +// callback type to own multicast messages received +using on_sent_multicast_received_cbk_t = + std::function; class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { public: udp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, const std::shared_ptr& _configuration); - virtual ~udp_server_endpoint_impl(); + virtual ~udp_server_endpoint_impl() = default; + void init(const endpoint_type& _local, boost::system::error_code& _error); void start(); void stop(); @@ -57,8 +52,8 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { VSOMEIP_EXPORT void join(const std::string &_address); VSOMEIP_EXPORT void join_unlocked(const std::string &_address); VSOMEIP_EXPORT void leave(const std::string &_address); - VSOMEIP_EXPORT void set_multicast_option( - const boost::asio::ip::address &_address, bool _is_join); + VSOMEIP_EXPORT void set_multicast_option(const boost::asio::ip::address &_address, + bool _is_join, boost::system::error_code& _error); void add_default_target(service_t _service, const std::string &_address, uint16_t _port); @@ -72,19 +67,30 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { void print_status(); bool is_reliable() const; + // Callback to sent messages + void set_unicast_sent_callback(const on_unicast_sent_cbk_t& _cbk); + // to own multicast messages received + void set_sent_multicast_received_callback(const on_sent_multicast_received_cbk_t& _cbk); + void set_receive_own_multicast_messages(bool value); + + bool is_joining() const; + private: void leave_unlocked(const std::string &_address); void set_broadcast(); void receive_unicast(); void receive_multicast(uint8_t _id); bool is_joined(const std::string &_address) const; - bool is_joined(const std::string &_address, bool* _received) const; + bool is_joined(const std::string &_address, bool& _received) const; std::string get_remote_information( const target_data_iterator_type _it) const; std::string get_remote_information(const endpoint_type& _remote) const; std::string get_address_port_local() const; - bool tp_segmentation_enabled(service_t _service, method_t _method) const; + bool tp_segmentation_enabled( + service_t _service, + instance_t _instance, + method_t _method) const; void on_unicast_received(boost::system::error_code const &_error, std::size_t _bytes); @@ -106,14 +112,14 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { void multicast_shutdown_and_close_unlocked(); private: - socket_type unicast_socket_; + std::shared_ptr unicast_socket_; endpoint_type unicast_remote_; message_buffer_t unicast_recv_buffer_; mutable std::mutex unicast_mutex_; bool is_v4_; - std::unique_ptr multicast_socket_; + std::shared_ptr multicast_socket_; std::unique_ptr multicast_local_; endpoint_type multicast_remote_; message_buffer_t multicast_recv_buffer_; @@ -128,7 +134,7 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { boost::asio::ip::address netmask_; unsigned short prefix_; - const std::uint16_t local_port_; + std::uint16_t local_port_; std::shared_ptr tp_reassembler_; boost::asio::steady_timer tp_cleanup_timer_; @@ -137,6 +143,13 @@ class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { std::chrono::steady_clock::time_point last_sent_; std::atomic is_stopped_; + + // to tracking sent messages + on_unicast_sent_cbk_t on_unicast_sent_; + + // to receive own multicast messages + bool receive_own_multicast_messages_; + on_sent_multicast_received_cbk_t on_sent_multicast_received_; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp index 35638cd71..5823dcf59 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp @@ -6,8 +6,6 @@ #ifndef VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ #define VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ -#if VSOMEIP_BOOST_VERSION >= 106600 - #ifdef _WIN32 #include #endif @@ -19,6 +17,12 @@ #include +#if defined(__QNX__) +#include +#include +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { namespace udp_endpoint_receive_op { @@ -32,7 +36,7 @@ struct storage : public std::enable_shared_from_this { std::recursive_mutex &multicast_mutex_; - socket_type_t &socket_; + std::weak_ptr socket_; endpoint_type_t &sender_; receive_handler_t handler_; byte_t *buffer_ = nullptr; @@ -44,7 +48,7 @@ struct storage : storage( std::recursive_mutex &_multicast_mutex, - socket_type_t &_socket, + std::weak_ptr _socket, endpoint_type_t &_sender, receive_handler_t _handler, byte_t *_buffer, @@ -62,7 +66,7 @@ struct storage : multicast_id_(_multicast_id), is_v4_(_is_v4), destination_(_destination), - bytes_(_bytes) + bytes_(_bytes) {} }; @@ -75,15 +79,21 @@ receive_cb (std::shared_ptr _data) { std::lock_guard its_lock(_data->multicast_mutex_); - if (!_data->socket_.native_non_blocking()) - _data->socket_.native_non_blocking(true, _error); + auto multicast_socket = _data->socket_.lock(); + if (!multicast_socket) { + VSOMEIP_WARNING << "udp_endpoint_receive_op::receive_cb: multicast_socket with id " << int{_data->multicast_id_} << " has expired!"; + return; + } + + if (!multicast_socket->native_non_blocking()) + multicast_socket->native_non_blocking(true, _error); for (;;) { #ifdef _WIN32 GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; LPFN_WSARECVMSG WSARecvMsg; DWORD its_bytes; - SOCKET its_socket { _data->socket_.native_handle() }; + SOCKET its_socket { multicast_socket->native_handle() }; WSAIoctl(its_socket, SIO_GET_EXTENSION_FUNCTION_POINTER, &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, @@ -146,7 +156,7 @@ receive_cb (std::shared_ptr _data) { if (_error == boost::asio::error::would_block || _error == boost::asio::error::try_again) { - _data->socket_.async_wait( + multicast_socket->async_wait( socket_type_t::wait_read, receive_cb(_data) ); @@ -221,7 +231,7 @@ receive_cb (std::shared_ptr _data) { int its_flags { 0 }; // Create control elements - msghdr its_header = msghdr(); + auto its_header = msghdr(); struct iovec its_vec[1]; // Prepare @@ -263,7 +273,7 @@ receive_cb (std::shared_ptr _data) { // Call recvmsg and handle its result errno = 0; - its_result = ::recvmsg(_data->socket_.native_handle(), &its_header, its_flags); + its_result = ::recvmsg(multicast_socket->native_handle(), &its_header, its_flags); _error = boost::system::error_code(its_result < 0 ? errno : 0, boost::asio::error::get_system_category()); @@ -274,8 +284,8 @@ receive_cb (std::shared_ptr _data) { if (_error == boost::asio::error::would_block || _error == boost::asio::error::try_again) { - _data->socket_.async_wait( - socket_type_t::wait_read, + multicast_socket->async_wait( + socket_type_t::wait_read, receive_cb(_data) ); return; @@ -356,6 +366,4 @@ receive_cb (std::shared_ptr _data) { } // namespace udp_endpoint_receive_op } // namespace vsomeip_v3 -#endif // VSOMEIP_BOOST_VERSION >= 106600 - #endif // VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ diff --git a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp index 1739f8406..555260c20 100644 --- a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp @@ -6,15 +6,8 @@ #ifndef VSOMEIP_V3_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP_ -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif - +#include #include - #include "../include/endpoint.hpp" namespace vsomeip_v3 { @@ -59,10 +52,6 @@ class virtual_server_endpoint_impl : public endpoint, public std::enable_shared_ bool is_reliable() const; bool is_local() const; - void increment_use_count(); - void decrement_use_count(); - uint32_t get_use_count(); - void restart(bool _force); void register_error_handler(const error_handler_t &_handler); @@ -75,7 +64,6 @@ class virtual_server_endpoint_impl : public endpoint, public std::enable_shared_ uint16_t port_; bool reliable_; - uint32_t use_count_; boost::asio::io_context &io_; }; diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp index 58041ecae..fe91ca949 100644 --- a/implementation/endpoints/src/client_endpoint_impl.cpp +++ b/implementation/endpoints/src/client_endpoint_impl.cpp @@ -20,35 +20,24 @@ #include "../include/client_endpoint_impl.hpp" #include "../include/endpoint_host.hpp" #include "../../utility/include/utility.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { template client_endpoint_impl::client_endpoint_impl( - const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, - const endpoint_type& _remote, - boost::asio::io_context &_io, - std::uint32_t _max_message_size, - configuration::endpoint_queue_limit_t _queue_limit, - const std::shared_ptr& _configuration) - : endpoint_impl(_endpoint_host, _routing_host, _local, _io, - _max_message_size, _queue_limit, _configuration), - socket_(std::make_unique(_io)), remote_(_remote), - flush_timer_(_io), connect_timer_(_io), - connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable - state_(cei_state_e::CLOSED), - reconnect_counter_(0), - connecting_timer_(_io), connecting_timeout_(VSOMEIP_DEFAULT_CONNECTING_TIMEOUT), - train_(std::make_shared()), - dispatch_timer_(_io), - has_last_departure_(false), - queue_size_(0), - was_not_connected_(false), - is_sending_(false), - strand_(_io) { + const endpoint_type& _local, const endpoint_type& _remote, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : + endpoint_impl(_endpoint_host, _routing_host, _io, _configuration), + socket_ {std::make_unique(_io)}, remote_ {_remote}, flush_timer_ {_io}, + connect_timer_ {_io}, connect_timeout_ {VSOMEIP_DEFAULT_CONNECT_TIMEOUT}, + state_ {cei_state_e::CLOSED}, reconnect_counter_ {0}, connecting_timer_ {_io}, + connecting_timeout_ {VSOMEIP_DEFAULT_CONNECTING_TIMEOUT}, + train_ {std::make_shared()}, dispatch_timer_ {_io}, has_last_departure_ {false}, + queue_size_ {0}, was_not_connected_ {false}, is_sending_ {false}, strand_(_io) { + this->local_ = _local; } template @@ -212,10 +201,9 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) cancel_dispatch_timer(); // STEP 3: Get configured timings - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + const service_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + std::chrono::nanoseconds its_debouncing(0), its_retention(0); get_configured_times_from_endpoint(its_service, its_method, &its_debouncing, &its_retention); @@ -289,6 +277,13 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) return true; } +template +bool client_endpoint_impl::tp_segmentation_enabled( + service_t /*_service*/, instance_t /*_instance*/, method_t /*_method*/) const { + + return false; +} + template void client_endpoint_impl::send_segments( const tp::tp_split_messages_t &_segments, std::uint32_t _separation_time) { @@ -299,12 +294,9 @@ void client_endpoint_impl::send_segments( return; } - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN], - (*(_segments[0]))[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*(_segments[0]))[VSOMEIP_METHOD_POS_MIN], - (*(_segments[0]))[VSOMEIP_METHOD_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&(*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN]); + const service_t its_method = bithelper::read_uint16_be(&(*(_segments[0]))[VSOMEIP_METHOD_POS_MIN]); + std::chrono::nanoseconds its_debouncing(0), its_retention(0); get_configured_times_from_endpoint(its_service, its_method, &its_debouncing, &its_retention); @@ -321,6 +313,7 @@ void client_endpoint_impl::send_segments( // messages as we will send several now anyway. if (!train_->passengers_.empty()) { schedule_train(); + train_ = std::make_shared(); train_->departure_ = its_now + its_retention; } @@ -330,8 +323,6 @@ void client_endpoint_impl::send_segments( } if (!is_sending_ && !queue_.empty()) { // no writing in progress - // respect minimal debounce time - schedule_train(); // ignore retention time and send immediately as the train is full anyway auto its_entry = get_front(); if (its_entry.first) { @@ -414,13 +405,18 @@ void client_endpoint_impl::connect_cbk( if (_error == boost::asio::error::operation_aborted || endpoint_impl::sending_blocked_) { - // endpoint was stopped + VSOMEIP_WARNING << "cei::" << __func__ << ": endpoint stopped" << " endpoint > " << this + << " socket state > " << static_cast(state_.load()); shutdown_and_close_socket(false); return; } std::shared_ptr its_host = this->endpoint_host_.lock(); if (its_host) { if (_error && _error != boost::asio::error::already_connected) { + VSOMEIP_WARNING << "cei::" << __func__ << ": restarting socket due to" + << "(" << _error.value() << "):" << _error.message() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); + shutdown_and_close_socket(true); if (state_ != cei_state_e::ESTABLISHED) { @@ -437,6 +433,12 @@ void client_endpoint_impl::connect_cbk( if (connect_timeout_ < VSOMEIP_MAX_CONNECT_TIMEOUT) connect_timeout_ = (connect_timeout_ << 1); } else { + if (_error) { + VSOMEIP_WARNING << "cei::" << __func__ << ": connect_cbk attempt " + << "(" << _error.value() << "):" << _error.message() + << " endpoint > " << this << " socket state > " + << static_cast(state_.load()); + } { std::lock_guard its_lock(connect_timer_mutex_); connect_timer_.cancel(); @@ -451,8 +453,9 @@ void client_endpoint_impl::connect_cbk( is_sending_ = true; strand_.dispatch(std::bind(&client_endpoint_impl::send_queued, this->shared_from_this(), its_entry)); - VSOMEIP_WARNING << __func__ << ": resume sending to: " - << get_remote_information(); + VSOMEIP_WARNING + << __func__ << ": resume sending to: " << get_remote_information() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); } } if (state_ != cei_state_e::ESTABLISHED) { @@ -474,7 +477,16 @@ void client_endpoint_impl::cancel_and_connect_cbk( operations_cancelled = connecting_timer_.cancel(); } if (operations_cancelled != 0) { + if (_error) { + VSOMEIP_WARNING << "cei::" << __func__ << ": cancelled " << operations_cancelled + << " operations err: (" << _error.value() + << "): msg: " << _error.message() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); + } connect_cbk(_error); + } else { + VSOMEIP_INFO << "cei::" << __func__ << " operations_cancelled is 0 endpoint > " + << this << " socket state > " << static_cast(state_.load()); } } @@ -495,6 +507,11 @@ void client_endpoint_impl::wait_connecting_cbk( if (!_error && !client_endpoint_impl::sending_blocked_) { connect_cbk(boost::asio::error::timed_out); + } else if (_error.value() != ECANCELED) { + VSOMEIP_WARNING << "cei::" << __func__ << ": not calling connect_cbk: " + << "sending_blocked_: " << client_endpoint_impl::sending_blocked_ + << " (" << _error.value() << "):" << _error.message() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); } } @@ -538,29 +555,21 @@ void client_endpoint_impl::send_cbk( client_t its_client(0); session_t its_session(0); if (_sent_msg && _sent_msg->size() > VSOMEIP_SESSION_POS_MAX) { - its_service = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SERVICE_POS_MIN], - (*_sent_msg)[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_METHOD_POS_MIN], - (*_sent_msg)[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_CLIENT_POS_MIN], - (*_sent_msg)[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SESSION_POS_MIN], - (*_sent_msg)[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SESSION_POS_MIN]); } VSOMEIP_WARNING << "cei::send_cbk received error: " << _error.message() << " (" << std::dec << _error.value() << ") " << get_remote_information() << " " << std::dec << queue_.size() - << " " << queue_size_ << " (" - << std::hex << std::setfill('0') - << std::setw(4) << its_client << "): [" - << std::setw(4) << its_service << "." - << std::setw(4) << its_method << "." - << std::setw(4) << its_session << "]"; + << " " << std::dec << queue_size_ << " (" + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "." + << std::hex << std::setw(4) << std::setfill('0') << its_session << "]" + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); } } if (!stopping) { @@ -577,7 +586,8 @@ void client_endpoint_impl::send_cbk( if (_error == boost::asio::error::no_permission) { VSOMEIP_WARNING << "cei::send_cbk received error: " << _error.message() << " (" << std::dec << _error.value() << ") " - << get_remote_information(); + << get_remote_information() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); std::lock_guard its_lock(mutex_); queue_.clear(); queue_size_ = 0; @@ -587,14 +597,16 @@ void client_endpoint_impl::send_cbk( strand_.dispatch(std::bind(&client_endpoint_impl::connect, this->shared_from_this())); } else if (_error == boost::asio::error::operation_aborted) { - VSOMEIP_WARNING << "cei::send_cbk received error: " << _error.message(); + VSOMEIP_WARNING << "cei::send_cbk received error: " << _error.message() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); // endpoint was stopped endpoint_impl::sending_blocked_ = true; shutdown_and_close_socket(false); } else if (_error == boost::system::errc::destination_address_required) { VSOMEIP_WARNING << "cei::send_cbk received error: " << _error.message() << " (" << std::dec << _error.value() << ") " - << get_remote_information(); + << get_remote_information() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); was_not_connected_ = true; } else { service_t its_service(0); @@ -602,29 +614,21 @@ void client_endpoint_impl::send_cbk( client_t its_client(0); session_t its_session(0); if (_sent_msg && _sent_msg->size() > VSOMEIP_SESSION_POS_MAX) { - its_service = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SERVICE_POS_MIN], - (*_sent_msg)[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_METHOD_POS_MIN], - (*_sent_msg)[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_CLIENT_POS_MIN], - (*_sent_msg)[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SESSION_POS_MIN], - (*_sent_msg)[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SESSION_POS_MIN]); } VSOMEIP_WARNING << "cei::send_cbk received error: " << _error.message() << " (" << std::dec << _error.value() << ") " << get_remote_information() << " " - << " " << queue_.size() - << " " << queue_size_ << " (" - << std::hex << std::setfill('0') - << std::setw(4) << its_client << "): [" - << std::setw(4) << its_service << "." - << std::setw(4) << its_method << "." - << std::setw(4) << its_session << "]"; + << " " << std::dec << queue_.size() + << " " << std::dec << queue_size_ << " (" + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "." + << std::hex << std::setw(4) << std::setfill('0') << its_session << "]" + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); print_status(); } @@ -656,15 +660,37 @@ void client_endpoint_impl::shutdown_and_close_socket_unlocked(bool _re if (-1 == fcntl(socket_->native_handle(), F_GETFD)) { VSOMEIP_ERROR << "cei::shutdown_and_close_socket_unlocked: socket/handle closed already '" << std::string(std::strerror(errno)) - << "' (" << errno << ") " << get_remote_information(); + << "' (" << errno << ") " << get_remote_information() + << " endpoint > " << this; } #endif boost::system::error_code its_error; socket_->shutdown(Protocol::socket::shutdown_both, its_error); + if (its_error) { + VSOMEIP_WARNING << "cei::" << __func__ << ": socket shutdown error " + << "(" << its_error.value() << "): " << its_error.message() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); + } socket_->close(its_error); + if (its_error) { + VSOMEIP_WARNING << "cei::" << __func__ << ": socket close error " + << "(" << its_error.value() << "): " << its_error.message() + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); + } + } else { + VSOMEIP_WARNING << "cei::" << __func__ << ": socket was not open " + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); } + + state_ = cei_state_e::CLOSED; + if (_recreate_socket) { socket_.reset(new socket_type(endpoint_impl::io_)); + VSOMEIP_WARNING << "cei::" << __func__ << ": socket has been reset " + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); + } else { + VSOMEIP_INFO << "cei::" << __func__ << ": not recreating socket " + << " endpoint > " << this << " socket state > " << static_cast(state_.load()); } } @@ -724,15 +750,12 @@ typename endpoint_impl::cms_ret_e client_endpoint_impl::chec if (endpoint_impl::max_message_size_ != MESSAGE_SIZE_UNLIMITED && _size > endpoint_impl::max_message_size_) { if (endpoint_impl::is_supporting_someip_tp_ && _data != nullptr) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - if (tp_segmentation_enabled(its_service, its_method)) { - instance_t its_instance = this->get_instance(its_service); - if (its_instance != 0xFFFF) { + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + instance_t its_instance = this->get_instance(its_service); + + if (its_instance != ANY_INSTANCE) { + if (tp_segmentation_enabled(its_service, its_instance, its_method)) { std::uint16_t its_max_segment_length; std::uint32_t its_separation_time; this->configuration_->get_tp_configuration( @@ -756,7 +779,8 @@ template bool client_endpoint_impl::check_queue_limit(const uint8_t *_data, std::uint32_t _size) const { if (endpoint_impl::queue_limit_ != QUEUE_SIZE_UNLIMITED - && queue_size_ + _size > endpoint_impl::queue_limit_) { + && (queue_size_ + _size > endpoint_impl::queue_limit_ + || queue_size_ + _size < _size)) { // overflow protection service_t its_service(0); method_t its_method(0); client_t its_client(0); @@ -769,25 +793,20 @@ bool client_endpoint_impl::check_queue_limit(const uint8_t *_data, std // [(Command + lowerbyte sender's client ID). // highbyte sender's client ID + lowbyte command size. // lowbyte methodid + highbyte vsomeip length] - its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); } VSOMEIP_ERROR << "cei::check_queue_limit: queue size limit (" << std::dec << endpoint_impl::queue_limit_ << ") reached. Dropping message (" - << std::hex << std::setfill('0') - << std::setw(4) << its_client << "): [" - << std::setw(4) << its_service << "." - << std::setw(4) << its_method << "." - << std::setw(4) << its_session << "] " + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "." + << std::hex << std::setw(4) << std::setfill('0') << its_session << "] " << "queue_size: " << std::dec << queue_size_ - << " data size: " << _size; + << " data size: " << std::dec << _size; return false; } return true; diff --git a/implementation/endpoints/src/credentials.cpp b/implementation/endpoints/src/credentials.cpp index deebaaa6b..636319913 100644 --- a/implementation/endpoints/src/credentials.cpp +++ b/implementation/endpoints/src/credentials.cpp @@ -108,7 +108,7 @@ boost::optional credentials::receive_credentials(const void credentials::send_credentials(const int _fd, client_t _client, std::string _client_host) { struct msghdr msgh; struct iovec iov[3]; - uint8_t client_host_length = (uint8_t)_client_host.length(); + auto client_host_length = static_cast(_client_host.length()); // data to send msgh.msg_iov = &iov[0]; diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp index 757d3b4c4..b69943bca 100644 --- a/implementation/endpoints/src/endpoint_impl.cpp +++ b/implementation/endpoints/src/endpoint_impl.cpp @@ -6,10 +6,6 @@ #include #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -#include -#include -#endif #include #include @@ -22,30 +18,13 @@ namespace vsomeip_v3 { template -endpoint_impl::endpoint_impl( - const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_context &_io, - std::uint32_t _max_message_size, - configuration::endpoint_queue_limit_t _queue_limit, - const std::shared_ptr& _configuration) - : io_(_io), - endpoint_host_(_endpoint_host), - routing_host_(_routing_host), - is_supporting_magic_cookies_(false), - has_enabled_magic_cookies_(false), - max_message_size_(_max_message_size), - use_count_(0), - sending_blocked_(false), - local_(_local), - queue_limit_(_queue_limit), - configuration_(_configuration), - is_supporting_someip_tp_(false) { -} - -template -endpoint_impl::~endpoint_impl() { +endpoint_impl::endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration) : + io_(_io), endpoint_host_(_endpoint_host), routing_host_(_routing_host), + is_supporting_magic_cookies_(false), has_enabled_magic_cookies_(false), use_count_(0), + sending_blocked_(false), configuration_(_configuration), is_supporting_someip_tp_(false) { } template @@ -114,22 +93,6 @@ template void endpoint_impl::remove_stop_handler(service_t) { } -template -void endpoint_impl::increment_use_count() { - use_count_++; -} - -template -void endpoint_impl::decrement_use_count() { - if (use_count_ > 0) - use_count_--; -} - -template -uint32_t endpoint_impl::get_use_count() { - return use_count_; -} - template void endpoint_impl::register_error_handler(const error_handler_t &_error_handler) { std::lock_guard its_lock(error_handler_mutex_); @@ -150,17 +113,10 @@ instance_t endpoint_impl::get_instance(service_t _service) { // Instantiate template #if defined(__linux__) || defined(__QNX__) -#if VSOMEIP_BOOST_VERSION < 106600 -template class endpoint_impl; -#endif template class endpoint_impl; #endif template class endpoint_impl; template class endpoint_impl; -#if VSOMEIP_BOOST_VERSION < 106600 -template class endpoint_impl; -#endif - } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/endpoint_manager_base.cpp b/implementation/endpoints/src/endpoint_manager_base.cpp index 4e484454a..f13b41839 100644 --- a/implementation/endpoints/src/endpoint_manager_base.cpp +++ b/implementation/endpoints/src/endpoint_manager_base.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2024 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,11 +6,12 @@ #include "../include/endpoint_manager_base.hpp" #include -#include "../../utility/include/utility.hpp" -#include "../../routing/include/routing_manager_base.hpp" -#include "../../configuration/include/configuration.hpp" #include "../include/local_tcp_client_endpoint_impl.hpp" #include "../include/local_tcp_server_endpoint_impl.hpp" +#include "../../configuration/include/configuration.hpp" +#include "../../protocol/include/config_command.hpp" +#include "../../routing/include/routing_manager_base.hpp" +#include "../../utility/include/utility.hpp" #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) #include "../include/local_uds_client_endpoint_impl.hpp" @@ -44,18 +45,25 @@ void endpoint_manager_base::remove_local(const client_t _client) { its_endpoint->register_error_handler(nullptr); its_endpoint->stop(); VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is closing connection to [" - << std::hex << _client << "]"; + << std::hex << _client << "]" << " endpoint > " << its_endpoint; std::lock_guard its_lock(local_endpoint_mutex_); local_endpoints_.erase(_client); } } std::shared_ptr endpoint_manager_base::find_or_create_local(client_t _client) { - std::lock_guard its_lock(local_endpoint_mutex_); - std::shared_ptr its_endpoint(find_local_unlocked(_client)); - if (!its_endpoint) { - its_endpoint = create_local_unlocked(_client); + std::shared_ptr its_endpoint {nullptr}; + { + std::scoped_lock its_lock {local_endpoint_mutex_}; + its_endpoint = find_local_unlocked(_client); + if (!its_endpoint) { + its_endpoint = create_local_unlocked(_client); + } + } + if (its_endpoint) { its_endpoint->start(); + } else { + VSOMEIP_ERROR << __func__ << ": couldn't find or create endpoint for client " << _client; } return its_endpoint; } @@ -82,7 +90,7 @@ std::unordered_set endpoint_manager_base::get_connected_clients() cons std::shared_ptr endpoint_manager_base::create_local_server( const std::shared_ptr &_routing_host) { - std::shared_ptr its_server_endpoint; + std::shared_ptr its_local_server; std::stringstream its_path; its_path << utility::get_base_path(configuration_->get_network()) << std::hex << rm_->get_client(); @@ -90,83 +98,100 @@ std::shared_ptr endpoint_manager_base::create_local_server( #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) if (is_local_routing_) { - if (-1 == ::unlink(its_path.str().c_str()) && errno != ENOENT) { - VSOMEIP_ERROR << "endpoint_manager_base::init_receiver unlink failed (" - << its_path.str() << "): "<< std::strerror(errno); - } try { - its_server_endpoint = std::make_shared( - shared_from_this(), _routing_host, -# if VSOMEIP_BOOST_VERSION < 106600 - boost::asio::local::stream_protocol_ext::endpoint(its_path.str()), -# else - boost::asio::local::stream_protocol::endpoint(its_path.str()), -# endif - io_, - configuration_, false); - - VSOMEIP_INFO << __func__ << ": Listening @ " << its_path.str(); - - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Local UDS server endpoint creation failed. Client " - << std::hex << std::setw(4) << std::setfill('0') << its_client - << " Path: " << its_path.str() - << " Reason: " << e.what(); + if (-1 == ::unlink(its_path.str().c_str()) && errno != ENOENT) { + VSOMEIP_ERROR << "endpoint_manager_base::init_receiver unlink failed (" + << its_path.str() << "): "<< std::strerror(errno); + } + auto its_tmp {std::make_shared( + shared_from_this(), _routing_host, + io_, configuration_, false)}; + if (its_tmp) { + boost::asio::local::stream_protocol::endpoint its_local_endpoint(its_path.str()); + boost::system::error_code its_error; + its_tmp->init(its_local_endpoint, its_error); + if (!its_error) { + VSOMEIP_INFO << __func__ << ": Listening @ " << its_path.str(); + its_local_server = its_tmp; + } else { + VSOMEIP_ERROR << "Local UDS server endpoint initialization failed. Client " + << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Path: " << its_path.str() << " Reason: " << its_error.message(); + } + } else { + VSOMEIP_ERROR << "Local UDS server endpoint creation failed. Client " + << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Path: " << its_path.str() << " Reason: out_of_memory"; + } + } catch (const std::exception& e) { + VSOMEIP_ERROR << __func__ << ": " << e.what(); } } else { #else { #endif - std::lock_guard its_lock(create_local_server_endpoint_mutex_); - ::unlink(its_path.str().c_str()); - port_t its_port; - std::set its_used_ports; - auto its_address = configuration_->get_routing_guest_address(); - uint32_t its_current_wait_time { 0 }; - while (get_local_server_port(its_port, its_used_ports) && !its_server_endpoint) { - try { - its_server_endpoint = std::make_shared( - shared_from_this(), _routing_host, - boost::asio::ip::tcp::endpoint(its_address, its_port), - io_, - configuration_, false); - - VSOMEIP_INFO << __func__ << ": Listening @ " - << its_address.to_string() << ":" << std::dec << its_port; - - if (rm_->is_routing_manager()) - local_port_ = port_t(configuration_->get_routing_host_port() + 1); - else - local_port_ = port_t(its_port + 1); - VSOMEIP_INFO << __func__ << ": Connecting to other clients from " - << its_address.to_string() << ":" << std::dec << local_port_; - - rm_->set_sec_client_port(local_port_); - - } catch (const boost::system::system_error &e) { - if (e.code() == boost::asio::error::address_in_use) { - its_used_ports.insert(its_port); - } else { - its_current_wait_time += LOCAL_TCP_PORT_WAIT_TIME; - if (its_current_wait_time > LOCAL_TCP_PORT_MAX_WAIT_TIME) - break; + try { + std::lock_guard its_lock(create_local_server_endpoint_mutex_); + ::unlink(its_path.str().c_str()); + port_t its_port; + std::set its_used_ports; + auto its_address = configuration_->get_routing_guest_address(); + uint32_t its_current_wait_time { 0 }; + + auto its_tmp {std::make_shared( + shared_from_this(), _routing_host, io_, configuration_, false)}; + if (its_tmp) { + while (get_local_server_port(its_port, its_used_ports) && !its_local_server) { + boost::asio::ip::tcp::endpoint its_local_endpoint(its_address, its_port); + boost::system::error_code its_error; + its_tmp->init(its_local_endpoint, its_error); + if (!its_error) { + VSOMEIP_INFO << __func__ << ": Listening @ " + << its_address.to_string() << ":" << std::dec << its_port; + + if (rm_->is_routing_manager()) + local_port_ = port_t(configuration_->get_routing_host_port() + 1); + else + local_port_ = port_t(its_port + 1); + VSOMEIP_INFO << __func__ << ": Connecting to other clients from " + << its_address.to_string() << ":" << std::dec << local_port_; + + rm_->set_sec_client_port(local_port_); + + its_local_server = its_tmp; + } else { + its_tmp->deinit(); + if (its_error == boost::asio::error::address_in_use) { + its_used_ports.insert(its_port); + } else { + its_current_wait_time += LOCAL_TCP_PORT_WAIT_TIME; + if (its_current_wait_time > LOCAL_TCP_PORT_MAX_WAIT_TIME) + break; + + std::this_thread::sleep_for( + std::chrono::milliseconds(LOCAL_TCP_PORT_WAIT_TIME)); + } + } + } - std::this_thread::sleep_for( - std::chrono::milliseconds(LOCAL_TCP_PORT_WAIT_TIME)); + if (its_local_server) { + rm_->add_guest(its_client, its_address, its_port); + } else { + VSOMEIP_ERROR << __func__ << ": Local TCP server endpoint initialization failed. " + << "Client " << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Reason: No local port available!"; } + } else { + VSOMEIP_ERROR << __func__ << ": Local TCP server endpoint creation failed. " + << "Client " << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Reason: No local port available!"; } - } - - if (!its_server_endpoint) { - VSOMEIP_ERROR << "Local TCP server endpoint creation failed. Client " - << std::hex << std::setw(4) << std::setfill('0') << its_client - << " Reason: No local port available!"; - } else { - rm_->add_guest(its_client, its_address, its_port); + } catch (const std::exception& e) { + VSOMEIP_ERROR << __func__ << ": " << e.what(); } } - return its_server_endpoint; + return its_local_server; } void endpoint_manager_base::on_connect(std::shared_ptr _endpoint) { @@ -270,7 +295,7 @@ endpoint_manager_base::create_local_unlocked(client_t _client) { boost::asio::local::stream_protocol::endpoint(its_path.str()), io_, configuration_); VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is connecting to [" - << std::hex << _client << "] at " << its_path.str(); + << std::hex << _client << "] at " << its_path.str() << " endpoint > " << its_endpoint; } else { #else { @@ -294,7 +319,8 @@ endpoint_manager_base::create_local_unlocked(client_t _client) { << its_local_address.to_string() << ":" << std::dec << local_port_ << " is connecting to [" << std::hex << std::setw(4) << std::setfill('0') << _client << "] @ " - << its_remote_address.to_string() << ":" << std::dec << its_remote_port; + << its_remote_address.to_string() << ":" << std::dec << its_remote_port + << " endpoint > " << its_endpoint; } catch (...) { } @@ -315,8 +341,10 @@ endpoint_manager_base::create_local_unlocked(client_t _client) { local_endpoints_[_client] = its_endpoint; } rm_->register_client_error_handler(_client, its_endpoint); + } else { + VSOMEIP_WARNING << __func__ << ": (" << std::hex << get_client() + << ") not connected. Ignoring client assignment"; } - return its_endpoint; } @@ -376,10 +404,15 @@ endpoint_manager_base::get_local_server_port(port_t &_port, return false; } -void -endpoint_manager_base::add_multicast_option(const multicast_option_t &_option) { - +void endpoint_manager_base::add_multicast_option(const multicast_option_t &_option) { (void)_option; } +void endpoint_manager_base::suspend(void) { + // Nothing to be done for internal endpoints +} +void endpoint_manager_base::resume(void) { + // Nothing to be done for internal endpoints +} + } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/endpoint_manager_impl.cpp b/implementation/endpoints/src/endpoint_manager_impl.cpp index d423d4590..4b2bf17a8 100644 --- a/implementation/endpoints/src/endpoint_manager_impl.cpp +++ b/implementation/endpoints/src/endpoint_manager_impl.cpp @@ -21,7 +21,7 @@ #include "../../routing/include/routing_manager_impl.hpp" #include "../../routing/include/routing_host.hpp" #include "../../utility/include/utility.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include @@ -245,54 +245,59 @@ void endpoint_manager_impl::clear_remote_service_info(service_t _service, } } -std::shared_ptr endpoint_manager_impl::create_server_endpoint( - uint16_t _port, bool _reliable, bool _start) { +std::shared_ptr +endpoint_manager_impl::create_server_endpoint(uint16_t _port, bool _reliable, bool _start) { + std::shared_ptr its_server_endpoint; + boost::system::error_code its_error; + boost::asio::ip::address its_unicast {configuration_->get_unicast_address()}; + const std::string its_unicast_str {its_unicast.to_string()}; + std::lock_guard its_lock(endpoint_mutex_); - std::shared_ptr its_endpoint; - try { - boost::asio::ip::address its_unicast = configuration_->get_unicast_address(); - const std::string its_unicast_str = its_unicast.to_string(); - if (_start) { - if (_reliable) { - its_endpoint = std::make_shared( - shared_from_this(), - rm_->shared_from_this(), - boost::asio::ip::tcp::endpoint(its_unicast, _port), - io_, - configuration_); - if (configuration_->has_enabled_magic_cookies( - its_unicast_str, _port) || - configuration_->has_enabled_magic_cookies( - "local", _port)) { - its_endpoint->enable_magic_cookies(); + if (_start) { + if (_reliable) { + auto its_tmp {std::make_shared(shared_from_this(), + rm_->shared_from_this(), io_, configuration_)}; + if (its_tmp) { + boost::asio::ip::tcp::endpoint its_reliable(its_unicast, _port); + its_tmp->init(its_reliable, its_error); + if (!its_error) { + if (configuration_->has_enabled_magic_cookies( + its_unicast_str, _port) || + configuration_->has_enabled_magic_cookies( + "local", _port)) { + its_tmp->enable_magic_cookies(); + } + its_server_endpoint = its_tmp; } - } else { - its_endpoint = std::make_shared( - shared_from_this(), - rm_->shared_from_this(), - boost::asio::ip::udp::endpoint(its_unicast, _port), - io_, - configuration_); } - } else { - its_endpoint = std::make_shared( - its_unicast_str, _port, _reliable, io_); + auto its_tmp {std::make_shared(shared_from_this(), + rm_->shared_from_this(), io_, configuration_)}; + if (its_tmp) { + boost::asio::ip::udp::endpoint its_unreliable(its_unicast, _port); + its_tmp->init(its_unreliable, its_error); + if (!its_error) { + its_server_endpoint = its_tmp; + } + } } + } else { + its_server_endpoint = std::make_shared(its_unicast_str, + _port, _reliable, io_); + } - if (its_endpoint) { - server_endpoints_[_port][_reliable] = its_endpoint; - its_endpoint->start(); - } - } catch (const std::exception &e) { + if (its_server_endpoint) { + server_endpoints_[_port][_reliable] = its_server_endpoint; + its_server_endpoint->start(); + } else { VSOMEIP_ERROR << __func__ << " Server endpoint creation failed." - << " Reason: "<< e.what() + << " Reason: " << its_error.message() << " Port: " << _port << " (" << _reliable << ")"; } - return its_endpoint; + return its_server_endpoint; } std::shared_ptr endpoint_manager_impl::find_server_endpoint( @@ -325,28 +330,38 @@ std::shared_ptr endpoint_manager_impl::find_or_create_server_endpoint( if (!_is_multicast) { service_instances_[_service][its_endpoint.get()] = _instance; } - its_endpoint->increment_use_count(); } return its_endpoint; } bool endpoint_manager_impl::remove_server_endpoint(uint16_t _port, bool _reliable) { - bool ret = false; - std::lock_guard its_lock(endpoint_mutex_); - auto found_port = server_endpoints_.find(_port); - if (found_port != server_endpoints_.end()) { - auto found_reliable = found_port->second.find(_reliable); - if (found_reliable != found_port->second.end()) { - if (found_reliable->second->get_use_count() == 0 && - found_port->second.erase(_reliable)) { - ret = true; + + std::shared_ptr its_endpoint; + { + std::lock_guard its_lock(endpoint_mutex_); + auto found_port = server_endpoints_.find(_port); + if (found_port != server_endpoints_.end()) { + auto found_reliable = found_port->second.find(_reliable); + if (found_reliable != found_port->second.end()) { + its_endpoint = found_reliable->second; + } + } + } + + if (!is_used_endpoint(its_endpoint.get())) { + std::lock_guard its_lock(endpoint_mutex_); + auto found_port = server_endpoints_.find(_port); + if (found_port != server_endpoints_.end()) { + if (found_port->second.erase(_reliable)) { if (found_port->second.empty()) { server_endpoints_.erase(found_port); } } + return true; } } - return ret; + + return false; } void @@ -420,8 +435,8 @@ endpoint_manager_impl::clear_client_endpoints( its_udp_client_endpoint->get_remote_address(its_remote_address); } } - const auto found_ip = client_endpoints_by_ip_.find(its_remote_address); - if (found_ip != client_endpoints_by_ip_.end()) { + const auto found_ip = client_endpoints_.find(its_remote_address); + if (found_ip != client_endpoints_.end()) { const auto found_port = found_ip->second.find(its_remote_port); if (found_port != found_ip->second.end()) { auto found_reliable = found_port->second.find(_reliable); @@ -436,7 +451,7 @@ endpoint_manager_impl::clear_client_endpoints( if (0 == found_port->second.size()) { found_ip->second.erase(found_port); if (0 == found_ip->second.size()) { - client_endpoints_by_ip_.erase(found_ip); + client_endpoints_.erase(found_ip); } } } @@ -460,11 +475,11 @@ void endpoint_manager_impl::find_or_create_multicast_endpoint( service_t _service, instance_t _instance, const boost::asio::ip::address &_sender, const boost::asio::ip::address &_address, uint16_t _port) { - bool multicast_known(false); + bool is_known_multicast(false); { std::lock_guard its_lock(endpoint_mutex_); - const auto found_service = multicast_info.find(_service); - if (found_service != multicast_info.end()) { + const auto found_service = multicast_info_.find(_service); + if (found_service != multicast_info_.end()) { const auto found_instance = found_service->second.find(_instance); if (found_instance != found_service->second.end()) { const auto& endpoint_def = found_instance->second; @@ -472,7 +487,7 @@ void endpoint_manager_impl::find_or_create_multicast_endpoint( endpoint_def->get_port() == _port) { // Multicast info and endpoint already created before // This can happen when more than one client subscribe on the same instance! - multicast_known = true; + is_known_multicast = true; } } } @@ -489,58 +504,62 @@ void endpoint_manager_impl::find_or_create_multicast_endpoint( std::lock_guard its_lock(endpoint_mutex_); std::shared_ptr endpoint_def = endpoint_definition::get(_address, _port, false, _service, _instance); - multicast_info[_service][_instance] = endpoint_def; + multicast_info_[_service][_instance] = endpoint_def; } if (its_endpoint) { - if (!multicast_known) { + if (!is_known_multicast) { std::lock_guard its_lock(endpoint_mutex_); service_instances_multicast_[_service][_sender] = _instance; } - auto its_udp_server_endpoint - = std::dynamic_pointer_cast(its_endpoint); - its_udp_server_endpoint->join(_address.to_string()); + auto its_udp_server_endpoint = + std::dynamic_pointer_cast(its_endpoint); + if (its_udp_server_endpoint) + its_udp_server_endpoint->join(_address.to_string()); } else { VSOMEIP_ERROR << "Could not find/create multicast endpoint!"; } } void endpoint_manager_impl::clear_multicast_endpoints(service_t _service, instance_t _instance) { - std::shared_ptr multicast_endpoint; - std::string address; + std::shared_ptr its_multicast_endpoint; + std::string its_address; { std::lock_guard its_lock(endpoint_mutex_); // Clear multicast info and endpoint and multicast instance (remote service) - if (multicast_info.find(_service) != multicast_info.end()) { - if (multicast_info[_service].find(_instance) != multicast_info[_service].end()) { - address = multicast_info[_service][_instance]->get_address().to_string(); - uint16_t port = multicast_info[_service][_instance]->get_port(); - auto found_port = server_endpoints_.find(port); + if (multicast_info_.find(_service) != multicast_info_.end()) { + if (multicast_info_[_service].find(_instance) != multicast_info_[_service].end()) { + its_address = multicast_info_[_service][_instance]->get_address().to_string(); + uint16_t its_port = multicast_info_[_service][_instance]->get_port(); + auto found_port = server_endpoints_.find(its_port); if (found_port != server_endpoints_.end()) { auto found_unreliable = found_port->second.find(false); if (found_unreliable != found_port->second.end()) { - multicast_endpoint = found_unreliable->second; - server_endpoints_[port].erase(false); + its_multicast_endpoint = found_unreliable->second; + server_endpoints_[its_port].erase(false); } if (found_port->second.find(true) == found_port->second.end()) { - server_endpoints_.erase(port); + server_endpoints_.erase(its_port); } } - multicast_info[_service].erase(_instance); - if (0 >= multicast_info[_service].size()) { - multicast_info.erase(_service); + multicast_info_[_service].erase(_instance); + if (0 >= multicast_info_[_service].size()) { + multicast_info_.erase(_service); } (void)remove_instance_multicast(_service, _instance); } } } - if (multicast_endpoint) { - dynamic_cast( - multicast_endpoint.get())->leave(address); - - multicast_endpoint->stop(); + if (its_multicast_endpoint) { + auto its_udp_server_endpoint = + std::dynamic_pointer_cast(its_multicast_endpoint); + if (its_udp_server_endpoint) + its_udp_server_endpoint->leave(its_address); + + if (!is_used_endpoint(its_multicast_endpoint.get())) + its_multicast_endpoint->stop(); } } @@ -574,17 +593,17 @@ void endpoint_manager_impl::print_status() const { // udp and tcp client endpoints { - client_endpoints_by_ip_t client_endpoints_by_ip; - server_endpoints_t server_endpoints; + client_endpoints_t its_client_endpoints; + server_endpoints_t its_server_endpoints; { - std::lock_guard its_lock(endpoint_mutex_); - client_endpoints_by_ip = client_endpoints_by_ip_; - server_endpoints = server_endpoints_; + std::scoped_lock its_lock {endpoint_mutex_}; + its_client_endpoints = client_endpoints_; + its_server_endpoints = server_endpoints_; } VSOMEIP_INFO << "status start remote client endpoints:"; std::uint32_t num_remote_client_endpoints(0); // normal endpoints - for (const auto &its_address : 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) { for (const auto &its_partition : its_reliability.second) { @@ -603,7 +622,7 @@ void endpoint_manager_impl::print_status() const { static_cast(rm_)->print_stub_status(); // server endpoints - for (const auto& p : server_endpoints) { + for (const auto& p : its_server_endpoints) { for (const auto& ru : p.second ) { ru.second->print_status(); num_server_endpoints++; @@ -614,11 +633,9 @@ void endpoint_manager_impl::print_status() const { } } -bool -endpoint_manager_impl::create_routing_root( - std::shared_ptr &_root, - bool &_is_socket_activated, - const std::shared_ptr &_host) { +bool endpoint_manager_impl::create_routing_root(std::shared_ptr& _root, + bool& _is_socket_activated, + const std::shared_ptr& _host) { std::stringstream its_endpoint_path_ss; its_endpoint_path_ss << utility::get_base_path(configuration_->get_network()) @@ -639,8 +656,8 @@ endpoint_manager_impl::create_routing_root( } if (configuration_->is_local_routing()) { - uint32_t native_socket_fd = 0; - int32_t num_fd = 0; + int its_socket {0}; + int32_t num_fd {0}; #ifndef WITHOUT_SYSTEMD num_fd = sd_listen_fds(0); #endif @@ -649,109 +666,133 @@ endpoint_manager_impl::create_routing_root( if (num_fd > 1) { VSOMEIP_ERROR << "Too many file descriptors received by systemd socket activation! num_fd: " << num_fd; } else if (num_fd == 1) { - native_socket_fd = SD_LISTEN_FDS_START + 0; - VSOMEIP_INFO << "Using native socket created by systemd socket activation! fd: " << native_socket_fd; + its_socket = SD_LISTEN_FDS_START + 0; + VSOMEIP_INFO << "Using native socket created by systemd socket activation! fd: " << its_socket; if (is_local_routing_) { try { - _root = - std::make_shared ( - shared_from_this(), _host, -#if VSOMEIP_BOOST_VERSION < 106600 - boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), -#else - boost::asio::local::stream_protocol::endpoint(its_endpoint_path), -#endif - io_, - native_socket_fd, - configuration_, true); - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Routing endpoint creation failed. Client ID: " - << std::hex << std::setw(4) << std::setfill('0') - << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + auto its_root {std::make_shared (shared_from_this(), + _host, io_, configuration_, true)}; + if (its_root) { + boost::asio::local::stream_protocol::endpoint its_endpoint(its_endpoint_path); + boost::system::error_code its_error; + + its_root->init(its_endpoint, its_socket, its_error); + if (its_error) { + VSOMEIP_ERROR << "Routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << its_error.message(); + + its_root->deinit(); + return false; + } + + _root = its_root; + } + } catch (const std::exception& e) { + VSOMEIP_ERROR << __func__ << ": " << e.what(); } } _is_socket_activated = true; - } else { if (is_local_routing_) { - if (-1 == ::unlink(its_endpoint_path.c_str()) && errno != ENOENT) { - VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server unlink failed (" - << its_endpoint_path << "): "<< std::strerror(errno); - } - VSOMEIP_INFO << __func__ << ": Routing root @ " << its_endpoint_path; - try { - _root = - std::make_shared ( - shared_from_this(), _host, -#if VSOMEIP_BOOST_VERSION < 106600 - boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), -#else - boost::asio::local::stream_protocol::endpoint(its_endpoint_path), -#endif - io_, configuration_, true); - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " - << std::hex << std::setw(4) << std::setfill('0') - << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + if (-1 == ::unlink(its_endpoint_path.c_str()) && errno != ENOENT) { + VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server unlink failed (" + << its_endpoint_path << "): "<< std::strerror(errno); + } + VSOMEIP_INFO << __func__ << ": Routing root @ " << its_endpoint_path; + + auto its_root {std::make_shared ( + shared_from_this(), _host, io_, configuration_, true)}; + if (its_root) { + boost::asio::local::stream_protocol::endpoint its_endpoint(its_endpoint_path); + boost::system::error_code its_error; + + its_root->init(its_endpoint, its_error); + if (its_error) { + VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << its_error.message(); + + its_root->deinit(); + return false; + } - return false; + _root = its_root; + } + } catch (const std::exception& e) { + VSOMEIP_ERROR << __func__ << ": " << e.what(); } } - _is_socket_activated = false; } #else - ::unlink(its_endpoint_path.c_str()); - port_t port = VSOMEIP_INTERNAL_BASE_PORT; - VSOMEIP_INFO << __func__ << ": Routing root @ " << std::dec << port; - try { - _root = - std::make_shared ( - shared_from_this(), _host, - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), - io_, configuration_, true); - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " - << std::hex << std::setw(4) << std::setfill('0') - << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); - - return false; + ::unlink(its_endpoint_path.c_str()); + port_t port = VSOMEIP_INTERNAL_BASE_PORT; + VSOMEIP_INFO << __func__ << ": Routing root @ " << std::dec << port; + + auto its_root {std::make_shared (shared_from_this(), _host, + io_, configuration_, true)}; + if (its_root) { + boost::asio::ip::tcp::endpoint its_endpoint(boost::asio::ip::tcp::v4(), port); + boost::system::error_code its_error; + + its_root->init(its_endpoint, its_error); + if (its_error) { + VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << its_error.message(); + its_root->deinit(); + return false; + } + + _root = its_root; + } + } catch (const std::exception& e) { + VSOMEIP_ERROR << __func__ << ": " << e.what(); } _is_socket_activated = false; #endif // __linux__ || ANDROID } else { - auto its_address = configuration_->get_routing_host_address(); - auto its_port = configuration_->get_routing_host_port(); - - VSOMEIP_INFO << __func__ << ": Routing root @ " - << its_address.to_string() << ":" << std::dec << its_port; - - bool create_routing_result = false; - for (int attempt = 0; attempt < VSOMEIP_ROUTING_ROOT_RECONNECT_RETRIES; ++attempt) { - try { - _root = - std::make_shared ( - shared_from_this(), _host, - boost::asio::ip::tcp::endpoint(its_address, its_port), - io_, configuration_, true); - create_routing_result = true; - break; - } catch (const std::exception &e) { - VSOMEIP_ERROR << "endpoint_manager_impl::create_routing_root: " - << "Remote routing root endpoint creation failed (Attempt: " << attempt << ")." - << "Client ID: " << std::hex << std::setw(4) << std::setfill('0') - << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); - - std::this_thread::sleep_for( - std::chrono::milliseconds(VSOMEIP_ROUTING_ROOT_RECONNECT_INTERVAL)); - } - } + try { + auto its_address = configuration_->get_routing_host_address(); + auto its_port = configuration_->get_routing_host_port(); + + VSOMEIP_INFO << __func__ << ": Routing root @ " + << its_address.to_string() << ":" << std::dec << its_port; + + auto its_root {std::make_shared (shared_from_this(), _host, + io_, configuration_, true)}; + if (its_root) { + boost::asio::ip::tcp::endpoint its_endpoint(its_address, its_port); + boost::system::error_code its_error; + + int its_retry {0}; + do { + its_root->init(its_endpoint, its_error); + if (its_error) { + VSOMEIP_ERROR << "endpoint_manager_impl::create_routing_root: " + << "Remote routing root endpoint creation failed (" << its_retry << ") " + << "Client: " << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << its_error.message(); + + its_root->deinit(); + std::this_thread::sleep_for( + std::chrono::milliseconds(VSOMEIP_ROUTING_ROOT_RECONNECT_INTERVAL)); + } + its_retry++; + } while (its_retry < VSOMEIP_ROUTING_ROOT_RECONNECT_RETRIES && its_error); + + if (its_error) { + return false; + } - if (!create_routing_result) { - return false; + _root = its_root; + } + } catch (const std::exception& e) { + VSOMEIP_ERROR << __func__ << ": " << e.what(); } _is_socket_activated = false; @@ -790,17 +831,18 @@ instance_t endpoint_manager_impl::find_instance_multicast( bool endpoint_manager_impl::remove_instance(service_t _service, endpoint* const _endpoint) { - std::lock_guard its_lock(endpoint_mutex_); - auto found_service = service_instances_.find(_service); - if (found_service != service_instances_.end()) { - if (found_service->second.erase(_endpoint)) { - if (!found_service->second.size()) { - service_instances_.erase(found_service); + { + std::lock_guard its_lock(endpoint_mutex_); + auto found_service = service_instances_.find(_service); + if (found_service != service_instances_.end()) { + if (found_service->second.erase(_endpoint)) { + if (!found_service->second.size()) { + service_instances_.erase(found_service); + } } } } - _endpoint->decrement_use_count(); - return (_endpoint->get_use_count() == 0); + return !is_used_endpoint(_endpoint); } bool endpoint_manager_impl::remove_instance_multicast(service_t _service, @@ -957,8 +999,7 @@ void endpoint_manager_impl::on_error( std::uint16_t _remote_port) { instance_t its_instance = 0; if (_length >= VSOMEIP_SERVICE_POS_MAX) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); its_instance = find_instance(its_service, _receiver); } static_cast(rm_)->send_error( @@ -1039,9 +1080,9 @@ endpoint_manager_impl::find_remote_client( if (found_reliable != found_instance->second.end()) { std::shared_ptr its_ep_def = found_reliable->second; - auto found_address = client_endpoints_by_ip_.find( + auto found_address = client_endpoints_.find( its_ep_def->get_address()); - if (found_address != client_endpoints_by_ip_.end()) { + if (found_address != client_endpoints_.end()) { auto found_port = found_address->second.find( its_ep_def->get_remote_port()); if (found_port != found_address->second.end()) { @@ -1125,10 +1166,10 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( partition_id_t its_partition = configuration_->get_partition_id(_service, _instance); - client_endpoints_by_ip_[its_endpoint_def->get_address()] - [its_endpoint_def->get_port()] - [_reliable] - [its_partition]= its_endpoint; + client_endpoints_[its_endpoint_def->get_address()] + [its_endpoint_def->get_port()] + [_reliable] + [its_partition]= 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) { @@ -1187,7 +1228,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; + client_endpoints_t its_client_endpoints; std::vector< std::pair< std::tuple, @@ -1197,7 +1238,7 @@ endpoint_manager_impl::log_client_states() const { { std::lock_guard its_lock(endpoint_mutex_); - its_client_endpoints = client_endpoints_by_ip_; + its_client_endpoints = client_endpoints_; } for (const auto &its_address : its_client_endpoints) { @@ -1255,7 +1296,7 @@ endpoint_manager_impl::log_server_states() const { > its_client_queue_sizes; { - std::lock_guard its_lock(endpoint_mutex_); + std::scoped_lock its_lock {endpoint_mutex_}; its_server_endpoints = server_endpoints_; } @@ -1307,13 +1348,22 @@ endpoint_manager_impl::process_multicast_options() { if (options_queue_.size() > 0) { auto its_front = options_queue_.front(); options_queue_.pop(); - auto its_udp_server_endpoint - = std::dynamic_pointer_cast(its_front.endpoint_); + auto its_udp_server_endpoint = + std::dynamic_pointer_cast(its_front.endpoint_); if (its_udp_server_endpoint) { // Unlock before setting the option as this might block its_lock.unlock(); + + boost::system::error_code its_error; its_udp_server_endpoint->set_multicast_option( - its_front.address_, its_front.is_join_); + its_front.address_, its_front.is_join_, its_error); + + if (its_error) { + VSOMEIP_ERROR << __func__ << ": " + << (its_front.is_join_ ? "joining " : "leaving ") + << its_front.address_ << " (" << its_error.message() << ")"; + } + // Lock again after setting the option its_lock.lock(); } @@ -1323,4 +1373,81 @@ endpoint_manager_impl::process_multicast_options() { } } +bool endpoint_manager_impl::is_used_endpoint(endpoint* const _endpoint) const { + + { + std::lock_guard its_lock(endpoint_mutex_); + // Do we still use the endpoint to offer a service instance? + for (const auto& si : service_instances_) + if (si.second.find(_endpoint) != si.second.end()) + return true; + } + + // Do we still use the endpoint to join a multicast address= + auto its_udp_server_endpoint = dynamic_cast(_endpoint); + if (its_udp_server_endpoint) + return its_udp_server_endpoint->is_joining(); + + return false; +} + +void endpoint_manager_impl::suspend(void) { + + client_endpoints_t its_client_endpoints; + server_endpoints_t its_server_endpoints; + { + // TODO: Check whether we can avoid copying + std::scoped_lock its_lock {endpoint_mutex_}; + its_client_endpoints = client_endpoints_; + its_server_endpoints = server_endpoints_; + } + + // stop client endpoints + for (auto& its_address : its_client_endpoints) { + for (auto& its_port : its_address.second) { + for (auto& its_protocol : its_port.second) { + for (auto& its_partition : its_protocol.second) { + its_partition.second->stop(); + } + } + } + } + + // start server endpoints + for (auto& its_port : its_server_endpoints) { + for (auto& its_protocol : its_port.second) { + its_protocol.second->stop(); + } + } +} + +void endpoint_manager_impl::resume(void) { + client_endpoints_t its_client_endpoints; + server_endpoints_t its_server_endpoints; + { + // TODO: Check whether we can avoid copying + std::scoped_lock its_lock {endpoint_mutex_}; + its_client_endpoints = client_endpoints_; + its_server_endpoints = server_endpoints_; + } + + // start server endpoints + for (auto& its_port : its_server_endpoints) { + for (auto& its_protocol : its_port.second) { + its_protocol.second->restart(); + } + } + + // start client endpoints + for (auto& its_address : its_client_endpoints) { + for (auto& its_port : its_address.second) { + for (auto& its_protocol : its_port.second) { + for (auto& its_partition : its_protocol.second) { + its_partition.second->restart(); + } + } + } + } +} + } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp index 693f8f210..b4f00dc55 100644 --- a/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp @@ -3,6 +3,7 @@ // 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 @@ -26,22 +27,17 @@ local_tcp_client_endpoint_impl::local_tcp_client_endpoint_impl( const endpoint_type &_remote, boost::asio::io_context &_io, const std::shared_ptr &_configuration) - : local_tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, - _local, _remote, _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), + : local_tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, _remote, _io, + _configuration), recv_buffer_(VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE, 0) { is_supporting_magic_cookies_ = false; -} - -local_tcp_client_endpoint_impl::~local_tcp_client_endpoint_impl() { + this->max_message_size_ = _configuration->get_max_message_size_local(); + this->queue_limit_ = _configuration->get_endpoint_queue_limit_local(); } bool local_tcp_client_endpoint_impl::is_local() const { - return true; } @@ -67,12 +63,13 @@ void local_tcp_client_endpoint_impl::restart(bool _force) { } void local_tcp_client_endpoint_impl::start() { - - { - std::lock_guard its_lock(mutex_); - sending_blocked_ = false; + if (state_ == cei_state_e::CLOSED) { + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + } + connect(); } - connect(); } void local_tcp_client_endpoint_impl::stop() { @@ -113,21 +110,56 @@ void local_tcp_client_endpoint_impl::stop() { void local_tcp_client_endpoint_impl::connect() { boost::system::error_code its_connect_error; - std::lock_guard its_lock(socket_mutex_); + std::unique_lock its_lock(socket_mutex_); boost::system::error_code its_error; socket_->open(remote_.protocol(), its_error); if (!its_error || its_error == boost::asio::error::already_open) { + // Nagle algorithm off + socket_->set_option(boost::asio::ip::tcp::no_delay(true), its_error); + if (its_error) { + VSOMEIP_WARNING << "ltcei::connect: couldn't disable " + << "Nagle algorithm: " << its_error.message() + << " remote:" << remote_.port() + << " endpoint > " << this << " state_ > " << static_cast(state_.load()); + } + socket_->set_option(boost::asio::socket_base::keep_alive(true), its_error); + if (its_error) { + VSOMEIP_WARNING << "ltcei::connect: couldn't enable " + << "keep_alive: " << its_error.message() + << " remote:" << remote_.port() + << " endpoint > " << this << " state_ > " << static_cast(state_.load()); + } + // Setting the TIME_WAIT to 0 seconds forces RST to always be sent in reponse to a FIN + // Since this is endpoint for internal communication, setting the TIME_WAIT to 5 seconds + // should be enough to ensure the ACK to the FIN arrives to the server endpoint. + socket_->set_option(boost::asio::socket_base::linger(true, 5), its_error); + if (its_error) { + VSOMEIP_WARNING << "ltcei::connect: couldn't enable " + << "SO_LINGER: " << its_error.message() + << " remote:" << remote_.port() + << " endpoint > " << this << " state_ > " << static_cast(state_.load()); + } socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error); if (its_error) { - VSOMEIP_WARNING << "local_tcp_client_endpoint_impl::" << __func__ - << ": Cannot enable SO_REUSEADDR" - << "(" << its_error.message() << ")"; + VSOMEIP_WARNING << "ltcei::" << __func__ + << ": Cannot enable SO_REUSEADDR" << "(" << its_error.message() << ")" + << " endpoint > " << this << " state_ > " << static_cast(state_.load()); } socket_->bind(local_, its_error); if (its_error) { - VSOMEIP_WARNING << "local_tcp_client_endpoint_impl::" << __func__ - << ": Cannot bind to client port " << local_.port() - << "(" << its_error.message() << ")"; + VSOMEIP_WARNING << "ltcei::" << __func__ + << ": Cannot bind to client port " << local_.port() << "(" + << its_error.message() << ")" + << " endpoint > " << this << " state_ > " << static_cast(state_.load()); + try { + strand_.post( + std::bind(&client_endpoint_impl::connect_cbk, shared_from_this(), + its_connect_error)); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "ltcei::connect: " << e.what() + << " endpoint > " << this << " state_ > " << static_cast(state_.load()); + } + return; } state_ = cei_state_e::CONNECTING; start_connecting_timer(); @@ -142,15 +174,17 @@ void local_tcp_client_endpoint_impl::connect() { ) ); } else { - VSOMEIP_WARNING << "local_client_endpoint::connect: Error opening socket: " - << its_error.message() << " (" << std::dec << its_error.value() << ")"; + VSOMEIP_WARNING << "ltcei::connect: Error opening socket: " + << its_error.message() << " (" << std::dec << its_error.value() << ")" + << " endpoint > " << this; its_connect_error = its_error; try { strand_.post( std::bind(&client_endpoint_impl::connect_cbk, shared_from_this(), its_connect_error)); } catch (const std::exception &e) { - VSOMEIP_ERROR << "local_client_endpoint_impl::connect: " << e.what(); + VSOMEIP_ERROR << "ltcei::connect: " << e.what() + << " endpoint > " << this; } } } @@ -237,7 +271,7 @@ void local_tcp_client_endpoint_impl::get_configured_times_from_endpoint( (void)_method; (void)_debouncing; (void)_maximum_retention; - VSOMEIP_ERROR << "local_client_endpoint_impl::get_configured_times_from_endpoint called."; + VSOMEIP_ERROR << "ltcei::get_configured_times_from_endpoint called." << " endpoint > " << this; } void local_tcp_client_endpoint_impl::send_magic_cookie() { @@ -248,10 +282,20 @@ void local_tcp_client_endpoint_impl::receive_cbk( boost::system::error_code const &_error, std::size_t _bytes) { if (_error) { - VSOMEIP_INFO << "local_tcp_client_endpoint_impl::" << __func__ << " Error: " << _error.message(); + VSOMEIP_INFO << "ltcei::" << __func__ << " Error: " << _error.message() + << " endpoint > " << this << " state_ > " << static_cast(state_.load()); if (_error == boost::asio::error::operation_aborted) { // endpoint was stopped return; + } else if (_error == boost::asio::error::eof) { + std::scoped_lock its_lock {mutex_}; + sending_blocked_ = false; + queue_.clear(); + queue_size_ = 0; + } else if (_error == boost::asio::error::connection_reset + || _error == boost::asio::error::bad_descriptor) { + restart(true); + return; } error_handler_t handler; { @@ -333,7 +377,8 @@ std::string local_tcp_client_endpoint_impl::get_remote_information() const { bool local_tcp_client_endpoint_impl::check_packetizer_space(std::uint32_t _size) { if (train_->buffer_->size() + _size < train_->buffer_->size()) { - VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; + VSOMEIP_ERROR << "ltcei: Overflow in packetizer addition ~> abort sending!" + << " endpoint > " << this; return false; } if (train_->buffer_->size() + _size > max_message_size_ @@ -355,18 +400,11 @@ std::uint32_t local_tcp_client_endpoint_impl::get_max_allowed_reconnects() const return MAX_RECONNECTS_UNLIMITED; } -bool local_tcp_client_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { - - (void)_service; - (void)_method; - return false; -} - void local_tcp_client_endpoint_impl::max_allowed_reconnects_reached() { - VSOMEIP_ERROR << "local_client_endpoint::max_allowed_reconnects_reached: " - << get_remote_information(); + VSOMEIP_ERROR << "ltcei::max_allowed_reconnects_reached: " + << get_remote_information() + << " endpoint > " << this; error_handler_t handler; { std::lock_guard its_lock(error_handler_mutex_); diff --git a/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp index e9ff0ee40..3f0ce28d8 100644 --- a/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp @@ -21,7 +21,7 @@ #include "../../routing/include/routing_host.hpp" #include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" namespace vsomeip_v3 { @@ -29,57 +29,64 @@ namespace vsomeip_v3 { local_tcp_server_endpoint_impl::local_tcp_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration, bool _is_routing_endpoint) - : local_tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, - _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), + : local_tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _io, _configuration), acceptor_(_io), buffer_shrink_threshold_(_configuration->get_buffer_shrink_threshold()), - local_port_(_local.port()), is_routing_endpoint_(_is_routing_endpoint) { is_supporting_magic_cookies_ = false; - boost::system::error_code ec; - acceptor_.open(_local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); + this->max_message_size_ = _configuration->get_max_message_size_local(); + this->queue_limit_ = _configuration->get_endpoint_queue_limit_local(); +} +bool local_tcp_server_endpoint_impl::is_local() const { + + return true; +} + +void local_tcp_server_endpoint_impl::init(const endpoint_type& _local, + boost::system::error_code& _error) { + std::lock_guard its_lock(acceptor_mutex_); + init_unlocked(_local, _error); +} + +void local_tcp_server_endpoint_impl::init_unlocked(const endpoint_type& _local, + boost::system::error_code& _error) { + acceptor_.open(_local.protocol(), _error); + if (_error) + return; #ifndef _WIN32 - acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), _error); + if (_error) + return; #endif - acceptor_.bind(_local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); + acceptor_.bind(_local, _error); + if (_error) + return; - acceptor_.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); -} + acceptor_.listen(boost::asio::socket_base::max_connections, _error); + if (_error) + return; -local_tcp_server_endpoint_impl::~local_tcp_server_endpoint_impl() { + local_ = _local; + local_port_ = _local.port(); } -bool local_tcp_server_endpoint_impl::is_local() const { - - return true; +void local_tcp_server_endpoint_impl::deinit() { + boost::system::error_code its_error; + acceptor_.close(its_error); } void local_tcp_server_endpoint_impl::start() { std::lock_guard its_lock(acceptor_mutex_); if (!acceptor_.is_open()) { - boost::system::error_code ec; - acceptor_.open(local_.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); - acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); - acceptor_.bind(local_, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); - acceptor_.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); + boost::system::error_code its_error; + init_unlocked(local_, its_error); } if (acceptor_.is_open()) { @@ -210,7 +217,7 @@ bool local_tcp_server_endpoint_impl::add_connection(const client_t &_client, ret = true; } else { VSOMEIP_WARNING << "Attempt to add already existing " - "connection to client " << std::hex << _client; + "connection to client " << std::hex << _client << " endpoint > " << this; } return ret; } @@ -224,15 +231,38 @@ void local_tcp_server_endpoint_impl::remove_connection( void local_tcp_server_endpoint_impl::accept_cbk( const connection::ptr& _connection, boost::system::error_code const &_error) { + if (!_error) { + boost::system::error_code its_error; + endpoint_type remote; + { + std::unique_lock its_socket_lock(_connection->get_socket_lock()); + socket_type &new_connection_socket = _connection->get_socket(); + + // Nagle algorithm off + new_connection_socket.set_option(boost::asio::ip::tcp::no_delay(true), its_error); + if (its_error) { + VSOMEIP_WARNING << "ltsei::accept_cbk: couldn't disable " + << "Nagle algorithm: " << its_error.message() + << " endpoint > " << this; + } + new_connection_socket.set_option(boost::asio::socket_base::keep_alive(true), its_error); + if (its_error) { + VSOMEIP_WARNING << "ltsei::accept_cbk: couldn't enable " + << "keep_alive: " << its_error.message() + << " endpoint > " << this; + } + } + } if (_error != boost::asio::error::bad_descriptor && _error != boost::asio::error::operation_aborted && _error != boost::asio::error::no_descriptors) { start(); } else if (_error == boost::asio::error::no_descriptors) { - VSOMEIP_ERROR << "local_tcp_server_endpoint_impl::accept_cbk: " + VSOMEIP_ERROR << "ltsei::accept_cbk: " << _error.message() << " (" << std::dec << _error.value() - << ") Will try to accept again in 1000ms"; - std::shared_ptr its_timer = + << ") Will try to accept again in 1000ms" + << " endpoint > " << this; + auto its_timer = std::make_shared(io_, std::chrono::milliseconds(1000)); auto its_ep = std::dynamic_pointer_cast( @@ -244,7 +274,6 @@ void local_tcp_server_endpoint_impl::accept_cbk( } }); } - if (!_error) { _connection->start(); } @@ -312,14 +341,16 @@ void local_tcp_server_endpoint_impl::connection::start() { if (recv_buffer_size_ > its_capacity) { VSOMEIP_ERROR << __func__ << "Received buffer size is greater than the buffer capacity!" << " recv_buffer_size_: " << recv_buffer_size_ - << " its_capacity: " << its_capacity; + << " its_capacity: " << its_capacity + << " endpoint > " << this; return; } size_t left_buffer_size = its_capacity - recv_buffer_size_; try { if (missing_capacity_) { if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { - VSOMEIP_ERROR << "Missing receive buffer capacity exceeds allowed maximum!"; + VSOMEIP_ERROR << "Missing receive buffer capacity exceeds allowed maximum!" + << " endpoint > " << this; return; } const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); @@ -347,7 +378,6 @@ void local_tcp_server_endpoint_impl::connection::start() { } is_stopped_ = false; -#if VSOMEIP_BOOST_VERSION < 106600 socket_.async_receive( boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), std::bind( @@ -357,17 +387,6 @@ void local_tcp_server_endpoint_impl::connection::start() { std::placeholders::_2 ) ); -#else - socket_.async_receive( - boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), - std::bind( - &local_tcp_server_endpoint_impl::connection::receive_cbk, - shared_from_this(), - std::placeholders::_1, - std::placeholders::_2 - ) - ); -#endif } } @@ -377,8 +396,9 @@ void local_tcp_server_endpoint_impl::connection::stop() { if (socket_.is_open()) { #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { - VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) - << "' (" << errno << ") " << get_path_local(); + VSOMEIP_ERROR << "ltsei: socket/handle closed already '" + << std::string(std::strerror(errno)) << "' (" << errno << ") " + << get_path_local() << " endpoint > " << this; } #endif boost::system::error_code its_error; @@ -391,8 +411,8 @@ void local_tcp_server_endpoint_impl::connection::send_queued( std::shared_ptr its_server(server_.lock()); if (!its_server) { - VSOMEIP_TRACE << "local_server_endpoint_impl::connection::send_queued " - " couldn't lock server_"; + VSOMEIP_TRACE << "ltsei::connection::send_queued " + " couldn't lock server_" << " endpoint > " << this; return; } @@ -402,7 +422,7 @@ void local_tcp_server_endpoint_impl::connection::send_queued( #if 0 std::stringstream msg; - msg << "lse::sq: "; + msg << "ltsei::sq: "; for (std::size_t i = 0; i < _buffer->size(); i++) msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " "; @@ -457,7 +477,7 @@ void local_tcp_server_endpoint_impl::get_configured_times_from_endpoint( (void)_method; (void)_debouncing; (void)_maximum_retention; - VSOMEIP_ERROR << "local_tcp_server_endpoint_impl::get_configured_times_from_endpoint."; + VSOMEIP_ERROR << "ltsei::get_configured_times_from_endpoint." << " endpoint > " << this; } void local_tcp_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t _buffer, @@ -465,7 +485,8 @@ void local_tcp_server_endpoint_impl::connection::send_cbk(const message_buffer_p (void)_buffer; (void)_bytes; if (_error) - VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message(); + VSOMEIP_WARNING << "ltsei::send_cbk received error: " << _error.message() + << " endpoint > " << this; } void local_tcp_server_endpoint_impl::connection::receive_cbk( @@ -473,8 +494,8 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( { std::shared_ptr its_server(server_.lock()); if (!its_server) { - VSOMEIP_TRACE << "local_server_endpoint_impl::connection::receive_cbk " - " couldn't lock server_"; + VSOMEIP_TRACE << "ltsei::connection::receive_cbk couldn't lock server_" + << " endpoint > " << this; return; } std::shared_ptr its_host = its_server->routing_host_.lock(); @@ -510,7 +531,8 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( #endif if (recv_buffer_size_ + _bytes < recv_buffer_size_) { - VSOMEIP_ERROR << "receive buffer overflow in local server endpoint ~> abort!"; + VSOMEIP_ERROR << "receive buffer overflow in local tcp server endpoint ~> abort!" + << " endpoint > " << this; return; } recv_buffer_size_ += _bytes; @@ -524,7 +546,8 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( its_start = 0 + its_iteration_gap; if (its_start + 3 < its_start) { - VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + VSOMEIP_ERROR << "buffer overflow in local tcp server endpoint ~> abort!" + << " endpoint > " << this; return; } while (its_start + 3 < recv_buffer_size_ + its_iteration_gap && @@ -543,12 +566,7 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( if (!message_is_empty) { if (its_start + protocol::COMMAND_POSITION_SIZE + 3 < recv_buffer_size_ + its_iteration_gap) { - its_command_size = VSOMEIP_BYTES_TO_LONG( - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+3], - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+2], - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+1], - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); - + its_command_size = bithelper::read_uint32_le(&recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); its_end = its_start + protocol::COMMAND_POSITION_SIZE + 3 + its_command_size; } else { its_end = its_start; @@ -559,13 +577,15 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( VSOMEIP_ERROR << "Received a local message which exceeds " << "maximum message size (" << std::dec << its_command_size << ") aborting! local: " << get_path_local() << " remote: " - << get_path_remote(); + << get_path_remote() + << " endpoint > " << this; recv_buffer_.resize(recv_buffer_size_initial_, 0x0); recv_buffer_.shrink_to_fit(); return; } if (its_end + 3 < its_end) { - VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!" + << " endpoint > " << this; return; } while (its_end + 3 < recv_buffer_size_ + its_iteration_gap && @@ -576,7 +596,8 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( its_end ++; } if (its_end + 4 < its_end) { - VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!" + << " endpoint > " << this; return; } // check if we received a full message @@ -609,7 +630,7 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( i - its_iteration_gap < 32; i++) { local_msg << std::setw(2) << (int) recv_buffer_[i] << " "; } - VSOMEIP_ERROR << "lse::c<" << this + VSOMEIP_ERROR << "ltsei::c<" << this << ">rcb: recv_buffer_size is: " << std::dec << recv_buffer_size_ << " but couldn't read " "out command size. recv_buffer_capacity: " @@ -652,7 +673,7 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( = htonl(uint32_t(its_address.to_v4().to_ulong())); } sec_client_.port = htons(its_port); - security::sync_client(&sec_client_); + its_server->configuration_->get_security()->sync_client(&sec_client_); its_host->on_message(&recv_buffer_[its_start], uint32_t(its_end - its_start), its_server.get(), @@ -660,11 +681,13 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( its_address, its_port); } else { VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() - << " endpoint encountered an error[" << ec.value() << "]: " << ec.message(); + << " endpoint encountered an error[" << ec.value() << "]: " + << ec.message() << " endpoint > " << this; } } else { VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() - << " didn't receive VSOMEIP_ASSIGN_CLIENT as first message"; + << " didn't receive VSOMEIP_ASSIGN_CLIENT as first message" + << " endpoint > " << this; } #if 0 std::stringstream local_msg; @@ -693,7 +716,7 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( missing_capacity_ = 0; } } else if (message_is_empty) { - VSOMEIP_ERROR << "Received garbage data."; + VSOMEIP_ERROR << "Received garbage data." << " endpoint > " << this; is_error = true; } } @@ -706,7 +729,7 @@ void local_tcp_server_endpoint_impl::connection::receive_cbk( || is_error) { shutdown_and_close(); its_server->remove_connection(bound_client_); - policy_manager_impl::get()->remove_client_to_sec_client_mapping(bound_client_); + its_server->configuration_->get_policy_manager()->remove_client_to_sec_client_mapping(bound_client_); } else if (_error != boost::asio::error::bad_descriptor) { start(); } @@ -900,21 +923,14 @@ local_tcp_server_endpoint_impl::send_client_identifier( its_command.serialize(its_buffer, its_error); if (its_error != protocol::error_e::ERROR_OK) { - VSOMEIP_ERROR << __func__ + VSOMEIP_ERROR << "ltsei::" << __func__ << ": assign client ack command serialization failed (" - << std::dec << static_cast(its_error) << ")"; + << std::dec << static_cast(its_error) << ")" + << " endpoint > " << this; return; } send(&its_buffer[0], static_cast(its_buffer.size())); } -bool local_tcp_server_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { - - (void)_service; - (void)_method; - return false; -} - } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp b/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp index 56c621dbc..deca6d850 100644 --- a/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp @@ -3,6 +3,7 @@ // 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 @@ -26,18 +27,18 @@ local_uds_client_endpoint_impl::local_uds_client_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _remote, - boost::asio::io_context &_io, + boost::asio::io_context& _io, const std::shared_ptr& _configuration) : local_uds_client_endpoint_base_impl(_endpoint_host, _routing_host, _remote, - _remote, _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), + _remote, _io, _configuration), // Using _remote for the local(!) endpoint is ok, // because we have no bind for local endpoints! recv_buffer_(VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE, 0) { is_supporting_magic_cookies_ = false; + + this->max_message_size_ = _configuration->get_max_message_size_local(); + this->queue_limit_ = _configuration->get_endpoint_queue_limit_local(); } bool local_uds_client_endpoint_impl::is_local() const { @@ -65,8 +66,13 @@ void local_uds_client_endpoint_impl::restart(bool _force) { } void local_uds_client_endpoint_impl::start() { - - connect(); + if (state_ == cei_state_e::CLOSED) { + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + } + connect(); + } } void local_uds_client_endpoint_impl::stop() { @@ -258,6 +264,11 @@ void local_uds_client_endpoint_impl::receive_cbk( if (_error == boost::asio::error::operation_aborted) { // endpoint was stopped return; + } else if (_error == boost::asio::error::eof) { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + queue_.clear(); + queue_size_ = 0; } else if (_error == boost::asio::error::connection_reset || _error == boost::asio::error::bad_descriptor) { restart(true); @@ -361,14 +372,6 @@ std::uint32_t local_uds_client_endpoint_impl::get_max_allowed_reconnects() const return 13; } -bool local_uds_client_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { - - (void)_service; - (void)_method; - return false; -} - void local_uds_client_endpoint_impl::max_allowed_reconnects_reached() { VSOMEIP_ERROR << "local_client_endpoint::max_allowed_reconnects_reached: " diff --git a/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp b/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp index 33876c56c..0b552b455 100644 --- a/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp @@ -23,7 +23,7 @@ #include "../../protocol/include/assign_client_ack_command.hpp" #include "../../routing/include/routing_host.hpp" #include "../../security/include/policy_manager_impl.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" namespace vsomeip_v3 { @@ -31,81 +31,69 @@ namespace vsomeip_v3 { local_uds_server_endpoint_impl::local_uds_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration, bool _is_routing_endpoint) - : local_uds_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, - _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), + : local_uds_server_endpoint_base_impl(_endpoint_host, _routing_host, _io, _configuration), acceptor_(_io), buffer_shrink_threshold_(_configuration->get_buffer_shrink_threshold()), is_routing_endpoint_(_is_routing_endpoint) { is_supporting_magic_cookies_ = false; - boost::system::error_code ec; - acceptor_.open(_local.protocol(), ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": open failed (" << ec.message() << ")"; + this->max_message_size_ = _configuration->get_max_message_size_local(); + this->queue_limit_ = _configuration->get_endpoint_queue_limit_local(); +} - acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": set reuse address option failed (" << ec.message() << ")"; +void local_uds_server_endpoint_impl::init(const endpoint_type& _local, + boost::system::error_code& _error) { + std::lock_guard its_lock(acceptor_mutex_); + acceptor_.open(_local.protocol(), _error); + if (_error) + return; - acceptor_.bind(_local, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": bind failed (" << ec.message() << ")"; + init_helper(_local, _error); +} - acceptor_.listen(boost::asio::socket_base::max_connections, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": listen failed (" << ec.message() << ")"; -#ifndef __QNX__ - if (chmod(_local.path().c_str(), - static_cast(_configuration->get_permissions_uds())) == -1) { - VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); - } - credentials::activate_credentials(acceptor_.native_handle()); -#endif +void local_uds_server_endpoint_impl::init(const endpoint_type& _local, const int _socket, + boost::system::error_code& _error) { + std::lock_guard its_lock(acceptor_mutex_); + acceptor_.assign(_local.protocol(), _socket, _error); + if (_error) + return; + + init_helper(_local, _error); } -local_uds_server_endpoint_impl::local_uds_server_endpoint_impl( - const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, - int native_socket, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint) - : local_uds_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), - acceptor_(_io), - buffer_shrink_threshold_(configuration_->get_buffer_shrink_threshold()), - is_routing_endpoint_(_is_routing_endpoint) { - is_supporting_magic_cookies_ = false; +void local_uds_server_endpoint_impl::init_helper(const endpoint_type& _local, + boost::system::error_code& _error) { + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), _error); + if (_error) + return; - boost::system::error_code ec; - acceptor_.assign(_local.protocol(), native_socket, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": assign failed (" << ec.message() << ")"; + acceptor_.bind(_local, _error); + if (_error) + return; + + acceptor_.listen(boost::asio::socket_base::max_connections, _error); + if (_error) + return; #ifndef __QNX__ if (chmod(_local.path().c_str(), - static_cast(_configuration->get_permissions_uds())) == -1) { - VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); + static_cast(configuration_->get_permissions_uds())) == -1) { + VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); } credentials::activate_credentials(acceptor_.native_handle()); #endif + + local_ = _local; + } -bool local_uds_server_endpoint_impl::is_local() const { - return true; +void local_uds_server_endpoint_impl::deinit() { + std::lock_guard its_lock(acceptor_mutex_); + boost::system::error_code its_error; + acceptor_.close(its_error); } void local_uds_server_endpoint_impl::start() { @@ -153,6 +141,10 @@ void local_uds_server_endpoint_impl::stop() { } } +bool local_uds_server_endpoint_impl::is_local() const { + return true; +} + bool local_uds_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { #if 0 std::stringstream msg; @@ -259,7 +251,7 @@ void local_uds_server_endpoint_impl::accept_cbk( VSOMEIP_ERROR << "local_usd_server_endpoint_impl::accept_cbk: " << _error.message() << " (" << std::dec << _error.value() << ") Will try to accept again in 1000ms"; - std::shared_ptr its_timer = + auto its_timer = std::make_shared(io_, std::chrono::milliseconds(1000)); auto its_ep = std::dynamic_pointer_cast( @@ -341,7 +333,7 @@ void local_uds_server_endpoint_impl::accept_cbk( std::shared_ptr its_routing_host = routing_host_.lock(); its_routing_host->add_known_client(its_client, its_client_host); - if (!policy_manager_impl::get()->check_credentials(its_client, &its_sec_client)) { + if (!configuration_->get_policy_manager()->check_credentials(its_client, &its_sec_client)) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_host->get_client() << " received client credentials from client 0x" << its_client << " which violates the security policy : uid/gid=" @@ -358,8 +350,8 @@ void local_uds_server_endpoint_impl::accept_cbk( add_connection(its_client, _connection); } } else { - policy_manager_impl::get()->store_client_to_sec_client_mapping(its_client, &its_sec_client); - policy_manager_impl::get()->store_sec_client_to_client_mapping(&its_sec_client, its_client); + configuration_->get_policy_manager()->store_client_to_sec_client_mapping(its_client, &its_sec_client); + configuration_->get_policy_manager()->store_sec_client_to_client_mapping(&its_sec_client, its_client); if (!is_routing_endpoint_) { std::shared_ptr its_routing_host = routing_host_.lock(); @@ -470,7 +462,6 @@ void local_uds_server_endpoint_impl::connection::start() { } is_stopped_ = false; -#if VSOMEIP_BOOST_VERSION >= 106600 auto its_storage = std::make_shared( socket_, std::bind( @@ -489,19 +480,6 @@ void local_uds_server_endpoint_impl::connection::start() { ); socket_.async_wait(socket_type::wait_read, local_endpoint_receive_op::receive_cb(its_storage)); -#else - socket_.async_receive( - boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), - std::bind( - &local_uds_server_endpoint_impl::connection::receive_cbk, - shared_from_this(), - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3, - std::placeholders::_4 - ) - ); -#endif } } @@ -677,12 +655,7 @@ void local_uds_server_endpoint_impl::connection::receive_cbk( if (!message_is_empty) { if (its_start + protocol::COMMAND_POSITION_SIZE + 3 < recv_buffer_size_ + its_iteration_gap) { - its_command_size = VSOMEIP_BYTES_TO_LONG( - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+3], - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+2], - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+1], - recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); - + its_command_size = bithelper::read_uint32_le(&recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); its_end = its_start + protocol::COMMAND_POSITION_SIZE + 3 + its_command_size; } else { its_end = its_start; @@ -781,7 +754,7 @@ void local_uds_server_endpoint_impl::connection::receive_cbk( << " because of already existing connection using same client ID"; stop(); return; - } else if (!policy_manager_impl::get()->check_credentials( + } else if (!its_server->configuration_->get_policy_manager()->check_credentials( its_client, &sec_client_)) { VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() << " received client credentials from client 0x" << its_client @@ -859,7 +832,7 @@ void local_uds_server_endpoint_impl::connection::receive_cbk( || is_error) { shutdown_and_close(); its_server->remove_connection(bound_client_); - policy_manager_impl::get()->remove_client_to_sec_client_mapping(bound_client_); + its_server->configuration_->get_policy_manager()->remove_client_to_sec_client_mapping(bound_client_); } else if (_error != boost::asio::error::bad_descriptor) { start(); } @@ -1070,12 +1043,4 @@ local_uds_server_endpoint_impl::send_client_identifier( send(&its_buffer[0], static_cast(its_buffer.size())); } -bool local_uds_server_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { - - (void)_service; - (void)_method; - return false; -} - } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp index 120175367..97f43d49b 100644 --- a/implementation/endpoints/src/server_endpoint_impl.cpp +++ b/implementation/endpoints/src/server_endpoint_impl.cpp @@ -4,6 +4,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include #include #include #include @@ -11,13 +12,8 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -#include -#include -#else #include #include -#endif #include #include @@ -25,7 +21,7 @@ #include "../include/server_endpoint_impl.hpp" #include "../include/endpoint_definition.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" #include "../../service_discovery/include/defines.hpp" @@ -34,17 +30,10 @@ namespace vsomeip_v3 { template server_endpoint_impl::server_endpoint_impl( const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, endpoint_type _local, - boost::asio::io_context &_io, std::uint32_t _max_message_size, - configuration::endpoint_queue_limit_t _queue_limit, + const std::shared_ptr& _routing_host, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) - : endpoint_impl(_endpoint_host, _routing_host, _local, _io, _max_message_size, - _queue_limit, _configuration) { -} - -template -server_endpoint_impl::~server_endpoint_impl() { - + : endpoint_impl(_endpoint_host, _routing_host, _io, _configuration) { } template @@ -52,12 +41,22 @@ void server_endpoint_impl::prepare_stop( const endpoint::prepare_stop_handler_t &_handler, service_t _service) { std::lock_guard its_lock(mutex_); - bool queued_train(false); std::vector its_erased; boost::system::error_code ec; - if (_service == ANY_SERVICE) { // endpoint is shutting down completely + if (_service == ANY_SERVICE) { endpoint_impl::sending_blocked_ = true; + if (std::all_of(targets_.begin(), targets_.end(), + [&](const typename target_data_type::value_type &_t) + { return _t.second.queue_.empty(); })) { + // nothing was queued and all queues are empty -> ensure cbk is called + auto ptr = this->shared_from_this(); + endpoint_impl::io_.post( + [ptr, _handler]() { _handler(ptr); }); + } else { + prepare_stop_handlers_[_service] = _handler; + } + for (auto t = targets_.begin(); t != targets_.end(); t++) { auto its_train (t->second.train_); // cancel dispatch timer @@ -65,10 +64,31 @@ void server_endpoint_impl::prepare_stop( if (its_train->buffer_->size() > 0) { if (queue_train(t, its_train)) its_erased.push_back(t); - queued_train = true; } } } else { + // check if any of the queues contains a message of to be stopped service + bool found_service_msg(false); + for (const auto &t : targets_) { + for (const auto &q : t.second.queue_) { + const service_t its_service = bithelper::read_uint16_be(&(*q.first)[VSOMEIP_SERVICE_POS_MIN]); + if (its_service == _service) { + found_service_msg = true; + break; + } + } + if (found_service_msg) { + break; + } + } + if (found_service_msg) { + prepare_stop_handlers_[_service] = _handler; + } else { // no messages of the to be stopped service are or have been queued + auto ptr = this->shared_from_this(); + endpoint_impl::io_.post( + [ptr, _handler]() { _handler(ptr); }); + } + for (auto t = targets_.begin(); t != targets_.end(); t++) { auto its_train(t->second.train_); for (auto const& passenger_iter : its_train->passengers_) { @@ -78,7 +98,6 @@ void server_endpoint_impl::prepare_stop( // TODO: Queue all(!) trains here... if (queue_train(t, its_train)) its_erased.push_back(t); - queued_train = true; break; } } @@ -87,49 +106,6 @@ void server_endpoint_impl::prepare_stop( for (const auto t : its_erased) targets_.erase(t); - - if (!queued_train) { - if (_service == ANY_SERVICE) { - if (std::all_of(targets_.begin(), targets_.end(), - [&](const typename target_data_type::value_type &_t) - { return _t.second.queue_.empty(); })) { - // nothing was queued and all queues are empty -> ensure cbk is called - auto ptr = this->shared_from_this(); - endpoint_impl::io_.post([ptr, _handler, _service](){ - _handler(ptr, _service); - }); - } else { - prepare_stop_handlers_[_service] = _handler; - } - } else { - // check if any of the queues contains a message of to be stopped service - bool found_service_msg(false); - for (const auto &t : targets_) { - for (const auto &q : t.second.queue_) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*q.first)[VSOMEIP_SERVICE_POS_MIN], - (*q.first)[VSOMEIP_SERVICE_POS_MAX]); - if (its_service == _service) { - found_service_msg = true; - break; - } - } - if (found_service_msg) { - break; - } - } - if (found_service_msg) { - prepare_stop_handlers_[_service] = _handler; - } else { // no messages of the to be stopped service are or have been queued - auto ptr = this->shared_from_this(); - endpoint_impl::io_.post([ptr, _handler, _service](){ - _handler(ptr, _service); - }); - } - } - } else { - prepare_stop_handlers_[_service] = _handler; - } } template @@ -144,7 +120,10 @@ bool server_endpoint_impl::is_client() const { template void server_endpoint_impl::restart(bool _force) { (void)_force; - // intentionally left blank + + boost::system::error_code its_error; + this->init(server_endpoint_impl::local_, its_error); + this->start(); } template @@ -186,12 +165,9 @@ templatebool server_endpoint_impl::send(const uint8 return false; } - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], _data[VSOMEIP_SESSION_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + const client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); clients_mutex_.lock(); auto found_client = clients_.find(its_client); @@ -205,9 +181,8 @@ templatebool server_endpoint_impl::send(const uint8 VSOMEIP_WARNING << "server_endpoint::send: session_id 0x" << std::hex << its_session << " not found for client 0x" << its_client; - const method_t its_method = - VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); + const method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + if (its_service == VSOMEIP_SD_SERVICE && its_method == VSOMEIP_SD_METHOD) { VSOMEIP_ERROR << "Clearing clients map as a request was " @@ -254,15 +229,11 @@ bool server_endpoint_impl::send_intern( break; } if (!prepare_stop_handlers_.empty()) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); if (prepare_stop_handlers_.find(its_service) != prepare_stop_handlers_.end()) { - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], _data[VSOMEIP_SESSION_POS_MAX]); + const method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + const client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); VSOMEIP_WARNING << "server_endpoint::send: Service is stopping, ignoring message: [" << std::hex << std::setfill('0') << std::setw(4) << its_service << "." @@ -287,17 +258,16 @@ bool server_endpoint_impl::send_intern( VSOMEIP_DEBUG << msg.str(); #endif // STEP 1: Check queue limit - if (!check_queue_limit(_data, _size, its_data.queue_size_)) { + if (!check_queue_limit(_data, _size, its_data)) { return false; } + // STEP 2: Cancel the dispatch timer cancel_dispatch_timer(its_target_iterator); // STEP 3: Get configured timings - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); std::chrono::nanoseconds its_debouncing(0), its_retention(0); if (its_service != VSOMEIP_SD_SERVICE && its_method != VSOMEIP_SD_METHOD) { @@ -374,6 +344,13 @@ bool server_endpoint_impl::send_intern( return true; } +template +bool server_endpoint_impl::tp_segmentation_enabled( + service_t /*_service*/, instance_t /*_instance*/, method_t /*_method*/) const { + + return false; +} + template void server_endpoint_impl::send_segments( const tp::tp_split_messages_t &_segments, std::uint32_t _separation_time, @@ -387,10 +364,8 @@ void server_endpoint_impl::send_segments( auto its_now(std::chrono::steady_clock::now()); - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN], (*(_segments[0]))[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*(_segments[0]))[VSOMEIP_METHOD_POS_MIN], (*(_segments[0]))[VSOMEIP_METHOD_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&(*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&(*(_segments[0]))[VSOMEIP_METHOD_POS_MIN]); std::chrono::nanoseconds its_debouncing(0), its_retention(0); if (its_service != VSOMEIP_SD_SERVICE && its_method != VSOMEIP_SD_METHOD) { @@ -409,17 +384,16 @@ void server_endpoint_impl::send_segments( // messages as we will send several now anyway. if (!its_data.train_->passengers_.empty()) { schedule_train(its_data); + its_data.train_ = std::make_shared(); its_data.train_->departure_ = its_now + its_retention; } for (const auto &s : _segments) { - its_data.queue_.emplace_back(std::make_pair(s, _separation_time)); + its_data.queue_.emplace_back(s, _separation_time); its_data.queue_size_ += s->size(); } if (!its_data.is_sending_ && !its_data.queue_.empty()) { // no writing in progress - // respect minimal debounce time - schedule_train(its_data); // ignore retention time and send immediately as the train is full anyway (void)send_queued(its_target_iterator); } @@ -462,15 +436,12 @@ typename endpoint_impl::cms_ret_e server_endpoint_impl::chec if (endpoint_impl::max_message_size_ != MESSAGE_SIZE_UNLIMITED && _size > endpoint_impl::max_message_size_) { if (endpoint_impl::is_supporting_someip_tp_ && _data != nullptr) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - if (tp_segmentation_enabled(its_service, its_method)) { - instance_t its_instance = this->get_instance(its_service); - if (its_instance != 0xFFFF) { + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + instance_t its_instance = this->get_instance(its_service); + + if (its_instance != ANY_INSTANCE) { + if (tp_segmentation_enabled(its_service, its_instance, its_method)) { std::uint16_t its_max_segment_length; std::uint32_t its_separation_time; @@ -491,12 +462,37 @@ typename endpoint_impl::cms_ret_e server_endpoint_impl::chec return ret; } +template +void server_endpoint_impl::recalculate_queue_size(endpoint_data_type &_data) const { + _data.queue_size_ = 0; + for (const auto &q : _data.queue_) { + if (q.first) { + _data.queue_size_ += q.first->size(); + } + } +} + template bool server_endpoint_impl::check_queue_limit(const uint8_t *_data, std::uint32_t _size, - std::size_t _current_queue_size) const { - if (endpoint_impl::queue_limit_ != QUEUE_SIZE_UNLIMITED - && _current_queue_size + _size - > endpoint_impl::queue_limit_) { + endpoint_data_type &_endpoint_data) const { + + // No queue limit --> Fine + if (endpoint_impl::queue_limit_ == QUEUE_SIZE_UNLIMITED) { + return true; + } + + // Current queue size is bigger than the maximum queue size + if (_endpoint_data.queue_size_ >= endpoint_impl::queue_limit_) { + size_t its_error_queue_size { _endpoint_data.queue_size_ }; + recalculate_queue_size(_endpoint_data); + + VSOMEIP_WARNING << __func__ << ": Detected possible queue size underflow (" + << std::dec << its_error_queue_size << "). Recalculating it (" + << std::dec << _endpoint_data.queue_size_ << ")"; + } + + if (_endpoint_data.queue_size_ + _size > endpoint_impl::queue_limit_ + || _endpoint_data.queue_size_ + _size < _size) { // overflow protection service_t its_service(0); method_t its_method(0); client_t its_client(0); @@ -509,14 +505,10 @@ bool server_endpoint_impl::check_queue_limit(const uint8_t *_data, std // [(Command + lowerbyte sender's client ID). // highbyte sender's client ID + lowbyte command size. // lowbyte methodid + highbyte vsomeip length] - its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); } VSOMEIP_ERROR << "sei::send_intern: queue size limit (" << std::dec << endpoint_impl::queue_limit_ @@ -526,7 +518,7 @@ bool server_endpoint_impl::check_queue_limit(const uint8_t *_data, std << std::setw(4) << its_service << "." << std::setw(4) << its_method << "." << std::setw(4) << its_session << "]" - << " queue_size: " << std::dec << _current_queue_size + << " queue_size: " << std::dec << _endpoint_data.queue_size_ << " data size: " << _size; return false; } @@ -609,11 +601,10 @@ void server_endpoint_impl::connect_cbk( } template -void server_endpoint_impl::send_cbk( - const endpoint_type _key, - boost::system::error_code const &_error, std::size_t _bytes) { +void server_endpoint_impl::send_cbk(const endpoint_type _key, + boost::system::error_code const& _error, + std::size_t _bytes) { (void)_bytes; - // Helper auto check_if_all_msgs_for_stopped_service_are_sent = [&]() { bool found_service_msg(false); @@ -627,9 +618,7 @@ void server_endpoint_impl::send_cbk( } for (const auto& t : targets_) { for (const auto& e : t.second.queue_ ) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*e.first)[VSOMEIP_SERVICE_POS_MIN], - (*e.first)[VSOMEIP_SERVICE_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&(*e.first)[VSOMEIP_SERVICE_POS_MIN]); if (its_service == its_stopped_service) { found_service_msg = true; break; @@ -644,9 +633,7 @@ void server_endpoint_impl::send_cbk( } else { // all messages of the to be stopped service have been sent auto handler = stp_hndlr_iter->second; auto ptr = this->shared_from_this(); - endpoint_impl::io_.post([ptr, handler, its_stopped_service](){ - handler(ptr, its_stopped_service); - }); + endpoint_impl::io_.post([ptr, handler]() { handler(ptr); }); stp_hndlr_iter = prepare_stop_handlers_.erase(stp_hndlr_iter); } } @@ -666,15 +653,12 @@ void server_endpoint_impl::send_cbk( if (found_cbk != prepare_stop_handlers_.end()) { auto handler = found_cbk->second; auto ptr = this->shared_from_this(); - endpoint_impl::io_.post([ptr, handler](){ - handler(ptr, ANY_SERVICE); - }); + endpoint_impl::io_.post([ptr, handler]() { handler(ptr); }); prepare_stop_handlers_.erase(found_cbk); } } }; - std::lock_guard its_lock(mutex_); auto it = targets_.find(_key); @@ -698,34 +682,35 @@ void server_endpoint_impl::send_cbk( session_t& its_session ) { if (buffer && buffer->size() > VSOMEIP_SESSION_POS_MAX) { - its_service = VSOMEIP_BYTES_TO_WORD( - (*buffer)[VSOMEIP_SERVICE_POS_MIN], - (*buffer)[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - (*buffer)[VSOMEIP_METHOD_POS_MIN], - (*buffer)[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD( - (*buffer)[VSOMEIP_CLIENT_POS_MIN], - (*buffer)[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - (*buffer)[VSOMEIP_SESSION_POS_MIN], - (*buffer)[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&(*buffer)[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&(*buffer)[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&(*buffer)[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&(*buffer)[VSOMEIP_SESSION_POS_MIN]); } }; + message_buffer_ptr_t its_buffer; if (its_data.queue_.size()) { its_buffer = its_data.queue_.front().first; } + + if (!its_buffer) { + // Pointer not initialized. + its_buffer = std::make_shared(); + VSOMEIP_WARNING << __func__ << ": prevented nullptr de-reference by initializing queue buffer"; + } + service_t its_service(0); method_t its_method(0); client_t its_client(0); session_t its_session(0); if (!_error) { - const std::size_t payload_size = its_data.queue_.front().first->size(); + const std::size_t payload_size = its_buffer->size(); if (payload_size <= its_data.queue_size_) { its_data.queue_size_ -= payload_size; + its_data.queue_.pop_front(); } else { parse_message_ids(its_buffer, its_service, its_method, its_client, its_session); VSOMEIP_WARNING << __func__ << ": prevented queue_size underflow. queue_size: " @@ -734,9 +719,9 @@ void server_endpoint_impl::send_cbk( << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_method << "." << std::hex << std::setw(4) << std::setfill('0') << its_session << "]"; - its_data.queue_size_ = 0; + its_data.queue_.pop_front(); + recalculate_queue_size(its_data); } - its_data.queue_.pop_front(); update_last_departure(its_data); @@ -798,14 +783,14 @@ void server_endpoint_impl::flush_cbk( template void server_endpoint_impl::remove_stop_handler(service_t _service) { - - std::ostream&& its_services_log{VSOMEIP_INFO}; + std::stringstream its_services_log; its_services_log << __func__ << ": "; std::lock_guard its_lock{mutex_}; for (const auto &its_service : prepare_stop_handlers_) its_services_log << std::hex << std::setw(4) << std::setfill('0') << its_service.first << ' '; + VSOMEIP_INFO << its_services_log.str(); prepare_stop_handlers_.erase(_service); } @@ -877,23 +862,11 @@ void server_endpoint_impl::update_last_departure( } // Instantiate template -#ifdef __linux__ -#if VSOMEIP_BOOST_VERSION < 106600 -template class server_endpoint_impl; -#else +#if defined(__linux__) || defined(__QNX__) template class server_endpoint_impl; #endif -#endif - -#ifdef __QNX__ -template class server_endpoint_impl; -#endif template class server_endpoint_impl; template class server_endpoint_impl; -#if VSOMEIP_BOOST_VERSION < 106600 -template class server_endpoint_impl; -#endif - } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index e67551573..124c78b70 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -3,6 +3,7 @@ // 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 @@ -15,9 +16,7 @@ #include "../../routing/include/routing_host.hpp" #include "../include/tcp_client_endpoint_impl.hpp" #include "../../utility/include/utility.hpp" -#include "../../utility/include/byteorder.hpp" - -namespace ip = boost::asio::ip; +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { @@ -28,14 +27,7 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl( const endpoint_type& _remote, boost::asio::io_context &_io, const std::shared_ptr& _configuration) - : tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, - _remote, _io, - _configuration->get_max_message_size_reliable( - _remote.address().to_string(), - _remote.port()), - _configuration->get_endpoint_queue_limit( - _remote.address().to_string(), - _remote.port()), + : tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, _remote, _io, _configuration), recv_buffer_size_initial_(VSOMEIP_SOMEIP_HEADER_SIZE), recv_buffer_(std::make_shared(recv_buffer_size_initial_, 0)), @@ -53,6 +45,12 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl( sent_timer_(_io) { is_supporting_magic_cookies_ = true; + + this->max_message_size_ = _configuration->get_max_message_size_reliable( + _remote.address().to_string(), + _remote.port()); + this->queue_limit_ = _configuration->get_endpoint_queue_limit(_remote.address().to_string(), + _remote.port()); } tcp_client_endpoint_impl::~tcp_client_endpoint_impl() { @@ -68,7 +66,7 @@ bool tcp_client_endpoint_impl::is_local() const { void tcp_client_endpoint_impl::start() { strand_.dispatch(std::bind(&client_endpoint_impl::connect, - this->shared_from_this())); + this->shared_from_this())); } void tcp_client_endpoint_impl::restart(bool _force) { @@ -102,18 +100,10 @@ void tcp_client_endpoint_impl::restart(bool _force) { { std::lock_guard its_lock(self->mutex_); for (const auto &q : self->queue_) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*q.first)[VSOMEIP_SERVICE_POS_MIN], - (*q.first)[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*q.first)[VSOMEIP_METHOD_POS_MIN], - (*q.first)[VSOMEIP_METHOD_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - (*q.first)[VSOMEIP_CLIENT_POS_MIN], - (*q.first)[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - (*q.first)[VSOMEIP_SESSION_POS_MIN], - (*q.first)[VSOMEIP_SESSION_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&(*q.first)[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&(*q.first)[VSOMEIP_METHOD_POS_MIN]); + const client_t its_client = bithelper::read_uint16_be(&(*q.first)[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&(*q.first)[VSOMEIP_SESSION_POS_MIN]); VSOMEIP_WARNING << "tce::restart: dropping message: " << "remote:" << self->get_address_port_remote() << " (" << std::hex << std::setfill('0') @@ -137,13 +127,13 @@ void tcp_client_endpoint_impl::restart(bool _force) { void tcp_client_endpoint_impl::connect() { start_connecting_timer(); - std::lock_guard its_lock(socket_mutex_); + std::unique_lock its_lock(socket_mutex_); boost::system::error_code its_error; socket_->open(remote_.protocol(), its_error); if (!its_error || its_error == boost::asio::error::already_open) { // Nagle algorithm off - socket_->set_option(ip::tcp::no_delay(true), its_error); + socket_->set_option(boost::asio::ip::tcp::no_delay(true), its_error); if (its_error) { VSOMEIP_WARNING << "tcp_client_endpoint::connect: couldn't disable " << "Nagle algorithm: " << its_error.message() @@ -195,6 +185,8 @@ void tcp_client_endpoint_impl::connect() { << " local: " << get_address_port_local() << " remote:" << get_address_port_remote(); + its_lock.unlock(); + std::shared_ptr its_host = endpoint_host_.lock(); if (its_host) { // set new client port depending on service / instance / remote port @@ -219,6 +211,10 @@ void tcp_client_endpoint_impl::connect() { } if (operations_cancelled != 0) { try { + VSOMEIP_WARNING + << "tce::" << __func__ + << ":connecting to: local:" << this->get_address_port_local() + << " remote: " << this->get_address_port_remote(); // don't connect on bind error to avoid using a random port strand_.post(std::bind(&client_endpoint_impl::connect_cbk, shared_from_this(), its_bind_error)); @@ -235,6 +231,9 @@ void tcp_client_endpoint_impl::connect() { state_ = cei_state_e::CONNECTING; connect_timepoint_ = std::chrono::steady_clock::now(); aborted_restart_count_ = 0; + VSOMEIP_WARNING << "tce::" << __func__ + << ":connecting to: local:" << this->get_address_port_local() + << " remote: " << this->get_address_port_remote(); socket_->async_connect( remote_, strand_.wrap( @@ -246,14 +245,17 @@ void tcp_client_endpoint_impl::connect() { ) ); } else { + VSOMEIP_WARNING << "tce::" << __func__ << ": could not connect " + << "(" << its_error.value() << "): " << its_error.message(); std::size_t operations_cancelled; { std::lock_guard its_lock(connecting_timer_mutex_); operations_cancelled = connecting_timer_.cancel(); } if (operations_cancelled != 0) { - VSOMEIP_WARNING << "tcp_client_endpoint::connect: Error opening socket: " - << its_error.message() << " remote:" << get_address_port_remote(); + VSOMEIP_WARNING << "tce::" << __func__ << "Error opening socket: (" << its_error.message() + << "): conneting to local:" << this->get_address_port_local() + << " remote: " << this->get_address_port_remote(); strand_.post(std::bind(&tcp_client_endpoint_base_impl::connect_cbk, shared_from_this(), its_error)); } @@ -327,19 +329,10 @@ void tcp_client_endpoint_impl::receive(message_buffer_ptr_t _recv_buffer, } void tcp_client_endpoint_impl::send_queued(std::pair &_entry) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*_entry.first)[VSOMEIP_SERVICE_POS_MIN], - (*_entry.first)[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*_entry.first)[VSOMEIP_METHOD_POS_MIN], - (*_entry.first)[VSOMEIP_METHOD_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - (*_entry.first)[VSOMEIP_CLIENT_POS_MIN], - (*_entry.first)[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - (*_entry.first)[VSOMEIP_SESSION_POS_MIN], - (*_entry.first)[VSOMEIP_SESSION_POS_MAX]); - + const service_t its_service = bithelper::read_uint16_be(&(*_entry.first)[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&(*_entry.first)[VSOMEIP_METHOD_POS_MIN]); + const client_t its_client = bithelper::read_uint16_be(&(*_entry.first)[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&(*_entry.first)[VSOMEIP_SESSION_POS_MIN]); if (has_enabled_magic_cookies_) { const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); @@ -417,6 +410,9 @@ uint16_t tcp_client_endpoint_impl::get_local_port() const { if (!its_error) { its_port = its_local.port(); return its_port; + } else { + VSOMEIP_WARNING << "tce::" << __func__ << ": couldn't get local endpoint port " + << "(" << its_error.value() << "): " << its_error.message(); } } @@ -846,6 +842,9 @@ std::string tcp_client_endpoint_impl::get_address_port_local() const { its_address_port += its_local_endpoint.address().to_string(ec); its_address_port += ":"; its_address_port.append(std::to_string(its_local_endpoint.port())); + } else { + VSOMEIP_WARNING << "tce" << __func__ << "coudn't get local endpoint: (" << ec.value() + << "): " << ec.message(); } } return its_address_port; @@ -885,7 +884,15 @@ void tcp_client_endpoint_impl::handle_recv_buffer_exception( if (socket_->is_open()) { boost::system::error_code its_error; socket_->shutdown(socket_type::shutdown_both, its_error); + if (its_error) { + VSOMEIP_WARNING << "tce::" << __func__ << ": socket shutdown error " + << "(" << its_error.value() << "): " << its_error.message(); + } socket_->close(its_error); + if (its_error) { + VSOMEIP_WARNING << "tce::" << __func__ << ": socket close error " + << "(" << its_error.value() << "): " << its_error.message(); + } } } @@ -976,18 +983,10 @@ void tcp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, client_t its_client(0); session_t its_session(0); if (_sent_msg && _sent_msg->size() > VSOMEIP_SESSION_POS_MAX) { - its_service = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SERVICE_POS_MIN], - (*_sent_msg)[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_METHOD_POS_MIN], - (*_sent_msg)[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_CLIENT_POS_MIN], - (*_sent_msg)[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SESSION_POS_MIN], - (*_sent_msg)[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SESSION_POS_MIN]); } VSOMEIP_WARNING << "tce::send_cbk received error: " << _error.message() << " (" << std::dec @@ -1002,13 +1001,6 @@ void tcp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, } } -bool tcp_client_endpoint_impl::tp_segmentation_enabled(service_t _service, - method_t _method) const { - (void)_service; - (void)_method; - return false; -} - std::uint32_t tcp_client_endpoint_impl::get_max_allowed_reconnects() const { return MAX_RECONNECTS_UNLIMITED; } @@ -1018,7 +1010,12 @@ void tcp_client_endpoint_impl::max_allowed_reconnects_reached() { } void tcp_client_endpoint_impl::wait_until_sent(const boost::system::error_code &_error) { - + if (_error && _error != boost::asio::error::operation_aborted) { + // This Function is usually called with boost::asio::error::operation_aborted + // and therefore its part of its normal execution path. + VSOMEIP_WARNING << "tce::" << __func__ << ":: (" << _error.value() + << ") message: " << _error.message(); + } std::unique_lock its_lock(mutex_); if (!is_sending_ || !_error) { its_lock.unlock(); diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index 5aef72be9..fa4639d0d 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -16,7 +16,7 @@ #include "../../routing/include/routing_host.hpp" #include "../include/tcp_server_endpoint_impl.hpp" #include "../../utility/include/utility.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace ip = boost::asio::ip; @@ -25,58 +25,57 @@ namespace vsomeip_v3 { tcp_server_endpoint_impl::tcp_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_context &_io, const std::shared_ptr& _configuration) - : tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, - _configuration->get_max_message_size_reliable(_local.address().to_string(), _local.port()), - _configuration->get_endpoint_queue_limit(_local.address().to_string(), _local.port()), - _configuration), + : tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _io, _configuration), acceptor_(_io), buffer_shrink_threshold_(configuration_->get_buffer_shrink_threshold()), - local_port_(_local.port()), // send timeout after 2/3 of configured ttl, warning after 1/3 send_timeout_(configuration_->get_sd_ttl() * 666) { is_supporting_magic_cookies_ = true; +} - boost::system::error_code ec; - acceptor_.open(_local.protocol(), ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": open failed (" << ec.message() << ")"; +bool tcp_server_endpoint_impl::is_local() const { + return false; +} + +void tcp_server_endpoint_impl::init(const endpoint_type& _local, + boost::system::error_code& _error) { + acceptor_.open(_local.protocol(), _error); + if (_error) + return; - acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": set reuse address option failed (" << ec.message() << ")"; + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), _error); + if (_error) + return; #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { - if (setsockopt(acceptor_.native_handle(), - SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), static_cast(its_device.size())) == -1) { + if (setsockopt(acceptor_.native_handle(), SOL_SOCKET, SO_BINDTODEVICE, + its_device.c_str(), static_cast(its_device.size())) == -1) { VSOMEIP_WARNING << "TCP Server: Could not bind to device \"" << its_device << "\""; } } #endif - acceptor_.bind(_local, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": bind failed (" << ec.message() << ")"; + acceptor_.bind(_local, _error); + if (_error) + return; - acceptor_.listen(boost::asio::socket_base::max_connections, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": listen failed (" << ec.message() << ")"; -} + acceptor_.listen(boost::asio::socket_base::max_connections, _error); + if (_error) + return; -tcp_server_endpoint_impl::~tcp_server_endpoint_impl() { -} + local_ = _local; + local_port_ = _local.port(); -bool tcp_server_endpoint_impl::is_local() const { - return false; + this->max_message_size_ = configuration_->get_max_message_size_reliable( + _local.address().to_string(), + _local.port()); + this->queue_limit_ = configuration_->get_endpoint_queue_limit(_local.address().to_string(), + _local.port()); } void tcp_server_endpoint_impl::start() { @@ -135,7 +134,7 @@ bool tcp_server_endpoint_impl::send_error( auto &its_data = its_target_iterator->second; if (check_message_size(nullptr, _size, its_target) == endpoint_impl::cms_ret_e::MSG_OK && - check_queue_limit(_data, _size, its_data.queue_size_)) { + check_queue_limit(_data, _size, its_data)) { its_data.queue_.emplace_back( std::make_pair(std::make_shared(_data, _data + _size), 0)); its_data.queue_size_ += _size; @@ -175,9 +174,7 @@ bool tcp_server_endpoint_impl::send_queued(const target_data_iterator_type _it) for (const auto &its_q : _it->second.queue_) { auto its_buffer(its_q.first); if (its_buffer && its_buffer->size() > VSOMEIP_SESSION_POS_MAX) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*its_buffer)[VSOMEIP_SERVICE_POS_MIN], - (*its_buffer)[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&(*its_buffer)[VSOMEIP_SERVICE_POS_MIN]); its_services.insert(its_service); } } @@ -191,9 +188,7 @@ bool tcp_server_endpoint_impl::send_queued(const target_data_iterator_type _it) << its_service; auto handler = found_cbk->second; auto ptr = this->shared_from_this(); - io_.post([ptr, handler, its_service](){ - handler(ptr, its_service); - }); + io_.post([ptr, handler]() { handler(ptr); }); prepare_stop_handlers_.erase(found_cbk); } } @@ -289,7 +284,7 @@ void tcp_server_endpoint_impl::accept_cbk(const connection::ptr& _connection, VSOMEIP_ERROR<< "tcp_server_endpoint_impl::accept_cbk: " << _error.message() << " (" << std::dec << _error.value() << ") Will try to accept again in 1000ms"; - std::shared_ptr its_timer = + auto its_timer = std::make_shared(io_, std::chrono::milliseconds(1000)); auto its_ep = std::dynamic_pointer_cast( @@ -316,6 +311,14 @@ bool tcp_server_endpoint_impl::is_reliable() const { return true; } +bool tcp_server_endpoint_impl::is_suspended() const { + auto its_routing_host { routing_host_.lock() }; + if (its_routing_host) { + return routing_state_e::RS_SUSPENDED == its_routing_host->get_routing_state(); + } + return false; +} + /////////////////////////////////////////////////////////////////////////////// // class tcp_service_impl::connection /////////////////////////////////////////////////////////////////////////////// @@ -443,8 +446,36 @@ void tcp_server_endpoint_impl::connection::stop() { std::lock_guard its_lock(socket_mutex_); if (socket_.is_open()) { boost::system::error_code its_error; + + auto its_server { server_.lock() }; + if (its_server && its_server->is_suspended()) { + socket_.set_option(boost::asio::socket_base::linger(true, 0), its_error); + if (its_error) { + VSOMEIP_WARNING << "tcp_server_endpoint_impl::connection::stop< " + << get_address_port_remote() + << ">:setting SO_LINGER failed (" + << its_error.message() + << ")"; + } + } + socket_.shutdown(socket_.shutdown_both, its_error); + if (its_error) { + VSOMEIP_WARNING << "tcp_server_endpoint_impl::connection::stop< " + << get_address_port_remote() + << ">:shutting down socket failed (" + << its_error.message() + << ")"; + } + socket_.close(its_error); + if (its_error) { + VSOMEIP_WARNING << "tcp_server_endpoint_impl::connection::stop< " + << get_address_port_remote() + << ">:closing socket failed (" + << its_error.message() + << ")"; + } } } @@ -458,18 +489,10 @@ void tcp_server_endpoint_impl::connection::send_queued( return; } message_buffer_ptr_t its_buffer = _it->second.queue_.front().first; - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*its_buffer)[VSOMEIP_SERVICE_POS_MIN], - (*its_buffer)[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*its_buffer)[VSOMEIP_METHOD_POS_MIN], - (*its_buffer)[VSOMEIP_METHOD_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - (*its_buffer)[VSOMEIP_CLIENT_POS_MIN], - (*its_buffer)[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - (*its_buffer)[VSOMEIP_SESSION_POS_MIN], - (*its_buffer)[VSOMEIP_SESSION_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&(*its_buffer)[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&(*its_buffer)[VSOMEIP_METHOD_POS_MIN]); + const client_t its_client = bithelper::read_uint16_be(&(*its_buffer)[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&(*its_buffer)[VSOMEIP_SESSION_POS_MIN]); if (magic_cookies_enabled_) { const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); @@ -594,13 +617,9 @@ void tcp_server_endpoint_impl::connection::receive_cbk( if (utility::is_request( recv_buffer_[its_iteration_gap + VSOMEIP_MESSAGE_TYPE_POS])) { - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - recv_buffer_[its_iteration_gap + VSOMEIP_CLIENT_POS_MIN], - recv_buffer_[its_iteration_gap + VSOMEIP_CLIENT_POS_MAX]); + const client_t its_client = bithelper::read_uint16_be(&recv_buffer_[its_iteration_gap + VSOMEIP_CLIENT_POS_MIN]); if (its_client != MAGIC_COOKIE_CLIENT) { - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - recv_buffer_[its_iteration_gap + VSOMEIP_SESSION_POS_MIN], - recv_buffer_[its_iteration_gap + VSOMEIP_SESSION_POS_MAX]); + const session_t its_session = bithelper::read_uint16_be(&recv_buffer_[its_iteration_gap + VSOMEIP_SESSION_POS_MIN]); its_server->clients_mutex_.lock(); its_server->clients_[its_client][its_session] = remote_; its_server->clients_mutex_.unlock(); @@ -996,13 +1015,6 @@ std::string tcp_server_endpoint_impl::get_remote_information( + std::to_string(_remote.port()); } -bool tcp_server_endpoint_impl::tp_segmentation_enabled(service_t _service, - method_t _method) const { - (void)_service; - (void)_method; - return false; -} - void tcp_server_endpoint_impl::connection::wait_until_sent(const boost::system::error_code &_error) { std::shared_ptr its_server(server_.lock()); diff --git a/implementation/endpoints/src/tp.cpp b/implementation/endpoints/src/tp.cpp index 359995086..b0879aafd 100644 --- a/implementation/endpoints/src/tp.cpp +++ b/implementation/endpoints/src/tp.cpp @@ -8,7 +8,6 @@ #include #include "../include/tp.hpp" -#include "../../utility/include/byteorder.hpp" #ifdef ANDROID #include "../../configuration/include/internal_android.hpp" diff --git a/implementation/endpoints/src/tp_message.cpp b/implementation/endpoints/src/tp_message.cpp index 986976f08..7cb77b804 100644 --- a/implementation/endpoints/src/tp_message.cpp +++ b/implementation/endpoints/src/tp_message.cpp @@ -10,7 +10,7 @@ #include "../include/tp_message.hpp" #include "../include/tp.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #ifdef ANDROID #include "../../configuration/include/internal_android.hpp" @@ -47,11 +47,7 @@ tp_message::tp_message(const byte_t* const _data, std::uint32_t _data_length, const length_t its_segment_size = _data_length - VSOMEIP_FULL_HEADER_SIZE - VSOMEIP_TP_HEADER_SIZE; - const tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - _data[VSOMEIP_TP_HEADER_POS_MIN], - _data[VSOMEIP_TP_HEADER_POS_MIN + 1], - _data[VSOMEIP_TP_HEADER_POS_MIN + 2], - _data[VSOMEIP_TP_HEADER_POS_MAX]); + const tp_header_t its_tp_header = bithelper::read_uint32_be(&_data[VSOMEIP_TP_HEADER_POS_MIN]); if (check_lengths(_data, _data_length, its_segment_size, tp::more_segments(its_tp_header))) { @@ -82,11 +78,7 @@ bool tp_message::add_segment(const byte_t* const _data, const length_t its_segment_size = _data_length - VSOMEIP_FULL_HEADER_SIZE - VSOMEIP_TP_HEADER_SIZE; - const tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - _data[VSOMEIP_TP_HEADER_POS_MIN], - _data[VSOMEIP_TP_HEADER_POS_MIN + 1], - _data[VSOMEIP_TP_HEADER_POS_MIN + 2], - _data[VSOMEIP_TP_HEADER_POS_MAX]); + const tp_header_t its_tp_header = bithelper::read_uint32_be(&_data[VSOMEIP_TP_HEADER_POS_MIN]); if (check_lengths(_data, _data_length, its_segment_size, tp::more_segments(its_tp_header))) { @@ -259,14 +251,11 @@ std::chrono::steady_clock::time_point tp_message::get_creation_time() const { std::string tp_message::get_message_id(const byte_t* const _data, std::uint32_t _data_length) { std::stringstream ss; if (_data_length >= VSOMEIP_FULL_HEADER_SIZE) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], _data[VSOMEIP_SESSION_POS_MAX]); + + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + const service_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + const service_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + const service_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); const interface_version_t its_interface_version = _data[VSOMEIP_INTERFACE_VERSION_POS]; const message_type_e its_msg_type = tp::tp_flag_unset( @@ -282,11 +271,7 @@ std::string tp_message::get_message_id(const byte_t* const _data, std::uint32_t << std::setw(4) << its_session << "] "; if (_data_length > VSOMEIP_TP_HEADER_POS_MAX) { - const tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - _data[VSOMEIP_TP_HEADER_POS_MIN], - _data[VSOMEIP_TP_HEADER_POS_MIN + 1], - _data[VSOMEIP_TP_HEADER_POS_MIN + 2], - _data[VSOMEIP_TP_HEADER_POS_MAX]); + const tp_header_t its_tp_header = bithelper::read_uint32_be(&_data[VSOMEIP_TP_HEADER_POS_MIN]); const length_t its_offset = tp::get_offset(its_tp_header); ss << " TP offset: 0x" << std::hex << its_offset << " "; } @@ -297,17 +282,11 @@ std::string tp_message::get_message_id(const byte_t* const _data, std::uint32_t bool tp_message::check_lengths(const byte_t* const _data, std::uint32_t _data_length, length_t _segment_size, bool _more_fragments) { - const length_t its_length = VSOMEIP_BYTES_TO_LONG( - _data[VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_LENGTH_POS_MAX]); - const tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - _data[VSOMEIP_TP_HEADER_POS_MIN], - _data[VSOMEIP_TP_HEADER_POS_MIN + 1], - _data[VSOMEIP_TP_HEADER_POS_MIN + 2], - _data[VSOMEIP_TP_HEADER_POS_MAX]); + + const length_t its_length = bithelper::read_uint32_be(&_data[VSOMEIP_LENGTH_POS_MIN]); + const tp_header_t its_tp_header = bithelper::read_uint32_be(&_data[VSOMEIP_TP_HEADER_POS_MIN]); bool ret(true); + if (!tp::tp_flag_is_set(_data[VSOMEIP_MESSAGE_TYPE_POS])) { VSOMEIP_ERROR << __func__ << ": TP flag not set " << get_message_id(_data, _data_length); @@ -343,14 +322,16 @@ bool tp_message::check_lengths(const byte_t* const _data, << " data: " << std::dec << _data_length << " header: " << std::dec << its_length; ret = false; - } else if (current_message_size_ + _segment_size > max_message_size_) { + } else if (current_message_size_ + _segment_size > max_message_size_ + || current_message_size_ + _segment_size < _segment_size) { // overflow check VSOMEIP_ERROR << __func__ << ": Message exceeds maximum configured size: " << get_message_id(_data, _data_length) << "segment size: " << std::dec << _segment_size << " current message size: " << std::dec << current_message_size_ << " maximum message size: " << std::dec << max_message_size_; ret = false; - } else if (tp::get_offset(its_tp_header) + _segment_size > max_message_size_ ) { + } else if (tp::get_offset(its_tp_header) + _segment_size > max_message_size_ + || tp::get_offset(its_tp_header) + _segment_size < _segment_size) { // overflow check VSOMEIP_ERROR << __func__ << ": SomeIP/TP offset field exceeds maximum configured message size: " << get_message_id(_data, _data_length) << " TP offset [bytes]: " << std::dec << tp::get_offset(its_tp_header) diff --git a/implementation/endpoints/src/tp_reassembler.cpp b/implementation/endpoints/src/tp_reassembler.cpp index a1d0b45ae..f235957fc 100644 --- a/implementation/endpoints/src/tp_reassembler.cpp +++ b/implementation/endpoints/src/tp_reassembler.cpp @@ -12,7 +12,7 @@ #include #include "../include/tp.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #ifdef ANDROID #include "../../configuration/include/internal_android.hpp" @@ -39,14 +39,10 @@ std::pair tp_reassembler::process_tp_message( cleanup_timer_start(false); - const service_t its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + const method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + const client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); const interface_version_t its_interface_version = _data[VSOMEIP_INTERFACE_VERSION_POS]; const message_type_e its_msg_type = tp::tp_flag_unset(_data[VSOMEIP_MESSAGE_TYPE_POS]); @@ -129,11 +125,11 @@ bool tp_reassembler::cleanup_unfinished_messages() { now - tp_id_iter->second.second.get_creation_time()).count() > 5000) { // message is older than 5 seconds delete it - const service_t its_service = static_cast(tp_id_iter->first >> 48); - const method_t its_method = static_cast(tp_id_iter->first >> 32); - const client_t its_client = static_cast(tp_id_iter->first >> 16); - const interface_version_t its_interface_version = static_cast(tp_id_iter->first >> 8); - const message_type_e its_msg_type = static_cast(tp_id_iter->first >> 0); + const auto its_service = static_cast(tp_id_iter->first >> 48); + const auto its_method = static_cast(tp_id_iter->first >> 32); + const auto its_client = static_cast(tp_id_iter->first >> 16); + const auto its_interface_version = static_cast(tp_id_iter->first >> 8); + const auto its_msg_type = static_cast(tp_id_iter->first >> 0); VSOMEIP_WARNING << __func__ << ": deleting unfinished SOME/IP-TP message from: " << ip_iter->first.to_string() << ":" << std::dec diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index f52b23540..4f7bd46ac 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -15,7 +15,7 @@ #include "../../routing/include/routing_host.hpp" #include "../include/udp_client_endpoint_impl.hpp" #include "../../utility/include/utility.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { @@ -26,11 +26,7 @@ udp_client_endpoint_impl::udp_client_endpoint_impl( const endpoint_type& _remote, boost::asio::io_context &_io, const std::shared_ptr& _configuration) - : udp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, - _remote, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, - _configuration->get_endpoint_queue_limit( - _remote.address().to_string(), - _remote.port()), + : udp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, _remote, _io, _configuration), remote_address_(_remote.address()), remote_port_(_remote.port()), @@ -38,6 +34,10 @@ udp_client_endpoint_impl::udp_client_endpoint_impl( tp_reassembler_(std::make_shared( _configuration->get_max_message_size_unreliable(), _io)) { is_supporting_someip_tp_ = true; + + this->max_message_size_ = VSOMEIP_MAX_UDP_MESSAGE_SIZE; + this->queue_limit_ = _configuration->get_endpoint_queue_limit(_remote.address().to_string(), + _remote.port()); } udp_client_endpoint_impl::~udp_client_endpoint_impl() { @@ -560,18 +560,10 @@ void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, client_t its_client(0); session_t its_session(0); if (_sent_msg && _sent_msg->size() > VSOMEIP_SESSION_POS_MAX) { - its_service = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SERVICE_POS_MIN], - (*_sent_msg)[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_METHOD_POS_MIN], - (*_sent_msg)[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_CLIENT_POS_MIN], - (*_sent_msg)[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SESSION_POS_MIN], - (*_sent_msg)[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SESSION_POS_MIN]); } VSOMEIP_WARNING << "uce::send_cbk received error: " << _error.message() << " (" << std::dec @@ -636,18 +628,10 @@ void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, client_t its_client(0); session_t its_session(0); if (_sent_msg && _sent_msg->size() > VSOMEIP_SESSION_POS_MAX) { - its_service = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SERVICE_POS_MIN], - (*_sent_msg)[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_METHOD_POS_MIN], - (*_sent_msg)[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_CLIENT_POS_MIN], - (*_sent_msg)[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - (*_sent_msg)[VSOMEIP_SESSION_POS_MIN], - (*_sent_msg)[VSOMEIP_SESSION_POS_MAX]); + its_service = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_CLIENT_POS_MIN]); + its_session = bithelper::read_uint16_be(&(*_sent_msg)[VSOMEIP_SESSION_POS_MIN]); } VSOMEIP_WARNING << "uce::send_cbk received error: " << _error.message() << " (" << std::dec << _error.value() << ") " @@ -667,11 +651,9 @@ void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, } bool udp_client_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { + service_t _service, instance_t _instance, method_t _method) const { - return configuration_->is_tp_client(_service, - remote_address_.to_string(), remote_port_, - _method); + return configuration_->is_tp_client(_service, _instance, _method); } bool udp_client_endpoint_impl::is_reliable() const { diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index 587fb94c2..23675b4aa 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -8,10 +8,8 @@ #include #include -#if VSOMEIP_BOOST_VERSION >= 106600 #include #include -#endif #include #include @@ -24,7 +22,7 @@ #include "../../configuration/include/configuration.hpp" #include "../../routing/include/routing_host.hpp" #include "../../service_discovery/include/defines.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" namespace ip = boost::asio::ip; @@ -34,124 +32,110 @@ namespace vsomeip_v3 { udp_server_endpoint_impl::udp_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_context &_io, - const std::shared_ptr& _configuration) : -#if VSOMEIP_BOOST_VERSION >= 106600 - server_endpoint_impl( -#else - server_endpoint_impl( -#endif - _endpoint_host, _routing_host, _local, - _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, - _configuration->get_endpoint_queue_limit(_configuration->get_unicast_address().to_string(), _local.port()), - _configuration), - unicast_socket_(_io, _local.protocol()), - unicast_recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0), - is_v4_(false), - multicast_id_(0), - joined_group_(false), - netmask_(_configuration->get_netmask()), - prefix_(_configuration->get_prefix()), - local_port_(_local.port()), - tp_reassembler_(std::make_shared(_configuration->get_max_message_size_unreliable(), _io)), - tp_cleanup_timer_(_io), - is_stopped_(true) { + boost::asio::io_context& _io, const std::shared_ptr& _configuration) : + server_endpoint_impl(_endpoint_host, _routing_host, _io, _configuration), + unicast_recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0), + is_v4_(false), multicast_id_(0), joined_group_(false), netmask_(_configuration->get_netmask()), + prefix_(_configuration->get_prefix()), + tp_reassembler_(std::make_shared( + _configuration->get_max_message_size_unreliable(), _io)), + tp_cleanup_timer_(_io), is_stopped_(true), on_unicast_sent_ {nullptr}, + receive_own_multicast_messages_(false), on_sent_multicast_received_ {nullptr} { is_supporting_someip_tp_ = true; +} - boost::system::error_code ec; +bool udp_server_endpoint_impl::is_local() const { + return false; +} + +void udp_server_endpoint_impl::init(const endpoint_type& _local, + boost::system::error_code& _error) { + + if (!unicast_socket_) { + unicast_socket_ = std::make_shared(io_, _local.protocol()); + if (!unicast_socket_) { + _error = boost::system::errc::make_error_code(boost::system::errc::not_enough_memory); + return; + } + } + + if (!unicast_socket_->is_open()) { + unicast_socket_->open(_local.protocol(), _error); + if (_error) + return; + } boost::asio::socket_base::reuse_address optionReuseAddress(true); - unicast_socket_.set_option(optionReuseAddress, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": set reuse address option failed (" << ec.message() << ")"; + unicast_socket_->set_option(optionReuseAddress, _error); + if (_error) + return; #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { - if (setsockopt(unicast_socket_.native_handle(), - SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), static_cast(its_device.size())) == -1) { + if (setsockopt(unicast_socket_->native_handle(), SOL_SOCKET, SO_BINDTODEVICE, + its_device.c_str(), static_cast(its_device.size())) == -1) { VSOMEIP_WARNING << "UDP Server: Could not bind to device \"" << its_device << "\""; } } #endif - unicast_socket_.bind(_local, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": bind failed (" << ec.message() << ")"; + unicast_socket_->bind(_local, _error); + if (_error) + return; - if (local_.address().is_v4()) { + if (_local.address().is_v4()) { is_v4_ = true; boost::asio::ip::multicast::outbound_interface option(_local.address().to_v4()); - unicast_socket_.set_option(option, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": set IPv4 outbound interface option failed (" << ec.message() << ")"; + unicast_socket_->set_option(option, _error); + if (_error) + return; } else { boost::asio::ip::multicast::outbound_interface option( - static_cast(local_.address().to_v6().scope_id())); - unicast_socket_.set_option(option, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": set IPv6 outbound interface option failed (" << ec.message() << ")"; + static_cast(_local.address().to_v6().scope_id())); + unicast_socket_->set_option(option, _error); + if (_error) + return; } boost::asio::socket_base::broadcast option(true); - unicast_socket_.set_option(option, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": set broadcast option failed (" << ec.message() << ")"; - - const int its_udp_recv_buffer_size = - configuration_->get_udp_receive_buffer_size(); - unicast_socket_.set_option(boost::asio::socket_base::receive_buffer_size( - static_cast(its_udp_recv_buffer_size)), ec); - - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " - << "SO_RCVBUF: " << ec.message() << " to: " << std::dec - << its_udp_recv_buffer_size << " local port: " << std::dec - << local_port_; - } + unicast_socket_->set_option(option, _error); + if (_error) + return; + + const int its_udp_recv_buffer_size = configuration_->get_udp_receive_buffer_size(); + unicast_socket_->set_option(boost::asio::socket_base::receive_buffer_size( + static_cast(its_udp_recv_buffer_size)), _error); + + if (_error) + return; boost::asio::socket_base::receive_buffer_size its_option; - unicast_socket_.get_option(its_option, ec); + unicast_socket_->get_option(its_option, _error); #ifdef __linux__ // If regular setting of the buffer size did not work, try to force // (requires CAP_NET_ADMIN to be successful) - if (its_option.value() < 0 - || its_option.value() < its_udp_recv_buffer_size) { - ec.assign(setsockopt(unicast_socket_.native_handle(), - SOL_SOCKET, SO_RCVBUFFORCE, - &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), - boost::system::generic_category()); - if (!ec) { - VSOMEIP_INFO << "udp_server_endpoint_impl: " - << "SO_RCVBUFFORCE successful."; + if (its_option.value() < 0 || its_option.value() < its_udp_recv_buffer_size) { + _error.assign(setsockopt(unicast_socket_->native_handle(), SOL_SOCKET, SO_RCVBUFFORCE, + &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), + boost::system::generic_category()); + if (!_error) { + VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUFFORCE successful."; } - unicast_socket_.get_option(its_option, ec); + unicast_socket_->get_option(its_option, _error); } #endif - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't get " - << "SO_RCVBUF: " << ec.message() << " local port:" - << std::dec << local_port_; - } else { - VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUF is: " - << std::dec << its_option.value() - << " (" << its_udp_recv_buffer_size << ") local port:" - << std::dec << local_port_; - } -} + if (_error) + return; -udp_server_endpoint_impl::~udp_server_endpoint_impl() { -} + local_ = _local; + local_port_ = _local.port(); -bool udp_server_endpoint_impl::is_local() const { - return false; + this->max_message_size_ = VSOMEIP_MAX_UDP_MESSAGE_SIZE; + this->queue_limit_ = configuration_->get_endpoint_queue_limit( + configuration_->get_unicast_address().to_string(), + local_port_); } void udp_server_endpoint_impl::start() { @@ -162,22 +146,25 @@ void udp_server_endpoint_impl::start() { void udp_server_endpoint_impl::stop() { server_endpoint_impl::stop(); is_stopped_ = true; + { - std::lock_guard its_lock(unicast_mutex_); + std::scoped_lock its_lock {unicast_mutex_}; - if (unicast_socket_.is_open()) { + if (unicast_socket_->is_open()) { boost::system::error_code its_error; - unicast_socket_.cancel(its_error); + unicast_socket_->cancel(its_error); } } { - std::lock_guard its_lock(multicast_mutex_); - + std::scoped_lock its_lock {multicast_mutex_}; if (multicast_socket_ && multicast_socket_->is_open()) { boost::system::error_code its_error; multicast_socket_->cancel(its_error); } + + for (auto& its_joined_address : joined_) + its_joined_address.second = false; } tp_reassembler_->stop(); @@ -197,8 +184,8 @@ void udp_server_endpoint_impl::shutdown_and_close() { void udp_server_endpoint_impl::unicast_shutdown_and_close_unlocked() { boost::system::error_code its_error; - unicast_socket_.shutdown(socket_type::shutdown_both, its_error); - unicast_socket_.close(its_error); + unicast_socket_->shutdown(socket_type::shutdown_both, its_error); + unicast_socket_->close(its_error); } void udp_server_endpoint_impl::multicast_shutdown_and_close_unlocked() { @@ -218,8 +205,8 @@ void udp_server_endpoint_impl::receive_unicast() { std::lock_guard its_lock(unicast_mutex_); - if (unicast_socket_.is_open()) { - unicast_socket_.async_receive_from( + if (unicast_socket_->is_open()) { + unicast_socket_->async_receive_from( boost::asio::buffer(&unicast_recv_buffer_[0], max_message_size_), unicast_remote_, std::bind( @@ -239,10 +226,9 @@ void udp_server_endpoint_impl::receive_unicast() { void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) { if (_multicast_id == multicast_id_ && multicast_socket_ && multicast_socket_->is_open()) { -#if VSOMEIP_BOOST_VERSION >= 106600 auto its_storage = std::make_shared( multicast_mutex_, - *multicast_socket_, + multicast_socket_, multicast_remote_, std::bind( &udp_server_endpoint_impl::on_multicast_received, @@ -261,21 +247,6 @@ void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) { std::numeric_limits::min() ); multicast_socket_->async_wait(socket_type::wait_read, udp_endpoint_receive_op::receive_cb(its_storage)); -#else - multicast_socket_->async_receive_from( - boost::asio::buffer(&multicast_recv_buffer_[0], max_message_size_), - multicast_remote_, - std::bind( - &udp_server_endpoint_impl::on_multicast_received, - std::dynamic_pointer_cast< - udp_server_endpoint_impl >(shared_from_this()), - std::placeholders::_1, - std::placeholders::_2, - _multicast_id, - std::placeholders::_3 - ) - ); -#endif } } @@ -299,7 +270,7 @@ bool udp_server_endpoint_impl::send_error( auto& its_data = its_target_iterator->second; if (check_message_size(nullptr, _size, its_target) == endpoint_impl::cms_ret_e::MSG_OK && - check_queue_limit(_data, _size, its_data.queue_size_)) { + check_queue_limit(_data, _size, its_data)) { its_data.queue_.emplace_back( std::make_pair(std::make_shared(_data, _data + _size), 0)); its_data.queue_size_ += _size; @@ -345,18 +316,15 @@ bool udp_server_endpoint_impl::send_queued( } _it->second.is_sending_ = true; - unicast_socket_.async_send_to( - boost::asio::buffer(*its_entry.first), - _it->first, - std::bind( - &udp_server_endpoint_base_impl::send_cbk, - shared_from_this(), - _it->first, - std::placeholders::_1, - std::placeholders::_2 - ) - ); - + unicast_socket_->async_send_to( + boost::asio::buffer(*its_entry.first), _it->first, + [this, _it, its_entry](boost::system::error_code const& _error, std::size_t _bytes) { + if (!_error && on_unicast_sent_ && !_it->first.address().is_multicast()) { + on_unicast_sent_(&(its_entry.first)->at(0), static_cast(_bytes), + _it->first.address()); + } + send_cbk(_it->first, _error, _bytes); + }); return false; } @@ -380,13 +348,13 @@ bool udp_server_endpoint_impl::is_joined(const std::string &_address) const { } bool udp_server_endpoint_impl::is_joined( - const std::string &_address, bool* _received) const { + const std::string &_address, bool& _received) const { const auto found_address = joined_.find(_address); if (found_address != joined_.end()) { - *_received = found_address->second; + _received = found_address->second; } else { - *_received = false; + _received = false; } return (found_address != joined_.end()); @@ -413,11 +381,7 @@ void udp_server_endpoint_impl::join_unlocked(const std::string &_address) { auto its_endpoint_host = endpoint_host_.lock(); if (its_endpoint_host) { multicast_option_t its_join_option { shared_from_this(), true, -#if VSOMEIP_BOOST_VERSION < 106600 - boost::asio::ip::address::from_string(_address) }; -#else boost::asio::ip::make_address(_address) }; -#endif its_endpoint_host->add_multicast_option(its_join_option); } @@ -428,7 +392,7 @@ void udp_server_endpoint_impl::join_unlocked(const std::string &_address) { } }; - if (!is_joined(_address, &has_received)) { + 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 @@ -454,11 +418,7 @@ void udp_server_endpoint_impl::leave_unlocked(const std::string &_address) { auto its_endpoint_host = endpoint_host_.lock(); if (its_endpoint_host) { multicast_option_t its_leave_option { shared_from_this(), -#if VSOMEIP_BOOST_VERSION < 106600 - false, boost::asio::ip::address::from_string(_address) }; -#else false, boost::asio::ip::make_address(_address) }; -#endif its_endpoint_host->add_multicast_option(its_leave_option); } } @@ -538,16 +498,19 @@ void udp_server_endpoint_impl::on_multicast_received( || _error == boost::asio::error::connection_reset) { shutdown_and_close(); } else if (_error != boost::asio::error::operation_aborted) { - // Filter messages sent from the same source address - if (multicast_remote_.address() != local_.address() - && is_same_subnet(multicast_remote_.address())) { - auto find_joined = joined_.find(_destination.to_string()); - if (find_joined != joined_.end()) - find_joined->second = true; + if (multicast_remote_.address() != local_.address()) { + if (is_same_subnet(multicast_remote_.address())) { + auto find_joined = joined_.find(_destination.to_string()); + if (find_joined != joined_.end()) + find_joined->second = true; - on_message_received(_error, _bytes, true, - multicast_remote_, multicast_recv_buffer_); + on_message_received(_error, _bytes, true, multicast_remote_, + multicast_recv_buffer_); + } + } else if (receive_own_multicast_messages_ && on_sent_multicast_received_) { + on_sent_multicast_received_(&multicast_recv_buffer_[0], static_cast(_bytes), + boost::asio::ip::address()); } receive_multicast(_multicast_id); @@ -631,44 +594,39 @@ void udp_server_endpoint_impl::on_message_received( return; } remaining_bytes -= current_message_size; - const service_t its_service = VSOMEIP_BYTES_TO_WORD(_buffer[i + VSOMEIP_SERVICE_POS_MIN], - _buffer[i + VSOMEIP_SERVICE_POS_MAX]); + const service_t its_service = bithelper::read_uint16_be(&_buffer[i + VSOMEIP_SERVICE_POS_MIN]); + if (utility::is_request( _buffer[i + VSOMEIP_MESSAGE_TYPE_POS])) { - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - _buffer[i + VSOMEIP_CLIENT_POS_MIN], - _buffer[i + VSOMEIP_CLIENT_POS_MAX]); + const client_t its_client = bithelper::read_uint16_be(&_buffer[i + VSOMEIP_CLIENT_POS_MIN]); if (its_client != MAGIC_COOKIE_CLIENT) { - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _buffer[i + VSOMEIP_SESSION_POS_MIN], - _buffer[i + VSOMEIP_SESSION_POS_MAX]); + const session_t its_session = bithelper::read_uint16_be(&_buffer[i + VSOMEIP_SESSION_POS_MIN]); clients_mutex_.lock(); clients_[its_client][its_session] = _remote; clients_mutex_.unlock(); } } if (tp::tp::tp_flag_is_set(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS])) { - const method_t its_method = VSOMEIP_BYTES_TO_WORD(_buffer[i + VSOMEIP_METHOD_POS_MIN], - _buffer[i + VSOMEIP_METHOD_POS_MAX]); - if (!tp_segmentation_enabled(its_service, its_method)) { - VSOMEIP_WARNING << "use: Received a SomeIP/TP message for service: 0x" << std::hex << its_service - << " method: 0x" << its_method << " which is not configured for TP:" - << " local: " << get_address_port_local() - << " remote: " << its_remote_address << ":" << std::dec << its_remote_port; - return; + const method_t its_method = bithelper::read_uint16_be(&_buffer[i + VSOMEIP_METHOD_POS_MIN]); + instance_t its_instance = this->get_instance(its_service); + + if (its_instance != ANY_INSTANCE) { + if (!tp_segmentation_enabled(its_service, its_instance, its_method)) { + VSOMEIP_WARNING << "use: Received a SomeIP/TP message for service: 0x" << std::hex << its_service + << " method: 0x" << its_method << " which is not configured for TP:" + << " local: " << get_address_port_local() + << " remote: " << its_remote_address << ":" << std::dec << its_remote_port; + return; + } } const auto res = tp_reassembler_->process_tp_message( &_buffer[i], current_message_size, its_remote_address, its_remote_port); if (res.first) { if (utility::is_request(res.second[VSOMEIP_MESSAGE_TYPE_POS])) { - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - res.second[VSOMEIP_CLIENT_POS_MIN], - res.second[VSOMEIP_CLIENT_POS_MAX]); + const client_t its_client = bithelper::read_uint16_be(&res.second[VSOMEIP_CLIENT_POS_MIN]); if (its_client != MAGIC_COOKIE_CLIENT) { - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - res.second[VSOMEIP_SESSION_POS_MIN], - res.second[VSOMEIP_SESSION_POS_MAX]); + const session_t its_session = bithelper::read_uint16_be(&res.second[VSOMEIP_SESSION_POS_MIN]); std::lock_guard its_client_lock(clients_mutex_); clients_[its_client][its_session] = _remote; } @@ -701,8 +659,7 @@ void udp_server_endpoint_impl::on_message_received( << " local: " << get_address_port_local() << " remote: " << its_remote_address << ":" << std::dec << its_remote_port; if (remaining_bytes > VSOMEIP_SERVICE_POS_MAX) { - service_t its_service = VSOMEIP_BYTES_TO_WORD(_buffer[VSOMEIP_SERVICE_POS_MIN], - _buffer[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_buffer[VSOMEIP_SERVICE_POS_MIN]); if (its_service != VSOMEIP_SD_SERVICE) { if (read_message_size == 0) { VSOMEIP_ERROR << "Ignoring unreliable vSomeIP message with SomeIP message length 0!"; @@ -724,34 +681,8 @@ void udp_server_endpoint_impl::on_message_received( } bool udp_server_endpoint_impl::is_same_subnet(const boost::asio::ip::address &_address) const { - bool is_same(true); -#if VSOMEIP_BOOST_VERSION < 106600 - // TODO: This needs some (more) testing - if (_address.is_v4()) { - uint32_t its_local(uint32_t(local_.address().to_v4().to_ulong())); - uint32_t its_mask(uint32_t(netmask_.to_v4().to_ulong())); - uint32_t its_address(uint32_t(_address.to_v4().to_ulong())); - return ((its_local & its_mask) == (its_address & its_mask)); - } else { - boost::asio::ip::address_v6::bytes_type its_local(local_.address().to_v6().to_bytes()); - boost::asio::ip::address_v6::bytes_type its_address(_address.to_v6().to_bytes()); - - for (size_t i = 0; i < its_local.size(); ++i) { - byte_t its_mask(0x00); - if ((i+1) * sizeof(byte_t) <= prefix_) - its_mask = 0xff; - else if (i <= prefix_) - its_mask = byte_t(0xff << (((i+1) * sizeof(byte_t)) - prefix_)); - - if ((its_local[i] & its_mask) != (its_address[i] & its_mask)) - return false; - } - - return true; - } -#else if (_address.is_v4()) { boost::asio::ip::network_v4 its_network(local_.address().to_v4(), netmask_.to_v4()); boost::asio::ip::address_v4_range its_hosts = its_network.hosts(); @@ -761,7 +692,7 @@ bool udp_server_endpoint_impl::is_same_subnet(const boost::asio::ip::address &_a boost::asio::ip::address_v6_range its_hosts = its_network.hosts(); is_same = (its_hosts.find(_address.to_v6()) != its_hosts.end()); } -#endif + return is_same; } @@ -816,8 +747,8 @@ std::string udp_server_endpoint_impl::get_address_port_local() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; - if (unicast_socket_.is_open()) { - endpoint_type its_local_endpoint = unicast_socket_.local_endpoint(ec); + if (unicast_socket_->is_open()) { + endpoint_type its_local_endpoint = unicast_socket_->local_endpoint(ec); if (!ec) { its_address_port += its_local_endpoint.address().to_string(ec); its_address_port += ":"; @@ -828,172 +759,187 @@ std::string udp_server_endpoint_impl::get_address_port_local() const { } bool udp_server_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { + service_t _service, instance_t _instance, method_t _method) const { - return configuration_->is_tp_service(_service, - local_.address().to_string(), local_.port(), - _method); + return configuration_->is_tp_service(_service, _instance, _method); } void -udp_server_endpoint_impl::set_multicast_option( - const boost::asio::ip::address &_address, bool _is_join) { - - boost::system::error_code ec; - +udp_server_endpoint_impl::set_multicast_option(const boost::asio::ip::address& _address, + bool _is_join, boost::system::error_code &_error) { + std::scoped_lock its_lock {multicast_mutex_}; if (_is_join) { + // If the multicast socket does not yet exist, create it. if (!multicast_socket_) { - std::lock_guard its_guard(multicast_mutex_); - multicast_socket_ = std::make_unique(io_, local_.protocol()); + if (!multicast_socket_) { + _error = boost::system::errc::make_error_code(boost::system::errc::not_enough_memory); + return; + } + } - multicast_socket_->set_option(ip::udp::socket::reuse_address(true), ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": set reuse address option failed (" << ec.message() << ")"; + // If the multicast socket is not yet open, open it. + if (!multicast_socket_->is_open()) { + multicast_socket_->open(local_.protocol(), _error); + if (_error) { + return; + } + } + + multicast_socket_->set_option(ip::udp::socket::reuse_address(true), _error); + if (_error) { + return; + } #ifdef _WIN32 - const char *its_pktinfo_option("0001"); - ::setsockopt(multicast_socket_->native_handle(), - (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), - (is_v4_ ? IP_PKTINFO : IPV6_PKTINFO), - its_pktinfo_option, sizeof(its_pktinfo_option)); + const char *its_pktinfo_option("0001"); + ::setsockopt(multicast_socket_->native_handle(), + (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), + (is_v4_ ? IP_PKTINFO : IPV6_PKTINFO), + its_pktinfo_option, sizeof(its_pktinfo_option)); #else - int its_pktinfo_option(1); - ::setsockopt(multicast_socket_->native_handle(), - (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), - (is_v4_ ? IP_PKTINFO : IPV6_RECVPKTINFO), - &its_pktinfo_option, sizeof(its_pktinfo_option)); + int its_pktinfo_option(1); + ::setsockopt(multicast_socket_->native_handle(), + (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), + (is_v4_ ? IP_PKTINFO : IPV6_RECVPKTINFO), + &its_pktinfo_option, sizeof(its_pktinfo_option)); #endif - - if (multicast_recv_buffer_.empty()) - multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0); - - if (!multicast_local_) { - if (is_v4_) { - multicast_local_ = std::make_unique - (boost::asio::ip::address_v4::any(), local_port_); - } else { // is_v6 - multicast_local_ = std::make_unique - (boost::asio::ip::address_v6::any(), local_port_); - } - } - - multicast_socket_->bind(*multicast_local_, ec); - if (ec) - VSOMEIP_ERROR << __func__ - << ": bind failed (" << ec.message() << ")"; - - const int its_udp_recv_buffer_size = - configuration_->get_udp_receive_buffer_size(); - - multicast_socket_->set_option(boost::asio::socket_base::receive_buffer_size( - its_udp_recv_buffer_size), ec); - + if (multicast_recv_buffer_.empty()) + multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0); + + if (!multicast_local_) { + if (is_v4_) { + multicast_local_ = std::make_unique + (boost::asio::ip::address_v4::any(), local_port_); + } else { // is_v6 + multicast_local_ = std::make_unique + (boost::asio::ip::address_v6::any(), local_port_); + } + } + + multicast_socket_->bind(*multicast_local_, _error); + if (_error) { + return; + } + + const int its_udp_recv_buffer_size = + configuration_->get_udp_receive_buffer_size(); + + multicast_socket_->set_option(boost::asio::socket_base::receive_buffer_size( + its_udp_recv_buffer_size), _error); + if (_error) { + return; + } #ifndef _WIN32 - // define socket timeout - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = VSOMEIP_SETSOCKOPT_TIMEOUT_US; - - if (setsockopt( - multicast_socket_->native_handle(), - SOL_SOCKET, SO_RCVTIMEO, - &timeout, sizeof(timeout)) == -1) { - VSOMEIP_WARNING << __func__ - << ": unable to setsockopt SO_RCVTIMEO"; - } - - if (setsockopt( - multicast_socket_->native_handle(), - SOL_SOCKET, SO_SNDTIMEO, - &timeout, sizeof(timeout)) == -1) { - VSOMEIP_WARNING << __func__ - << ": unable to setsockopt SO_SNDTIMEO"; - } + // define socket timeout + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = VSOMEIP_SETSOCKOPT_TIMEOUT_US; + + if (setsockopt( + multicast_socket_->native_handle(), + SOL_SOCKET, SO_RCVTIMEO, + &timeout, sizeof(timeout)) == -1) { + VSOMEIP_WARNING << __func__ + << ": unable to setsockopt SO_RCVTIMEO"; + } + + if (setsockopt( + multicast_socket_->native_handle(), + SOL_SOCKET, SO_SNDTIMEO, + &timeout, sizeof(timeout)) == -1) { + VSOMEIP_WARNING << __func__ + << ": unable to setsockopt SO_SNDTIMEO"; + } #endif - - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " - << "SO_RCVBUF: " << ec.message() << " to: " << std::dec - << its_udp_recv_buffer_size << " local port: " << std::dec - << local_port_; - } - - boost::asio::socket_base::receive_buffer_size its_option; - multicast_socket_->get_option(its_option, ec); + boost::asio::socket_base::receive_buffer_size its_option; + multicast_socket_->get_option(its_option, _error); + if (_error) { + return; + } #ifdef __linux__ - // If regular setting of the buffer size did not work, try to force - // (requires CAP_NET_ADMIN to be successful) - if (its_option.value() < 0 - || its_option.value() < its_udp_recv_buffer_size) { - ec.assign(setsockopt(multicast_socket_->native_handle(), - SOL_SOCKET, SO_RCVBUFFORCE, - &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), - boost::system::generic_category()); - if (!ec) { - VSOMEIP_INFO << "udp_server_endpoint_impl: " - << "SO_RCVBUFFORCE: successful."; - } - multicast_socket_->get_option(its_option, ec); - } + // If regular setting of the buffer size did not work, try to force + // (requires CAP_NET_ADMIN to be successful) + if (its_option.value() < 0 + || its_option.value() < its_udp_recv_buffer_size) { + _error.assign(setsockopt(multicast_socket_->native_handle(), + SOL_SOCKET, SO_RCVBUFFORCE, + &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), + boost::system::generic_category()); + if (!_error) { + VSOMEIP_INFO << "udp_server_endpoint_impl: " + << "SO_RCVBUFFORCE: successful."; + } + multicast_socket_->get_option(its_option, _error); + if (_error) { + return; + } + } #endif - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't get " - << "SO_RCVBUF: " << ec.message() << " local port:" - << std::dec << local_port_; - } else { - VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUF is: " - << std::dec << its_option.value() - << " (" << its_udp_recv_buffer_size << ") local port:" - << std::dec << local_port_; - } - - multicast_id_++; - receive_multicast(multicast_id_); - } - - boost::asio::ip::multicast::join_group its_join_option; - { - std::lock_guard its_lock(local_mutex_); - if (is_v4_) { - - its_join_option = boost::asio::ip::multicast::join_group( - _address.to_v4(), - local_.address().to_v4()); - } else { - its_join_option = boost::asio::ip::multicast::join_group( - _address.to_v6(), - static_cast(local_.address().to_v6().scope_id())); + VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUF is: " + << std::dec << its_option.value() + << " (" << its_udp_recv_buffer_size << ") local port:" + << std::dec << local_port_; + + multicast_id_++; + receive_multicast(multicast_id_); + + boost::asio::ip::multicast::join_group its_join_option; + { + std::lock_guard its_lock(local_mutex_); + if (is_v4_) { + its_join_option = boost::asio::ip::multicast::join_group( + _address.to_v4(), + local_.address().to_v4()); + } else { + its_join_option = boost::asio::ip::multicast::join_group( + _address.to_v6(), + static_cast(local_.address().to_v6().scope_id())); + } + } + multicast_socket_->set_option(its_join_option, _error); + + if (!_error) { + std::lock_guard its_guard(multicast_mutex_); + joined_[_address.to_string()] = false; + joined_group_ = true; + } + } else if (multicast_socket_ && multicast_socket_->is_open()) { + boost::asio::ip::multicast::leave_group its_leave_option(_address); + multicast_socket_->set_option(its_leave_option, _error); + + if (!_error) { + joined_.erase(_address.to_string()); + + if (0 == joined_.size()) { + joined_group_ = false; + + multicast_socket_->cancel(_error); + + multicast_socket_.reset(); + multicast_local_.reset(nullptr); } } - multicast_socket_->set_option(its_join_option, ec); + } +} - if (!ec) { - std::lock_guard its_guard(multicast_mutex_); - joined_[_address.to_string()] = false; - joined_group_ = true; - } - } else { - if (multicast_socket_) { - boost::asio::ip::multicast::leave_group its_leave_option(_address); - multicast_socket_->set_option(its_leave_option, ec); +void udp_server_endpoint_impl::set_unicast_sent_callback(const on_unicast_sent_cbk_t& _cbk) { + on_unicast_sent_ = _cbk; +} - if (!ec) { - std::lock_guard its_guard(multicast_mutex_); - joined_.erase(_address.to_string()); +void udp_server_endpoint_impl::set_sent_multicast_received_callback( + const on_sent_multicast_received_cbk_t& _cbk) { + on_sent_multicast_received_ = _cbk; +} - if (0 == joined_.size()) { - joined_group_ = false; +void udp_server_endpoint_impl::set_receive_own_multicast_messages(bool value) { + receive_own_multicast_messages_ = value; +} - multicast_socket_->cancel(ec); +bool udp_server_endpoint_impl::is_joining() const { - multicast_socket_.reset(nullptr); - multicast_local_.reset(nullptr); - } - } - } - } + std::lock_guard its_lock(multicast_mutex_); + return !joined_.empty(); } } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp index cdcbd5197..1ed823964 100644 --- a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp @@ -10,12 +10,12 @@ namespace vsomeip_v3 { -virtual_server_endpoint_impl::virtual_server_endpoint_impl( - const std::string &_address, uint16_t _port, bool _reliable, - boost::asio::io_context &_io) - : address_(_address), port_(_port), reliable_(_reliable), use_count_(0), - io_(_io) { -} +virtual_server_endpoint_impl::virtual_server_endpoint_impl(const std::string& _address, + uint16_t _port, bool _reliable, + boost::asio::io_context& _io) : + + address_(_address), + port_(_port), reliable_(_reliable), io_(_io) { } virtual_server_endpoint_impl::~virtual_server_endpoint_impl() { } @@ -25,10 +25,10 @@ void virtual_server_endpoint_impl::start() { void virtual_server_endpoint_impl::prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service) { + (void)_service; + auto ptr = shared_from_this(); - io_.post([ptr, _handler, _service]() { - _handler(ptr, _service); - }); + io_.post([ptr, _handler]() { _handler(ptr); }); } void virtual_server_endpoint_impl::stop() { @@ -124,20 +124,6 @@ bool virtual_server_endpoint_impl::is_local() const { return true; } - -void virtual_server_endpoint_impl::increment_use_count() { - use_count_++; -} - -void virtual_server_endpoint_impl::decrement_use_count() { - if (use_count_ > 0) - use_count_--; -} - -uint32_t virtual_server_endpoint_impl::get_use_count() { - return use_count_; -} - void virtual_server_endpoint_impl::restart(bool _force) { (void)_force; } diff --git a/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 43b2d9387..000000000 --- a/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,954 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template > -class basic_datagram_socket_ext - : public basic_socket -{ -public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename DatagramSocketService::native_handle_type native_type; - - /// The native representation of a socket. - typedef typename DatagramSocketService::native_handle_type native_handle_type; - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - */ - explicit basic_datagram_socket_ext(boost::asio::io_service& io_service) - : basic_socket(io_service) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket( - BOOST_ASIO_MOVE_CAST(basic_datagram_socket_ext)(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST(basic_datagram_socket_ext)(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - template - basic_datagram_socket_ext( - basic_datagram_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - BOOST_ASIO_MOVE_CAST2(basic_datagram_socket_ext< - Protocol1, DatagramSocketService1>)(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - template - typename enable_if::value, - basic_datagram_socket_ext>::type& operator=( - basic_datagram_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST2(basic_datagram_socket_ext< - Protocol1, DatagramSocketService1>)(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().send_to(this->get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().receive_from(this->get_implementation(), - buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 4af4bac6c..000000000 --- a/implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,1139 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template > -class basic_socket_acceptor_ext - : public basic_io_object, - public socket_base -{ -public: - /// (Deprecated: Use native_handle_type.) The native representation of an - /// acceptor. - typedef typename SocketAcceptorService::native_handle_type native_type; - - /// The native representation of an acceptor. - typedef typename SocketAcceptorService::native_handle_type native_handle_type; - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(boost::asio::io_service& io_service) - : basic_io_object(io_service) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_io_object(io_service) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor_ext acceptor(io_service); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(listen_backlog); - * @endcode - */ - basic_socket_acceptor_ext(boost::asio::io_service& io_service, - const endpoint_type& endpoint, bool reuse_addr = true) - : basic_io_object(io_service) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - this->get_service().set_option(this->get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - this->get_service().listen(this->get_implementation(), - socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor_ext on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : basic_io_object(io_service) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor_ext from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_service&) constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : basic_io_object( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(other)) - { - } - - /// Move-assign a basic_socket_acceptor_ext from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_service&) constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(other)); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor_ext from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. - */ - template - basic_socket_acceptor_ext( - basic_socket_acceptor_ext&& other, - typename enable_if::value>::type* = 0) - : basic_io_object(other.get_io_service()) - { - this->get_service().template converting_move_construct( - this->get_implementation(), other.get_implementation()); - } - - /// Move-assign a basic_socket_acceptor_ext from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. - */ - template - typename enable_if::value, - basic_socket_acceptor_ext>::type& operator=( - basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(BOOST_ASIO_MOVE_CAST2(basic_socket_acceptor_ext< - Protocol1, SocketAcceptorService1>)(other)); - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code open(const protocol_type& protocol, - boost::system::error_code& ec) - { - return this->get_service().open(this->get_implementation(), protocol, ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - boost::system::error_code assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - return this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - return this->get_service().bind(this->get_implementation(), endpoint, ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_connections) - { - boost::system::error_code ec; - this->get_service().listen(this->get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code listen(int backlog, boost::system::error_code& ec) - { - return this->get_service().listen(this->get_implementation(), backlog, ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code close(boost::system::error_code& ec) - { - return this->get_service().close(this->get_implementation(), ec); - } - - /// (Deprecated: Use native_handle().) Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_type native() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - boost::system::error_code cancel(boost::system::error_code& ec) - { - return this->get_service().cancel(this->get_implementation(), ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - return this->get_service().set_option( - this->get_implementation(), option, ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - boost::system::error_code get_option(GettableSocketOption& option, - boost::system::error_code& ec) - { - return this->get_service().get_option( - this->get_implementation(), option, ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - return this->get_service().io_control( - this->get_implementation(), command, ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - boost::system::error_code non_blocking( - bool mode, boost::system::error_code& ec) - { - return this->get_service().non_blocking( - this->get_implementation(), mode, ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - boost::system::error_code native_non_blocking( - bool mode, boost::system::error_code& ec) - { - return this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket& peer, - typename enable_if::value>::type* = 0) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::soocket socket(io_service); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code accept( - basic_socket& peer, - boost::system::error_code& ec, - typename enable_if::value>::type* = 0) - { - return this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - return this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code accept( - basic_socket& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return this->get_service().accept( - this->get_implementation(), peer, &peer_endpoint, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - return this->get_service().async_accept(this->get_implementation(), peer, - &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index ab55eda1e..000000000 --- a/implementation/helper/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,855 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template > -class basic_stream_socket_ext - : public basic_socket -{ -public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename StreamSocketService::native_handle_type native_type; - - /// The native representation of a socket. - typedef typename StreamSocketService::native_handle_type native_handle_type; - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket_ext without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(boost::asio::io_service& io_service) - : basic_socket(io_service) - { - } - - /// Construct and open a basic_stream_socket_ext. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) - { - } - - /// Construct a basic_stream_socket_ext, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) - { - } - - /// Construct a basic_stream_socket_ext on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket_ext from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket( - BOOST_ASIO_MOVE_CAST(basic_stream_socket_ext)(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST(basic_stream_socket_ext)(other)); - return *this; - } - - /// Move-construct a basic_stream_socket_ext from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - template - basic_stream_socket_ext( - basic_stream_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - BOOST_ASIO_MOVE_CAST2(basic_stream_socket_ext< - Protocol1, StreamSocketService1>)(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - template - typename enable_if::value, - basic_stream_socket_ext>::type& operator=( - basic_stream_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST2(basic_stream_socket_ext< - Protocol1, StreamSocketService1>)(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send( - this->get_implementation(), buffers, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send( - this->get_implementation(), buffers, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().send(this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/boost/asio/datagram_socket_service_ext.hpp b/implementation/helper/boost/asio/datagram_socket_service_ext.hpp deleted file mode 100644 index 7648581b6..000000000 --- a/implementation/helper/boost/asio/datagram_socket_service_ext.hpp +++ /dev/null @@ -1,437 +0,0 @@ -// -// datagram_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_EXT_ASIO_DATAGRAM_SOCKET_SERVICE_EXT_HPP -#define BOOST_EXT_ASIO_DATAGRAM_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include "detail/win_iocp_socket_service_ext.hpp" -#else -# include "detail/reactive_socket_service_ext.hpp" -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a datagram socket. -template -class datagram_socket_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_service::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_service::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::null_socket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service_ext service_impl_type; -#else - typedef detail::reactive_socket_service_ext service_impl_type; -#endif - -public: - /// The type of a datagram socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// (Deprecated: Use native_handle_type.) The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_type; -#else - typedef typename service_impl_type::native_handle_type native_type; -#endif - - /// The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new datagram socket service for the specified io_service. - explicit datagram_socket_service_ext(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - datagram_socket_service_ext >(io_service), - service_impl_(io_service) - { - } - - /// Construct a new datagram socket implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new datagram socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another datagram socket implementation. - void move_assign(implementation_type& impl, - datagram_socket_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - /// Move-construct a new datagram socket implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - typename datagram_socket_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a datagram socket implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - // Open a new datagram socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM)) - service_impl_.open(impl, protocol, ec); - else - ec = boost::asio::error::invalid_argument; - return ec; - } - - /// Assign an existing native socket to a datagram socket. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - return service_impl_.assign(impl, protocol, native_socket, ec); - } - - /// Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Close a datagram socket implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.close(impl, ec); - } - - /// (Deprecated: Use native_handle().) Get the native socket implementation. - native_type native(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Get the native socket implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Cancel all asynchronous operations associated with the socket. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.cancel(impl, ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.at_mark(impl, ec); - } - - /// Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.available(impl, ec); - } - - // Bind the datagram socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - return service_impl_.bind(impl, endpoint, ec); - } - - /// Connect the datagram socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return service_impl_.connect(impl, peer_endpoint, ec); - } - - /// Start an asynchronous connect. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - detail::async_result_init< - ConnectHandler, void (boost::system::error_code)> init( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); - - service_impl_.async_connect(impl, peer_endpoint, init.handler); - - return init.result.get(); - } - - /// Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - return service_impl_.set_option(impl, option, ec); - } - - /// Get a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - return service_impl_.get_option(impl, option, ec); - } - - /// Perform an IO control command on the socket. - template - boost::system::error_code io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - return service_impl_.io_control(impl, command, ec); - } - - /// Gets the non-blocking mode of the socket. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.non_blocking(impl, mode, ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.native_non_blocking(impl, mode, ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.remote_endpoint(impl, ec); - } - - /// Disable sends or receives on the socket. - boost::system::error_code shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - return service_impl_.shutdown(impl, what, ec); - } - - /// Send the given data to the peer. - template - std::size_t send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send(impl, buffers, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(implementation_type& impl, const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - detail::async_result_init< - WriteHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - - service_impl_.async_send(impl, buffers, flags, init.handler); - - return init.result.get(); - } - - /// Send a datagram to the specified endpoint. - template - std::size_t send_to(implementation_type& impl, - const ConstBufferSequence& buffers, const endpoint_type& destination, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send_to(impl, buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, const endpoint_type& destination, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - detail::async_result_init< - WriteHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - - service_impl_.async_send_to(impl, buffers, - destination, flags, init.handler); - - return init.result.get(); - } - - /// Receive some data from the peer. - template - std::size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive(impl, buffers, flags, ec); - } - - /// Start an asynchronous receive. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t)) - async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - detail::async_result_init< - ReadHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - - service_impl_.async_receive(impl, buffers, flags, init.handler); - - return init.result.get(); - } - - /// Receive a datagram with the endpoint of the sender. - template - std::size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive_from(impl, buffers, sender_endpoint, flags, - ec); - } - - /// Start an asynchronous receive that will get the endpoint of the sender. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - detail::async_result_init< - ReadHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - - service_impl_.async_receive_from(impl, buffers, - sender_endpoint, flags, init.handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - service_impl_.shutdown_service(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP diff --git a/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 34b03759b..000000000 --- a/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,520 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -// Newer gcc, clang need special treatment to suppress unused typedef warnings. -#if defined(__clang__) -# if defined(__apple_build_version__) -# if (__clang_major__ >= 7) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // (__clang_major__ >= 7) -# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ - || (__clang_major__ > 3) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) - // || (__clang_major__ > 3) -#elif defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -#endif // defined(__GNUC__) -#if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF -#endif // !defined(BOOST_ASIO_UNUSED_TYPEDEF) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ComposedConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 717eb6e84..000000000 --- a/implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,536 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -// Newer gcc, clang need special treatment to suppress unused typedef warnings. -#if defined(__clang__) -# if defined(__apple_build_version__) -# if (__clang_major__ >= 7) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // (__clang_major__ >= 7) -# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ - || (__clang_major__ > 3) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) - // || (__clang_major__ > 3) -#elif defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -#endif // defined(__GNUC__) -#if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF -#endif // !defined(BOOST_ASIO_UNUSED_TYPEDEF) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, \ - std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ComposedConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 3b4a4a85c..000000000 --- a/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,270 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - boost::asio::io_service& io_service) - : reactor_(use_service(io_service)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::shutdown_service() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - } - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, true, is_continuation, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 26521cff1..000000000 --- a/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,270 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - boost::asio::io_service& io_service) - : reactor_(use_service(io_service)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::shutdown_service() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - } - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, true, is_continuation, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index fe90e83e9..000000000 --- a/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,210 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - - error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL), ec); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) - continue; - - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) - continue; - - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 03cdb9298..000000000 --- a/implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,372 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -#ifdef __QNX__ - #define UCRED_T struct sockcred - #define UCRED_UID(x) x->sc_uid - #define UCRED_GID(x) x->sc_gid - - // Reserved memory space to receive credential - // through ancilliary data. - #define CMSG_SIZE 512 -#endif - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; -#ifdef __QNX__ - UCRED_T *ucredp; -#else - struct ucred *ucredp; -#endif - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; -#ifdef __QNX__ - char control[CMSG_SIZE]; -#else - char control[CMSG_SPACE(sizeof(struct ucred))]; -#endif - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive -#ifdef __QNX__ - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(UCRED_T)); -#else - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); -#endif - control_un.cmh.cmsg_level = SOL_SOCKET; -#ifdef __QNX__ - control_un.cmh.cmsg_type = SCM_CREDS; -#else - control_un.cmh.cmsg_type = SCM_CREDENTIALS; -#endif - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { -#ifdef __QNX__ - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDS - || cmsg->cmsg_len != CMSG_LEN(sizeof(UCRED_T))) - continue; -#else - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; -#endif - -#ifdef __QNX__ - ucredp = (UCRED_T *) CMSG_DATA(cmsg); - if (ucredp) { - uid = UCRED_UID(ucredp); - gid = UCRED_GID(ucredp); - } -#else - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } -#endif - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; -#ifdef __QNX__ - UCRED_T *ucredp; -#else - struct ucred *ucredp; -#endif - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; -#ifdef __QNX__ - char control[CMSG_SIZE]; -#else - char control[CMSG_SPACE(sizeof(struct ucred))]; -#endif - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive -#ifdef __QNX__ - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(UCRED_T)); -#else - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); -#endif - control_un.cmh.cmsg_level = SOL_SOCKET; -#ifdef __QNX__ - control_un.cmh.cmsg_type = SCM_CREDS; -#else - control_un.cmh.cmsg_type = SCM_CREDENTIALS; -#endif - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { -#ifdef __QNX__ - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDS - || cmsg->cmsg_len != CMSG_LEN(sizeof(UCRED_T))) - continue; -#else - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; -#endif - -#ifdef __QNX__ - ucredp = (UCRED_T *) CMSG_DATA(cmsg); - if (ucredp) { - uid = UCRED_UID(ucredp); - gid = UCRED_GID(ucredp); - } -#else - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } -#endif - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 531ad21b5..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,126 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_); - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext(socket, state, - buffers, flags, &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index 6c151caf0..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,126 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext_local(socket, state, - buffers, flags, &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 93bdf0126..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,136 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - bool result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_); - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index a38844d88..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,136 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -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_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - bool result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index b28572b30..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_); - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 7b5bc539a..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_); - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext_local(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 3c0107c69..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,455 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext( - boost::asio::io_service& io_service); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void shutdown_service(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index e97fca293..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,454 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local( - boost::asio::io_service& io_service); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void shutdown_service(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 133301c9e..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,462 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(boost::asio::io_service& io_service) - : reactive_socket_service_base_ext(io_service) - { - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - if (!peer.assign(impl.protocol_, new_socket.get(), ec)) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects - // must be valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index 7b444b30e..000000000 --- a/implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,462 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(boost::asio::io_service& io_service) - : reactive_socket_service_base_ext_local(io_service) - { - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - if (!peer.assign(impl.protocol_, new_socket.get(), ec)) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects - // must be valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 948e016cb..000000000 --- a/implementation/helper/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index a10d87645..000000000 --- a/implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // The passed credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 65b8ad86a..000000000 --- a/implementation/helper/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index 77fd56375..000000000 --- a/implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/boost/asio/ip/udp_ext.hpp b/implementation/helper/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index c622ff979..000000000 --- a/implementation/helper/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 6ccd0ad0f..000000000 --- a/implementation/helper/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/boost/asio/socket_acceptor_service_ext.hpp b/implementation/helper/boost/asio/socket_acceptor_service_ext.hpp deleted file mode 100644 index 19a3bde1f..000000000 --- a/implementation/helper/boost/asio/socket_acceptor_service_ext.hpp +++ /dev/null @@ -1,305 +0,0 @@ -// -// socket_acceptor_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP -#define BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a socket acceptor. -template -class socket_acceptor_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_service::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_service::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename protocol_type::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::null_socket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service service_impl_type; -#else - typedef detail::reactive_socket_service_ext service_impl_type; -#endif - -public: - /// The native type of the socket acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// (Deprecated: Use native_handle_type.) The native acceptor type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_type; -#else - typedef typename service_impl_type::native_handle_type native_type; -#endif - - /// The native acceptor type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new socket acceptor service for the specified io_service. - explicit socket_acceptor_service_ext(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - socket_acceptor_service_ext >(io_service), - service_impl_(io_service) - { - } - - /// Construct a new socket acceptor implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new socket acceptor implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another socket acceptor implementation. - void move_assign(implementation_type& impl, - socket_acceptor_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - /// Move-construct a new socket acceptor implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - typename socket_acceptor_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a socket acceptor implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - /// Open a new socket acceptor implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - return service_impl_.open(impl, protocol, ec); - } - - /// Assign an existing native acceptor to a socket acceptor. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_acceptor, - boost::system::error_code& ec) - { - return service_impl_.assign(impl, protocol, native_acceptor, ec); - } - - /// Determine whether the acceptor is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Cancel all asynchronous operations associated with the acceptor. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.cancel(impl, ec); - } - - /// Bind the socket acceptor to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - return service_impl_.bind(impl, endpoint, ec); - } - - /// Place the socket acceptor into the state where it will listen for new - /// connections. - boost::system::error_code listen(implementation_type& impl, int backlog, - boost::system::error_code& ec) - { - return service_impl_.listen(impl, backlog, ec); - } - - /// Close a socket acceptor implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.close(impl, ec); - } - - /// (Deprecated: Use native_handle().) Get the native acceptor implementation. - native_type native(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Get the native acceptor implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - return service_impl_.set_option(impl, option, ec); - } - - /// Get a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - return service_impl_.get_option(impl, option, ec); - } - - /// Perform an IO control command on the socket. - template - boost::system::error_code io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - return service_impl_.io_control(impl, command, ec); - } - - /// Gets the non-blocking mode of the acceptor. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the acceptor. - boost::system::error_code non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.non_blocking(impl, mode, ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - boost::system::error_code native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.native_non_blocking(impl, mode, ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - basic_socket& peer, - endpoint_type* peer_endpoint, boost::system::error_code& ec, - typename enable_if::value>::type* = 0) - { - return service_impl_.accept(impl, peer, peer_endpoint, ec); - } - - /// Start an asynchronous accept. - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(implementation_type& impl, - basic_socket& peer, - endpoint_type* peer_endpoint, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) - { - detail::async_result_init< - AcceptHandler, void (boost::system::error_code)> init( - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); - - service_impl_.async_accept(impl, peer, peer_endpoint, init.handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - service_impl_.shutdown_service(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP diff --git a/implementation/helper/boost/asio/stream_socket_service_ext.hpp b/implementation/helper/boost/asio/stream_socket_service_ext.hpp deleted file mode 100644 index aaa13b356..000000000 --- a/implementation/helper/boost/asio/stream_socket_service_ext.hpp +++ /dev/null @@ -1,379 +0,0 @@ -// -// stream_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a stream socket. -template -class stream_socket_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_service::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_service::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::winrt_ssocket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service service_impl_type; -#else - typedef detail::reactive_socket_service_ext_local service_impl_type; -#endif - -public: - /// The type of a stream socket implementation. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// (Deprecated: Use native_handle_type.) The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_type; -#else - typedef typename service_impl_type::native_handle_type native_type; -#endif - - /// The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new stream socket service for the specified io_service. - explicit stream_socket_service_ext(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - stream_socket_service_ext >(io_service), - service_impl_(io_service) - { - } - - /// Construct a new stream socket implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new stream socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another stream socket implementation. - void move_assign(implementation_type& impl, - stream_socket_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - /// Move-construct a new stream socket implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - typename stream_socket_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a stream socket implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - /// Open a stream socket. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_STREAM)) - service_impl_.open(impl, protocol, ec); - else - ec = boost::asio::error::invalid_argument; - return ec; - } - - /// Assign an existing native socket to a stream socket. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - return service_impl_.assign(impl, protocol, native_socket, ec); - } - - /// Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Close a stream socket implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.close(impl, ec); - } - - /// (Deprecated: Use native_handle().) Get the native socket implementation. - native_type native(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Get the native socket implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Cancel all asynchronous operations associated with the socket. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.cancel(impl, ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.at_mark(impl, ec); - } - - /// Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.available(impl, ec); - } - - /// Bind the stream socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - return service_impl_.bind(impl, endpoint, ec); - } - - /// Connect the stream socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return service_impl_.connect(impl, peer_endpoint, ec); - } - - /// Start an asynchronous connect. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - detail::async_result_init< - ConnectHandler, void (boost::system::error_code)> init( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); - - service_impl_.async_connect(impl, peer_endpoint, init.handler); - - return init.result.get(); - } - - /// Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - return service_impl_.set_option(impl, option, ec); - } - - /// Get a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - return service_impl_.get_option(impl, option, ec); - } - - /// Perform an IO control command on the socket. - template - boost::system::error_code io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - return service_impl_.io_control(impl, command, ec); - } - - /// Gets the non-blocking mode of the socket. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.non_blocking(impl, mode, ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.native_non_blocking(impl, mode, ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.remote_endpoint(impl, ec); - } - - /// Disable sends or receives on the socket. - boost::system::error_code shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - return service_impl_.shutdown(impl, what, ec); - } - - /// Send the given data to the peer. - template - std::size_t send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send(impl, buffers, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - detail::async_result_init< - WriteHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - - service_impl_.async_send(impl, buffers, flags, init.handler); - - return init.result.get(); - } - - /// Receive some data from the peer. - template - std::size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive(impl, buffers, flags, ec); - } - - /// Start an asynchronous receive. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - detail::async_result_init< - ReadHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - - service_impl_.async_receive(impl, buffers, flags, init.handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - service_impl_.shutdown_service(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/logger/include/logger_impl.hpp b/implementation/logger/include/logger_impl.hpp index 34f006468..3ca6bebb9 100644 --- a/implementation/logger/include/logger_impl.hpp +++ b/implementation/logger/include/logger_impl.hpp @@ -8,6 +8,7 @@ #include #include +#include #ifdef USE_DLT #ifndef ANDROID @@ -31,24 +32,38 @@ class logger_impl { logger_impl() = default; ~logger_impl(); - std::shared_ptr get_configuration() const; - void set_configuration(const std::shared_ptr &_configuration); + void set_configuration(const std::shared_ptr& _configuration); + level_e get_loglevel() const; + bool has_console_log() const; + bool has_dlt_log() const; + bool has_file_log() const; + std::string get_logfile() const; + + const std::string& get_app_name() const; + std::unique_lock get_app_name_lock() const; #ifdef USE_DLT - void log(level_e _level, const char *_data); + void log(level_e _level, const char* _data); + void register_context(const std::string& _context_id); private: - void enable_dlt(const std::string &_application, const std::string &_context); + void enable_dlt(const std::string& _application, const std::string& _context); #endif private: static std::mutex mutex__; + static std::string app_name__; - std::shared_ptr configuration_; mutable std::mutex configuration_mutex_; + std::atomic cfg_level {level_e::LL_NONE}; + std::atomic_bool cfg_console_enabled {false}; + std::atomic_bool cfg_dlt_enabled {false}; + std::atomic_bool cfg_file_enabled {false}; + std::string cfg_file_name {""}; #ifdef USE_DLT #ifndef ANDROID + std::mutex dlt_context_mutex_; DLT_DECLARE_CONTEXT(dlt_) #endif #endif diff --git a/implementation/logger/src/logger_impl.cpp b/implementation/logger/src/logger_impl.cpp index b7cd57e31..d403500c1 100644 --- a/implementation/logger/src/logger_impl.cpp +++ b/implementation/logger/src/logger_impl.cpp @@ -14,13 +14,17 @@ namespace vsomeip_v3 { namespace logger { std::mutex logger_impl::mutex__; +std::string logger_impl::app_name__; void logger_impl::init(const std::shared_ptr &_configuration) { - std::lock_guard its_lock(mutex__); + std::scoped_lock its_lock {mutex__}; auto its_logger = logger_impl::get(); its_logger->set_configuration(_configuration); + const char *its_name = getenv(VSOMEIP_ENV_APPLICATION_NAME); + app_name__ = (nullptr != its_name) ? its_name : ""; + #ifdef USE_DLT # define VSOMEIP_LOG_DEFAULT_CONTEXT_ID "VSIP" # define VSOMEIP_LOG_DEFAULT_CONTEXT_NAME "vSomeIP context" @@ -29,8 +33,7 @@ logger_impl::init(const std::shared_ptr &_configuration) { 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); + its_logger->register_context(its_context_id); #endif #endif } @@ -43,19 +46,46 @@ logger_impl::~logger_impl() { #endif } -std::shared_ptr -logger_impl::get_configuration() const { +level_e logger_impl::get_loglevel() const { + return cfg_level; +} - std::lock_guard its_lock(configuration_mutex_); - return configuration_; +bool logger_impl::has_console_log() const { + return cfg_console_enabled; } -void -logger_impl::set_configuration( - const std::shared_ptr &_configuration) { +bool logger_impl::has_dlt_log() const { + return cfg_dlt_enabled; +} + +bool logger_impl::has_file_log() const { + return cfg_file_enabled; +} + +std::string logger_impl::get_logfile() const { + std::scoped_lock its_lock {configuration_mutex_}; + return cfg_file_name; +} - std::lock_guard its_lock(configuration_mutex_); - configuration_ = _configuration; +const std::string& logger_impl::get_app_name() const { + return app_name__; +} + +std::unique_lock logger_impl::get_app_name_lock() const { + std::unique_lock its_lock(mutex__); + return its_lock; +} + +void logger_impl::set_configuration(const std::shared_ptr& _configuration) { + + std::scoped_lock its_lock {configuration_mutex_}; + if (_configuration) { + cfg_level = _configuration->get_loglevel(); + cfg_console_enabled = _configuration->has_console_log(); + cfg_dlt_enabled = _configuration->has_dlt_log(); + cfg_file_enabled = _configuration->has_file_log(); + cfg_file_name = _configuration->get_logfile(); + } } #ifdef USE_DLT @@ -88,8 +118,14 @@ logger_impl::log(level_e _level, const char *_data) { its_level = DLT_LOG_DEFAULT; }; + std::scoped_lock its_lock {dlt_context_mutex_}; DLT_LOG_STRING(dlt_, its_level, _data); } + +void logger_impl::register_context(const std::string& _context_id) { + std::scoped_lock its_lock {dlt_context_mutex_}; + DLT_REGISTER_CONTEXT(dlt_, _context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME); +} #endif #endif @@ -99,7 +135,7 @@ static std::mutex the_logger_mutex__; std::shared_ptr logger_impl::get() { #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) - std::lock_guard its_lock(the_logger_mutex__); + std::scoped_lock its_lock {the_logger_mutex__}; #endif if (the_logger_ptr__ == nullptr) { the_logger_ptr__ = new std::shared_ptr(); @@ -120,7 +156,7 @@ static void logger_impl_teardown(void) // TODO: This mutex is causing a crash due to changes in the way mutexes are defined. // Since this function only runs on the main thread, no mutex should be needed. Leaving a // comment pending a refactor. - // std::lock_guard its_lock(the_logger_mutex__); + // std::scoped_lock its_lock(the_logger_mutex__); if (the_logger_ptr__ != nullptr) { the_logger_ptr__->reset(); delete the_logger_ptr__; diff --git a/implementation/logger/src/message.cpp b/implementation/logger/src/message.cpp index 1ed4aef3a..0ea45922f 100644 --- a/implementation/logger/src/message.cpp +++ b/implementation/logger/src/message.cpp @@ -78,18 +78,13 @@ message::message(level_e _level) } message::~message() try { - std::lock_guard its_lock(mutex__); + std::scoped_lock its_lock {mutex__}; auto its_logger = logger_impl::get(); - auto its_configuration = its_logger->get_configuration(); - if (!its_configuration) + if (level_ > its_logger->get_loglevel()) return; - if (level_ > its_configuration->get_loglevel()) - return; - - if (its_configuration->has_console_log() - || its_configuration->has_file_log()) { + if (its_logger->has_console_log() || its_logger->has_file_log()) { // Prepare log level const char *its_level; @@ -126,21 +121,20 @@ message::~message() try { #endif auto its_ms = (when_.time_since_epoch().count() / 100) % 1000000; - if (its_configuration->has_console_log()) { + if (its_logger->has_console_log()) { #ifndef ANDROID - std::cout - << std::dec - << std::setw(4) << its_time.tm_year + 1900 << "-" - << std::setfill('0') - << std::setw(2) << its_time.tm_mon + 1 << "-" - << std::setw(2) << its_time.tm_mday << " " - << std::setw(2) << its_time.tm_hour << ":" - << std::setw(2) << its_time.tm_min << ":" - << std::setw(2) << its_time.tm_sec << "." - << std::setw(6) << its_ms << " [" - << its_level << "] " - << buffer_.data_.str() - << std::endl; + { + std::unique_lock app_name_lock = its_logger->get_app_name_lock(); + std::cout << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" << std::dec + << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 << "-" + << 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_logger->get_app_name() + << " [" << its_level << "] " << buffer_.data_.str() << std::endl; + } #else std::string app = runtime::get_property("LogApplication"); @@ -169,28 +163,22 @@ message::~message() try { #endif // !ANDROID } - if (its_configuration->has_file_log()) { - std::ofstream its_logfile( - its_configuration->get_logfile(), - std::ios_base::app); + if (its_logger->has_file_log()) { + std::ofstream its_logfile(its_logger->get_logfile(), std::ios_base::app); if (its_logfile.is_open()) { - its_logfile - << std::dec - << std::setw(4) << its_time.tm_year + 1900 << "-" - << std::setfill('0') - << std::setw(2) << its_time.tm_mon + 1 << "-" - << std::setw(2) << its_time.tm_mday << " " - << std::setw(2) << its_time.tm_hour << ":" - << std::setw(2) << its_time.tm_min << ":" - << std::setw(2) << its_time.tm_sec << "." - << std::setw(6) << its_ms << " [" - << its_level << "] " - << buffer_.data_.str() - << std::endl; + its_logfile << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 + << "-" << 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; } } } - if (its_configuration->has_dlt_log()) { + if (its_logger->has_dlt_log()) { #ifdef USE_DLT #ifndef ANDROID its_logger->log(level_, buffer_.data_.str().c_str()); @@ -198,7 +186,8 @@ message::~message() try { #endif // USE_DLT } } catch (const std::exception& e) { - std::cout << "\nVSIP: Error destroying message class: " << e.what() << '\n'; + std::cerr << "\nVSIP: Error destroying message class: " << e.what() << '\n'; + return; } std::streambuf::int_type diff --git a/implementation/message/include/deserializer.hpp b/implementation/message/include/deserializer.hpp index 098698d04..3ebb8231d 100644 --- a/implementation/message/include/deserializer.hpp +++ b/implementation/message/include/deserializer.hpp @@ -11,6 +11,10 @@ #include #include +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { class message_impl; diff --git a/implementation/message/include/payload_impl.hpp b/implementation/message/include/payload_impl.hpp index d77eaa01d..e63dbc393 100644 --- a/implementation/message/include/payload_impl.hpp +++ b/implementation/message/include/payload_impl.hpp @@ -9,6 +9,10 @@ #include #include +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { class serializer; @@ -17,25 +21,25 @@ class deserializer; class payload_impl: public payload { public: VSOMEIP_EXPORT payload_impl(); - VSOMEIP_EXPORT payload_impl(const byte_t *_data, uint32_t _size); - VSOMEIP_EXPORT payload_impl(const std::vector< byte_t > &_data); + VSOMEIP_EXPORT payload_impl(const byte_t* _data, uint32_t _size); + VSOMEIP_EXPORT payload_impl(const std::vector& _data); VSOMEIP_EXPORT payload_impl(const payload_impl& _payload); - VSOMEIP_EXPORT virtual ~payload_impl(); + VSOMEIP_EXPORT virtual ~payload_impl() = default; - VSOMEIP_EXPORT bool operator == (const payload &_other); + VSOMEIP_EXPORT bool operator== (const payload& _other); - VSOMEIP_EXPORT byte_t * get_data(); - VSOMEIP_EXPORT const byte_t * get_data() const; + VSOMEIP_EXPORT byte_t* get_data(); + VSOMEIP_EXPORT const byte_t* get_data() const; VSOMEIP_EXPORT length_t get_length() const; VSOMEIP_EXPORT void set_capacity(length_t _capacity); - VSOMEIP_EXPORT void set_data(const byte_t *_data, length_t _length); - VSOMEIP_EXPORT void set_data(const std::vector< byte_t > &_data); - VSOMEIP_EXPORT void set_data(std::vector< byte_t > &&_data); + VSOMEIP_EXPORT void set_data(const byte_t* _data, length_t _length); + VSOMEIP_EXPORT void set_data(const std::vector& _data); + VSOMEIP_EXPORT void set_data(std::vector&& _data); - VSOMEIP_EXPORT bool serialize(serializer *_to) const; - VSOMEIP_EXPORT bool deserialize(deserializer *_from); + VSOMEIP_EXPORT bool serialize(serializer* _to) const; + VSOMEIP_EXPORT bool deserialize(deserializer* _from); private: std::vector data_; diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp index bfa723d34..746b83630 100644 --- a/implementation/message/src/deserializer.cpp +++ b/implementation/message/src/deserializer.cpp @@ -13,7 +13,7 @@ #include "../include/message_impl.hpp" #include "../include/deserializer.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { @@ -75,7 +75,8 @@ bool deserializer::deserialize(uint16_t& _value) { byte1 = *position_++; remaining_ -= 2; - _value = VSOMEIP_BYTES_TO_WORD(byte0, byte1); + uint8_t payload[2] = {byte0, byte1}; + _value = bithelper::read_uint16_be(payload); return true; } @@ -94,8 +95,8 @@ bool deserializer::deserialize(uint32_t &_value, bool _omit_last_byte) { byte3 = *position_++; remaining_ -= 3; - _value = VSOMEIP_BYTES_TO_LONG( - byte0, byte1, byte2, byte3); + uint8_t payload[4] = {byte0, byte1, byte2, byte3}; + _value = bithelper::read_uint32_be(payload); return true; } @@ -149,7 +150,7 @@ bool deserializer::look_ahead(std::size_t _index, uint16_t &_value) const { std::vector< uint8_t >::iterator i = position_ + static_cast::difference_type>(_index); - _value = VSOMEIP_BYTES_TO_WORD(*i, *(i+1)); + _value = bithelper::read_uint16_be(&(*i)); return true; } @@ -159,7 +160,7 @@ bool deserializer::look_ahead(std::size_t _index, uint32_t &_value) const { return false; std::vector< uint8_t >::const_iterator i = position_ + static_cast::difference_type>(_index); - _value = VSOMEIP_BYTES_TO_LONG(*i, *(i+1), *(i+2), *(i+3)); + _value = bithelper::read_uint32_be(&(*i)); return true; } diff --git a/implementation/message/src/message_base_impl.cpp b/implementation/message/src/message_base_impl.cpp index c1d7da7dd..c64a56f92 100644 --- a/implementation/message/src/message_base_impl.cpp +++ b/implementation/message/src/message_base_impl.cpp @@ -4,7 +4,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "../include/message_impl.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { @@ -19,12 +19,16 @@ message_base_impl::~message_base_impl() { // header interface message_t message_base_impl::get_message() const { - return VSOMEIP_WORDS_TO_LONG(header_.service_, header_.method_); + const uint8_t header_message[] = {static_cast((header_.service_ & 0xFF00) >> 8), + static_cast( header_.service_ & 0x00FF), + static_cast((header_.method_ & 0xFF00) >> 8), + static_cast( header_.method_ & 0x00FF)}; + return bithelper::read_uint32_be(header_message); } void message_base_impl::set_message(message_t _message) { - header_.service_ = VSOMEIP_LONG_WORD0(_message); - header_.method_ = VSOMEIP_LONG_WORD1(_message); + header_.service_ = bithelper::read_high_word(_message); + header_.method_ = bithelper::read_low_word(_message); } service_t message_base_impl::get_service() const { @@ -52,7 +56,11 @@ void message_base_impl::set_method(method_t _method) { } request_t message_base_impl::get_request() const { - return VSOMEIP_WORDS_TO_LONG(header_.client_, header_.session_); + const uint8_t header_message[] = {static_cast((header_.client_ & 0xFF00) >> 8), + static_cast( header_.client_ & 0x00FF), + static_cast((header_.session_ & 0xFF00) >> 8), + static_cast( header_.session_ & 0x00FF)}; + return bithelper::read_uint32_be(header_message); } client_t message_base_impl::get_client() const { diff --git a/implementation/message/src/message_impl.cpp b/implementation/message/src/message_impl.cpp index 47250c137..09db29722 100644 --- a/implementation/message/src/message_impl.cpp +++ b/implementation/message/src/message_impl.cpp @@ -13,7 +13,6 @@ #else #include "../../configuration/include/internal.hpp" #endif -#include "../../utility/include/byteorder.hpp" namespace vsomeip_v3 { diff --git a/implementation/message/src/payload_impl.cpp b/implementation/message/src/payload_impl.cpp index 7617cdc1a..617fe67c2 100644 --- a/implementation/message/src/payload_impl.cpp +++ b/implementation/message/src/payload_impl.cpp @@ -3,6 +3,8 @@ // 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/deserializer.hpp" #include "../include/payload_impl.hpp" #include "../include/serializer.hpp" @@ -13,11 +15,11 @@ payload_impl::payload_impl() : data_() { } -payload_impl::payload_impl(const byte_t *_data, uint32_t _size) { +payload_impl::payload_impl(const byte_t* _data, uint32_t _size) { data_.assign(_data, _data + _size); } -payload_impl::payload_impl(const std::vector &_data) +payload_impl::payload_impl(const std::vector& _data) : data_(_data) { } @@ -25,26 +27,19 @@ payload_impl::payload_impl(const payload_impl& _payload) : data_(_payload.data_) { } -payload_impl::~payload_impl() { -} - -bool payload_impl::operator==(const payload &_other) { - bool is_equal(true); - try { - const payload_impl &other = dynamic_cast< const payload_impl & >(_other); - is_equal = (data_ == other.data_); - } - catch (...) { - is_equal = false; +bool payload_impl::operator==(const payload& _other) { + bool is_equal {get_length() == _other.get_length()}; + if (is_equal) { + is_equal = (0 == std::memcmp(get_data(), _other.get_data(), get_length())); } return is_equal; } -byte_t * payload_impl::get_data() { +byte_t* payload_impl::get_data() { return data_.data(); } -const byte_t * payload_impl::get_data() const { +const byte_t* payload_impl::get_data() const { return data_.data(); } @@ -56,23 +51,23 @@ void payload_impl::set_capacity(length_t _capacity) { data_.reserve(_capacity); } -void payload_impl::set_data(const byte_t *_data, const length_t _length) { +void payload_impl::set_data(const byte_t* _data, const length_t _length) { data_.assign(_data, _data + _length); } -void payload_impl::set_data(const std::vector< byte_t > &_data) { +void payload_impl::set_data(const std::vector& _data) { data_ = _data; } -void payload_impl::set_data(std::vector< byte_t > &&_data) { +void payload_impl::set_data(std::vector&& _data) { data_ = std::move(_data); } -bool payload_impl::serialize(serializer *_to) const { +bool payload_impl::serialize(serializer* _to) const { return (0 != _to && _to->serialize(data_)); } -bool payload_impl::deserialize(deserializer *_from) { +bool payload_impl::deserialize(deserializer* _from) { return (0 != _from && _from->deserialize(data_)); } diff --git a/implementation/message/src/serializer.cpp b/implementation/message/src/serializer.cpp index 2bdad8ff8..9f6f03427 100644 --- a/implementation/message/src/serializer.cpp +++ b/implementation/message/src/serializer.cpp @@ -13,7 +13,7 @@ #include #include "../include/serializer.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include namespace vsomeip_v3 { @@ -37,18 +37,23 @@ bool serializer::serialize(const uint8_t _value) { } bool serializer::serialize(const uint16_t _value) { - data_.push_back(VSOMEIP_WORD_BYTE1(_value)); - data_.push_back(VSOMEIP_WORD_BYTE0(_value)); + uint8_t nvalue[2] = {0}; + bithelper::write_uint16_le(_value, nvalue); + data_.push_back(nvalue[1]); + data_.push_back(nvalue[0]); return true; } bool serializer::serialize(const uint32_t _value, bool _omit_last_byte) { + uint8_t nvalue[4] = {0}; + bithelper::write_uint32_le(_value, nvalue); + if (!_omit_last_byte) { - data_.push_back(VSOMEIP_LONG_BYTE3(_value)); + data_.push_back(nvalue[3]); } - data_.push_back(VSOMEIP_LONG_BYTE2(_value)); - data_.push_back(VSOMEIP_LONG_BYTE1(_value)); - data_.push_back(VSOMEIP_LONG_BYTE0(_value)); + data_.push_back(nvalue[2]); + data_.push_back(nvalue[1]); + data_.push_back(nvalue[0]); return true; } diff --git a/implementation/plugin/include/plugin_manager_impl.hpp b/implementation/plugin/include/plugin_manager_impl.hpp index e88772e60..9f755d60c 100644 --- a/implementation/plugin/include/plugin_manager_impl.hpp +++ b/implementation/plugin/include/plugin_manager_impl.hpp @@ -6,7 +6,7 @@ #ifndef VSOMEIP_V3_PLUGIN_MANAGER_IMPL_HPP #define VSOMEIP_V3_PLUGIN_MANAGER_IMPL_HPP -#include "../include/plugin_manager.hpp" +#include #include #include diff --git a/implementation/protocol/include/command.hpp b/implementation/protocol/include/command.hpp index d09eef29a..ccb8bdf28 100644 --- a/implementation/protocol/include/command.hpp +++ b/implementation/protocol/include/command.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2021-2024 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/. diff --git a/implementation/protocol/include/config_command.hpp b/implementation/protocol/include/config_command.hpp new file mode 100644 index 000000000..c547f0abf --- /dev/null +++ b/implementation/protocol/include/config_command.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2024 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_PROTOCOL_CONFIG_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_CONFIG_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3::protocol { + +/** + * A command for sharing configurations between peers. + * + * It contains a list of arbitrary key-value pairs that represent additional + * information that is relevant to the peer, but is not covered by the other + * commands in the protocol. + * + * See the vsomeip protocol documentation for more information on how this command + * is structured. + */ +class config_command final : public command { +public: + /** Creates a new `config_command`. */ + config_command() : command(id_e::CONFIG_ID) { } + + /** + * Serializes the `config_command` into the given buffer. + * + * Serialized data will be represented in Little-Endian byte order. + */ + void serialize(std::vector& _buffer, error_e& _error) const override; + + /** + * Deserializes the `config_command` from the given buffer. + * + * Serialized data is expected to be in Little-Endian byte order. + */ + void deserialize(const std::vector& _buffer, error_e& _error) override; + + /** Inserts a configuration with the given value at the given key. */ + void insert(const std::string& _key, const std::string&& _value); + + /** Whether the map contains the given configuration. */ + bool contains(const std::string& _key) const; + + /** + * Returns the value of the given configuration. + * + * Panics if the key does not exist. + */ + const std::string& at(const std::string& _key) const; + + /** Returns a map of configurations and their associated values. */ + const std::map>& configs() const; + +private: + /** A map of configurations and their associated values. */ + std::map> configs_; +}; + +} // namespace vsomeip_v3::protocol + +#endif // VSOMEIP_V3_PROTOCOL_CONFIG_COMMAND_HPP_ diff --git a/implementation/protocol/include/expire_command.hpp b/implementation/protocol/include/expire_command.hpp index 4c47aa98a..3f9fdfa40 100644 --- a/implementation/protocol/include/expire_command.hpp +++ b/implementation/protocol/include/expire_command.hpp @@ -12,6 +12,10 @@ #include "subscribe_command_base.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { namespace protocol { diff --git a/implementation/protocol/include/protocol.hpp b/implementation/protocol/include/protocol.hpp index 58a38924b..c33195904 100644 --- a/implementation/protocol/include/protocol.hpp +++ b/implementation/protocol/include/protocol.hpp @@ -53,6 +53,7 @@ enum class id_e : uint8_t { UPDATE_SECURITY_POLICY_INT_ID = 0x29, EXPIRE_ID = 0x2A, SUSPEND_ID = 0x30, + CONFIG_ID = 0x31, UNKNOWN_ID = 0xFF }; diff --git a/implementation/protocol/include/security_policy_response_command_base.hpp b/implementation/protocol/include/security_policy_response_command_base.hpp index 799f70391..2bb4ba6d0 100644 --- a/implementation/protocol/include/security_policy_response_command_base.hpp +++ b/implementation/protocol/include/security_policy_response_command_base.hpp @@ -10,6 +10,10 @@ #include "command.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { struct policy; diff --git a/implementation/protocol/include/unregister_event_command.hpp b/implementation/protocol/include/unregister_event_command.hpp index 9779946e2..287eac799 100644 --- a/implementation/protocol/include/unregister_event_command.hpp +++ b/implementation/protocol/include/unregister_event_command.hpp @@ -12,6 +12,10 @@ #include "command.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { namespace protocol { diff --git a/implementation/protocol/src/config_command.cpp b/implementation/protocol/src/config_command.cpp new file mode 100644 index 000000000..619aede98 --- /dev/null +++ b/implementation/protocol/src/config_command.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2024 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/config_command.hpp" + +#include +#include + +namespace vsomeip_v3::protocol { + +void config_command::serialize(std::vector& _buffer, error_e& _error) const { + size_t size = COMMAND_HEADER_SIZE; + for (const auto& [key, value] : configs_) { + size += sizeof(std::uint32_t) * 2; + size += key.size(); + size += value.size(); + } + if (size > std::numeric_limits::max()) { + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + _buffer.resize(size); + size_ = static_cast(size - COMMAND_HEADER_SIZE); + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) { + return; + } + + size_t write_position(COMMAND_POSITION_PAYLOAD); + for (const auto& [key, value] : configs_) { + auto key_size = static_cast(key.size()); + std::memcpy(&_buffer[write_position], &key_size, sizeof(std::uint32_t)); + write_position += sizeof(std::uint32_t); + + std::memcpy(&_buffer[write_position], key.data(), key.length()); + write_position += key_size; + + auto value_size = static_cast(value.size()); + std::memcpy(&_buffer[write_position], &value_size, sizeof(std::uint32_t)); + write_position += sizeof(std::uint32_t); + + std::memcpy(&_buffer[write_position], value.data(), value.length()); + write_position += value_size; + } + _error = error_e::ERROR_OK; +} + +void config_command::deserialize(const std::vector& _buffer, error_e& _error) { + if (_buffer.size() < COMMAND_HEADER_SIZE) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) { + return; + } + if (get_version() != 0) { + _error = error_e::ERROR_UNKNOWN; + return; + } + std::size_t remaining = size_; + if (_buffer.size() < remaining) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + size_t read_position(COMMAND_POSITION_PAYLOAD); + std::function read = [&_buffer, &read_position, &remaining](bool& failed) { + if (remaining < sizeof(std::uint32_t)) { + failed = true; + return std::string(""); + } + size_t size = 0; + std::memcpy(&size, &_buffer[read_position], sizeof(std::uint32_t)); + remaining -= sizeof(std::uint32_t); + read_position += sizeof(std::uint32_t); + if (remaining < size) { + failed = true; + return std::string(""); + } + std::string value; + value.assign(&_buffer[read_position], &_buffer[read_position + size]); + remaining -= size; + read_position += size; + return value; + }; + while (remaining > 0) { + bool failed = false; + std::string key = read(failed); + if (failed) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + std::string value = read(failed); + if (failed) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + configs_[key] = value; + } + _error = error_e::ERROR_OK; +} + +void config_command::insert(const std::string& _key, const std::string&& _value) { + configs_.insert_or_assign(_key, std::move(_value)); +} + +bool config_command::contains(const std::string& _key) const { + return configs_.find(_key) != configs_.end(); +} + +const std::string& config_command::at(const std::string& _key) const { + return configs_.at(_key); +} + +const std::map>& config_command::configs() const { + return configs_; +} + +} // namespace vsomeip_v3::protocol diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp index fd43638d2..447aff84a 100644 --- a/implementation/routing/include/event.hpp +++ b/implementation/routing/include/event.hpp @@ -179,6 +179,7 @@ class event std::atomic is_cache_placeholder_; epsilon_change_func_t epsilon_change_func_; + bool has_default_epsilon_change_func_; std::atomic reliability_; diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp index 1a5a1b976..2dc8279fc 100644 --- a/implementation/routing/include/eventgroupinfo.hpp +++ b/implementation/routing/include/eventgroupinfo.hpp @@ -22,6 +22,10 @@ #include "remote_subscription.hpp" #include "types.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { class endpoint_definition; diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp index f5bf2a210..a770a56f7 100644 --- a/implementation/routing/include/remote_subscription.hpp +++ b/implementation/routing/include/remote_subscription.hpp @@ -17,6 +17,9 @@ #include "types.hpp" #include +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif namespace vsomeip_v3 { @@ -92,6 +95,11 @@ class remote_subscription { VSOMEIP_EXPORT bool get_ip_address(boost::asio::ip::address &_address) const; + bool is_expired() const; + void set_expired(); + bool is_forwarded() const; + void set_forwarded(); + private: std::atomic id_; std::atomic is_initial_; @@ -121,9 +129,23 @@ class remote_subscription { // for the subscriptions. This is usally 1, but // may be larger if a matching subscription arrived // before the subscription could be acknowledged - std::uint32_t answers_; + std::atomic answers_; mutable std::mutex mutex_; + + /* + * This flag specifies what the "winner" of the + * expire_subscriptions()/on_remote_subscribe() + * race shall have as destination: + * - expiration, if expire_subscriptions() runs first + * - forwarding, if on_remote_subscribe() runs first + */ + enum struct destiny : std::uint8_t { + none, + expire, + forward + }; + std::atomic final_destination_; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_host.hpp b/implementation/routing/include/routing_host.hpp index 1decea3b6..2203bed8b 100644 --- a/implementation/routing/include/routing_host.hpp +++ b/implementation/routing/include/routing_host.hpp @@ -42,6 +42,8 @@ class routing_host { virtual void remove_subscriptions(port_t _local_port, const boost::asio::ip::address &_remote_address, port_t _remote_port) = 0; + + virtual routing_state_e get_routing_state() = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp index 3c19a9fea..58f38ca4b 100644 --- a/implementation/routing/include/routing_manager.hpp +++ b/implementation/routing/include/routing_manager.hpp @@ -10,13 +10,7 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif - +#include #include #include #include diff --git a/implementation/routing/include/routing_manager_base.hpp b/implementation/routing/include/routing_manager_base.hpp index a7ba02438..51262e5ff 100644 --- a/implementation/routing/include/routing_manager_base.hpp +++ b/implementation/routing/include/routing_manager_base.hpp @@ -28,6 +28,10 @@ #include "../../configuration/include/configuration.hpp" #include "../../endpoints/include/endpoint_manager_base.hpp" +#if defined(__QNX__) +#include "../../utility/include/qnx_helper.hpp" +#endif + namespace vsomeip_v3 { #ifdef USE_DLT @@ -211,6 +215,8 @@ class routing_manager_base : public routing_manager, const std::shared_ptr &_filter, client_t _client, std::set *_already_subscribed_events); + void clear_shadow_subscriptions(void); + std::shared_ptr get_serializer(); void put_serializer(const std::shared_ptr &_serializer); std::shared_ptr get_deserializer(); @@ -308,10 +314,6 @@ class routing_manager_base : public routing_manager, std::mutex event_registration_mutex_; -#ifdef USE_DLT - std::shared_ptr tc_; -#endif - struct subscription_data_t { service_t service_; instance_t instance_; @@ -350,6 +352,10 @@ class routing_manager_base : public routing_manager, std::mutex routing_state_mutex_; routing_state_e routing_state_; +#ifdef USE_DLT + std::shared_ptr tc_; +#endif + private: services_t services_; mutable std::mutex services_mutex_; diff --git a/implementation/routing/include/routing_manager_client.hpp b/implementation/routing/include/routing_manager_client.hpp index b923ad961..4d6bbd1f8 100644 --- a/implementation/routing/include/routing_manager_client.hpp +++ b/implementation/routing/include/routing_manager_client.hpp @@ -233,9 +233,9 @@ class routing_manager_client ST_ASSIGNED = 0x4 }; - std::atomic is_connected_; - std::atomic is_started_; - inner_state_type_e state_; + std::atomic_bool is_connected_; + std::atomic_bool is_started_; + std::atomic state_; std::shared_ptr sender_; // --> stub std::shared_ptr receiver_; // --> from everybody diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp index 27925bb4b..ec9788b2d 100644 --- a/implementation/routing/include/routing_manager_host.hpp +++ b/implementation/routing/include/routing_manager_host.hpp @@ -8,13 +8,7 @@ #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif - +#include #include #include diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 987f9d3d2..0a216ea09 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -251,6 +251,7 @@ class routing_manager_impl: public routing_manager_base, void handle_client_error(client_t _client); std::shared_ptr get_endpoint_manager() const; + routing_state_e get_routing_state(); void set_routing_state(routing_state_e _routing_state); void send_get_offered_services_info(client_t _client, offer_type_e _offer_type) { @@ -293,11 +294,11 @@ class routing_manager_impl: public routing_manager_base, service_t _service, instance_t _instance, eventgroup_t _eventgroup); #ifndef VSOMEIP_DISABLE_SECURITY - bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, + bool update_security_policy_configuration(uid_t _uid, gid_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, const security_update_handler_t &_handler); - bool remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, + bool remove_security_policy_configuration(uid_t _uid, gid_t _gid, const security_update_handler_t &_handler); #endif @@ -442,8 +443,6 @@ class routing_manager_impl: public routing_manager_base, client_t _client, major_version_t _major, minor_version_t _minor); bool erase_offer_command(service_t _service, instance_t _instance); - bool is_last_stop_callback(const uint32_t _callback_id); - std::string get_env(client_t _client) const; std::string get_env_unlocked(client_t _client) const; @@ -465,6 +464,11 @@ class routing_manager_impl: public routing_manager_base, service_t _service, instance_t _instance, const boost::asio::ip::address &_remote_address) const; +#ifdef VSOMEIP_ENABLE_DEFAULT_EVENT_CACHING + bool has_subscribed_eventgroup( + service_t _service, instance_t _instance) const; +#endif // VSOMEIP_ENABLE_DEFAULT_EVENT_CACHING + private: std::shared_ptr stub_; std::shared_ptr discovery_; diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp index d30915af4..23bedc320 100644 --- a/implementation/routing/include/routing_manager_stub.hpp +++ b/implementation/routing/include/routing_manager_stub.hpp @@ -16,12 +16,7 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif +#include #include #include @@ -110,24 +105,24 @@ class routing_manager_stub: public routing_host, pending_remote_offer_id_t _id); #ifndef VSOMEIP_DISABLE_SECURITY - bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, + bool update_security_policy_configuration(uid_t _uid, gid_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, const security_update_handler_t &_handler); - bool remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, + bool remove_security_policy_configuration(uid_t _uid, gid_t _gid, const security_update_handler_t &_handler); void on_security_update_response(pending_security_update_id_t _id, client_t _client); - void policy_cache_add(uint32_t _uid, const std::shared_ptr& _payload); - void policy_cache_remove(uint32_t _uid); - bool is_policy_cached(uint32_t _uid); + void policy_cache_add(uid_t _uid, const std::shared_ptr& _payload); + void policy_cache_remove(uid_t _uid); + bool is_policy_cached(uid_t _uid); bool send_update_security_policy_request(client_t _client, - pending_security_update_id_t _update_id, uint32_t _uid, + pending_security_update_id_t _update_id, uid_t _uid, const std::shared_ptr& _payload); bool send_remove_security_policy_request(client_t _client, - pending_security_update_id_t _update_id, uint32_t _uid, uint32_t _gid); + pending_security_update_id_t _update_id, uid_t _uid, gid_t _gid); bool send_cached_security_policies(client_t _client); @@ -144,6 +139,8 @@ class routing_manager_stub: public routing_host, const boost::asio::ip::address &_remote_address, port_t _remote_port); + routing_state_e get_routing_state(); + private: void broadcast(const std::vector &_command) const; @@ -200,7 +197,7 @@ class routing_manager_stub: public routing_host, protocol::routing_info_entry &_entry); void send_client_routing_info(const client_t _target, std::vector &&_entries); - void send_client_credentials(client_t _target, std::set> &_credentials); + void send_client_credentials(client_t _target, std::set> &_credentials); void on_client_id_timer_expired(boost::system::error_code const &_error); diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp index d9863039d..2b1c9079c 100644 --- a/implementation/routing/include/routing_manager_stub_host.hpp +++ b/implementation/routing/include/routing_manager_stub_host.hpp @@ -6,16 +6,9 @@ #ifndef VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_ #define VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_ -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif - +#include #include #include - #include "types.hpp" namespace vsomeip_v3 { @@ -132,6 +125,8 @@ class routing_manager_stub_host { virtual void remove_guest(client_t _client) = 0; virtual void clear_local_services() = 0; + + virtual routing_state_e get_routing_state() = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp index 85c2f87a0..c7e87ca5a 100644 --- a/implementation/routing/include/serviceinfo.hpp +++ b/implementation/routing/include/serviceinfo.hpp @@ -53,6 +53,12 @@ class serviceinfo { VSOMEIP_EXPORT bool is_in_mainphase() const; VSOMEIP_EXPORT void set_is_in_mainphase(bool _in_mainphase); + VSOMEIP_EXPORT bool is_accepting_remote_subscriptions() const; + VSOMEIP_EXPORT void set_accepting_remote_subscriptions(bool _accepting_remote_subscriptions); + + VSOMEIP_EXPORT void add_remote_ip(std::string _remote_ip); + VSOMEIP_EXPORT std::set> get_remote_ip_accepting_sub(); + private: service_t service_; instance_t instance_; @@ -72,6 +78,14 @@ class serviceinfo { std::atomic_bool is_local_; std::atomic_bool is_in_mainphase_; + + // Added flag, to ensure the lib only process subscriptions request + // when at least one offer is sent from SD, otherwise will be sent a NACK + // this is needed to avoid desynchronizations triggered by high CPU load + std::atomic_bool accepting_remote_subscription_; // offers sent to multicast + std::set> + accepting_remote_subscription_from_; // offers sent by unicast + std::mutex accepting_remote_mutex; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp index 8f5b44ce4..688baf5eb 100644 --- a/implementation/routing/src/event.cpp +++ b/implementation/routing/src/event.cpp @@ -37,6 +37,7 @@ event::event(routing_manager *_routing, bool _is_shadow) is_cache_placeholder_(false), epsilon_change_func_(std::bind(&event::has_changed, this, std::placeholders::_1, std::placeholders::_2)), + has_default_epsilon_change_func_(true), reliability_(reliability_type_e::RT_UNKNOWN) { } @@ -297,6 +298,7 @@ event::set_epsilon_change_function( std::lock_guard its_lock(mutex_); if (_epsilon_change_func) { epsilon_change_func_ = _epsilon_change_func; + has_default_epsilon_change_func_ = false; } } @@ -448,22 +450,12 @@ bool event::prepare_update_payload_unlocked( const std::shared_ptr &_payload, bool _force) { - // Copy payload to avoid manipulation from the outside - std::shared_ptr its_payload - = runtime::get()->create_payload( - _payload->get_data(), _payload->get_length()); - - bool is_change = has_changed(current_->get_payload(), its_payload); - - if (!_force - && type_ == event_type_e::ET_FIELD - && cycle_ == std::chrono::milliseconds::zero() - && !is_change - && !is_shadow_) { + if (!_force && type_ == event_type_e::ET_FIELD && cycle_ == std::chrono::milliseconds::zero() + && !has_changed(current_->get_payload(), _payload) && !is_shadow_) { return false; } - update_->set_payload(its_payload); + update_->set_payload(_payload); if (!is_set_) { start_cycle(); @@ -548,76 +540,79 @@ event::add_subscriber(eventgroup_t _eventgroup, its_filter_parameters << "])"; VSOMEIP_INFO << "Filter parameters: " << its_filter_parameters.str(); - - filters_[_client] = [_filter]( - const std::shared_ptr &_old, - const std::shared_ptr &_new) { - - bool is_changed(false), is_elapsed(false); - - // Check whether we should forward because of changed data - if (_filter->on_change_) { - length_t its_min_length, its_max_length; - - if (_old->get_length() < _new->get_length()) { - its_min_length = _old->get_length(); - its_max_length = _new->get_length(); - } else { - its_min_length = _new->get_length(); - its_max_length = _old->get_length(); - } - - // Check whether all additional bytes (if any) are excluded - for (length_t i = its_min_length; i < its_max_length; i++) { - auto j = _filter->ignore_.find(i); - // A change is detected when an additional byte is not - // excluded at all or if its exclusion does not cover all - // bits - if (j == _filter->ignore_.end() || j->second != 0xFF) { - is_changed = true; - break; + { + std::scoped_lock lk {filters_mutex_}; + filters_[_client] = [_filter]( + const std::shared_ptr &_old, + const std::shared_ptr &_new) { + + bool is_changed(false), is_elapsed(false); + + // Check whether we should forward because of changed data + if (_filter->on_change_) { + length_t its_min_length, its_max_length; + + if (_old->get_length() < _new->get_length()) { + its_min_length = _old->get_length(); + its_max_length = _new->get_length(); + } else { + its_min_length = _new->get_length(); + its_max_length = _old->get_length(); } - } - if (!is_changed) { - const byte_t *its_old = _old->get_data(); - const byte_t *its_new = _new->get_data(); - for (length_t i = 0; i < its_min_length; i++) { + // Check whether all additional bytes (if any) are excluded + for (length_t i = its_min_length; i < its_max_length; i++) { auto j = _filter->ignore_.find(i); - if (j == _filter->ignore_.end()) { - if (its_old[i] != its_new[i]) { - is_changed = true; - break; - } - } else if (j->second != 0xFF) { - if ((its_old[i] & ~(j->second)) != (its_new[i] & ~(j->second))) { - is_changed = true; - break; + // A change is detected when an additional byte is not + // excluded at all or if its exclusion does not cover all + // bits + if (j == _filter->ignore_.end() || j->second != 0xFF) { + is_changed = true; + break; + } + } + + if (!is_changed) { + const byte_t *its_old = _old->get_data(); + const byte_t *its_new = _new->get_data(); + for (length_t i = 0; i < its_min_length; i++) { + auto j = _filter->ignore_.find(i); + if (j == _filter->ignore_.end()) { + if (its_old[i] != its_new[i]) { + is_changed = true; + break; + } + } else if (j->second != 0xFF) { + if ((its_old[i] & ~(j->second)) != (its_new[i] & ~(j->second))) { + is_changed = true; + break; + } } } } } - } - - if (_filter->interval_ > -1) { - // Check whether we should forward because of the elapsed time since - // we did last time - std::chrono::steady_clock::time_point its_current - = std::chrono::steady_clock::now(); - int64_t elapsed = std::chrono::duration_cast( - its_current - _filter->last_forwarded_).count(); - is_elapsed = (_filter->last_forwarded_ == std::chrono::steady_clock::time_point::max() - || elapsed >= _filter->interval_); - if (is_elapsed || (is_changed && _filter->on_change_resets_interval_)) - _filter->last_forwarded_ = its_current; } - - return (is_changed || is_elapsed); - }; + if (_filter->interval_ > -1) { + // Check whether we should forward because of the elapsed time since + // we did last time + std::chrono::steady_clock::time_point its_current + = std::chrono::steady_clock::now(); + + int64_t elapsed = std::chrono::duration_cast( + its_current - _filter->last_forwarded_).count(); + is_elapsed = (_filter->last_forwarded_ == std::chrono::steady_clock::time_point::max() + || elapsed >= _filter->interval_); + if (is_elapsed || (is_changed && _filter->on_change_resets_interval_)) + _filter->last_forwarded_ = its_current; } + + return (is_changed || is_elapsed); + }; + } // Create a new callback for this client if filter interval is used routing_->register_debounce(_filter, _client, shared_from_this()); } else { + std::scoped_lock lk {filters_mutex_}; filters_.erase(_client); } @@ -683,9 +678,16 @@ event::get_filtered_subscribers(bool _force) { its_payload_update = update_->get_payload(); } - if (filters_.empty()) { + bool is_filters_empty = false; + { + std::scoped_lock its_lock {filters_mutex_}; + is_filters_empty = filters_.empty(); + } + + if (is_filters_empty) { - bool must_forward = (type_ != event_type_e::ET_FIELD + bool must_forward = ((type_ != event_type_e::ET_FIELD + && has_default_epsilon_change_func_) || _force || epsilon_change_func_(its_payload, its_payload_update)); @@ -695,7 +697,7 @@ event::get_filtered_subscribers(bool _force) { } else { byte_t is_allowed(0xff); - std::lock_guard its_lock(filters_mutex_); + std::scoped_lock its_lock {filters_mutex_}; for (const auto s : its_subscribers) { auto its_specific = filters_.find(s); @@ -704,7 +706,8 @@ event::get_filtered_subscribers(bool _force) { its_filtered_subscribers.insert(s); } else { if (is_allowed == 0xff) { - is_allowed = (type_ != event_type_e::ET_FIELD + is_allowed = ((type_ != event_type_e::ET_FIELD + && has_default_epsilon_change_func_) || _force || epsilon_change_func_(its_payload, its_payload_update) ? 0x01 : 0x00); @@ -817,17 +820,19 @@ bool event::has_changed(const std::shared_ptr &_lhs, const std::shared_ptr &_rhs) const { - bool is_change = (_lhs->get_length() != _rhs->get_length()); - if (!is_change) { - std::size_t its_pos = 0; - const byte_t *its_old_data = _lhs->get_data(); - const byte_t *its_new_data = _rhs->get_data(); - while (!is_change && its_pos < _lhs->get_length()) { - is_change = (*its_old_data++ != *its_new_data++); - its_pos++; + if (_lhs) { + if (_rhs) { + return !((*_lhs) == (*_rhs)); + } else { + return false; + } + } else { + if (_rhs) { + return false; } } - return is_change; + + return true; // both are nullptr } std::set diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp index 3c9510849..7f5a1044d 100644 --- a/implementation/routing/src/remote_subscription.cpp +++ b/implementation/routing/src/remote_subscription.cpp @@ -16,7 +16,8 @@ remote_subscription::remote_subscription() ttl_(DEFAULT_TTL), reserved_(0), counter_(0), - answers_(1) { + answers_(1), + final_destination_{destiny::none} { } remote_subscription::~remote_subscription() { @@ -340,4 +341,20 @@ remote_subscription::get_ip_address(boost::asio::ip::address &_address) const { return false; } +bool remote_subscription::is_expired() const { + return this->final_destination_.load(std::memory_order_acquire) == destiny::expire; +} + +void remote_subscription::set_expired() { + this->final_destination_.store(destiny::expire, std::memory_order_release); +} + +bool remote_subscription::is_forwarded() const { + return this->final_destination_.load(std::memory_order_acquire) == destiny::forward; +} + +void remote_subscription::set_forwarded() { + this->final_destination_.store(destiny::forward, std::memory_order_release); +} + } // namespace vsomeip_v3 diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp index 047e6566e..a9438ef4b 100644 --- a/implementation/routing/src/routing_manager_base.cpp +++ b/implementation/routing/src/routing_manager_base.cpp @@ -16,7 +16,7 @@ #ifdef USE_DLT #include "../../tracing/include/connector_impl.hpp" #endif -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" namespace vsomeip_v3 { @@ -25,7 +25,8 @@ routing_manager_base::routing_manager_base(routing_manager_host *_host) : host_(_host), io_(host_->get_io()), configuration_(host_->get_configuration()), - debounce_timer(host_->get_io()) + debounce_timer(host_->get_io()), + routing_state_(routing_state_e::RS_UNKNOWN) #ifdef USE_DLT , tc_(trace::connector_impl::get()) #endif @@ -50,52 +51,91 @@ routing_manager_base::routing_manager_base(routing_manager_host *_host) : } } -void routing_manager_base::debounce_timeout_update_cbk(const boost::system::error_code &_error, const std::shared_ptr &_event, client_t _client, const std::shared_ptr &_filter) { +void routing_manager_base::debounce_timeout_update_cbk( + const boost::system::error_code& _error, const std::shared_ptr& _event, + client_t _client, const std::shared_ptr& _filter) { if (!_error) { - std::lock_guard its_lock(debounce_mutex_); - if (_event && (_event->get_subscribers().find(_client) != _event->get_subscribers().end()) && _filter) { - bool is_elapsed{false}; - auto its_current = std::chrono::steady_clock::now(); - - int64_t elapsed = std::chrono::duration_cast( - its_current - _filter->last_forwarded_).count(); - is_elapsed = (_filter->last_forwarded_ == std::chrono::steady_clock::time_point::max() - || elapsed >= _filter->interval_); - - auto debounce_client = debounce_clients_.begin(); - auto event_id = std::get<3>(debounce_client->second); - bool has_update = std::get<1>(debounce_client->second); - if (is_elapsed) { - if (std::get<0>(debounce_client->second) == _client && has_update) { - _event->notify_one(_client, false); - has_update = false; - } - elapsed = 0; + if (!_event) { + std::lock_guard its_lock(debounce_mutex_); + if (debounce_clients_.size() > 0) { + debounce_timer.expires_from_now( + std::chrono::duration_cast( + debounce_clients_.begin()->first + - std::chrono::steady_clock::now())); + debounce_timer.async_wait(std::get<2>(debounce_clients_.begin()->second)); } + return; + } - debounce_clients_.erase(debounce_client); + // _event->get_subscribers() cannot be locked by debounce_mutex_, because it can lead to + // Lock inversion with remove_subscribes and its eventgroup_mutex! + auto its_subscribers = _event->get_subscribers(); - auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(_filter->interval_ - elapsed); - debounce_clients_.emplace(timeout, std::make_tuple(_client, has_update, std::bind(&routing_manager_base::debounce_timeout_update_cbk, shared_from_this(), - std::placeholders::_1, _event, _client, _filter), event_id)); - } + bool notify_client {false}; + { + std::lock_guard its_lock(debounce_mutex_); + if (its_subscribers.find(_client) != its_subscribers.end() && _filter) { + bool is_elapsed {false}; + auto its_current = std::chrono::steady_clock::now(); + + int64_t elapsed = std::chrono::duration_cast( + its_current - _filter->last_forwarded_) + .count(); + is_elapsed = + (_filter->last_forwarded_ == std::chrono::steady_clock::time_point::max() + || elapsed >= _filter->interval_); + + auto debounce_client = debounce_clients_.begin(); + auto event_id = std::get<3>(debounce_client->second); + bool has_update = std::get<1>(debounce_client->second); + if (is_elapsed) { + if (std::get<0>(debounce_client->second) == _client && has_update) { + notify_client = true; + has_update = false; + } + elapsed = 0; + } + + debounce_clients_.erase(debounce_client); + + auto timeout = std::chrono::steady_clock::now() + + std::chrono::milliseconds(_filter->interval_ - elapsed); + debounce_clients_.emplace( + timeout, + std::make_tuple( + _client, has_update, + std::bind(&routing_manager_base::debounce_timeout_update_cbk, + shared_from_this(), std::placeholders::_1, _event, + _client, _filter), + event_id)); + } + + if (debounce_clients_.size() > 0) { + debounce_timer.expires_from_now( + std::chrono::duration_cast( + debounce_clients_.begin()->first + - std::chrono::steady_clock::now())); + debounce_timer.async_wait(std::get<2>(debounce_clients_.begin()->second)); + } + } // its_lock(debounce_mutex_) - if (debounce_clients_.size() > 0) { - debounce_timer.expires_from_now(std::chrono::duration_cast(debounce_clients_.begin()->first - std::chrono::steady_clock::now())); - debounce_timer.async_wait(std::get<2>(debounce_clients_.begin()->second)); + // _event->notify_one cannot be locked by debounce_mutex_, because it can lead to + // Lock inversion with update_and_get_filtered_subscribers and its mutex_! + if (notify_client) { + _event->notify_one(_client, false); } - } + } } void routing_manager_base::register_debounce(const std::shared_ptr &_filter, client_t _client, const std::shared_ptr &_event) { if (_filter->send_current_value_after_ == true) { std::lock_guard its_lock(debounce_mutex_); auto sec = std::chrono::milliseconds(_filter->interval_); - auto timeout = std::chrono::steady_clock::now() + sec; + auto timeout = std::chrono::steady_clock::now() + sec; auto elem = debounce_clients_.emplace(timeout, std::make_tuple(_client, false, std::bind(&routing_manager_base::debounce_timeout_update_cbk, shared_from_this(), - std::placeholders::_1, _event, _client, _filter), _event->get_event())); - + std::placeholders::_1, _event, _client, _filter), _event->get_event())); + if (elem == debounce_clients_.begin()) { debounce_timer.cancel(); debounce_timer.expires_from_now(sec); @@ -158,7 +198,7 @@ const vsomeip_sec_client_t *routing_manager_base::get_sec_client() const { void routing_manager_base::set_sec_client_port(port_t _port) { - host_->set_sec_client_port(_port); + host_->set_sec_client_port(_port); } std::string routing_manager_base::get_client_host() const { @@ -286,7 +326,7 @@ void routing_manager_base::release_service(client_t _client, its_info->remove_client(_client); } { - std::lock_guard its_lock(local_services_mutex_); + std::lock_guard its_service_guard(local_services_mutex_); auto found_service = local_services_history_.find(_service); if (found_service != local_services_history_.end()) { auto found_instance = found_service->second.find(_instance); @@ -418,12 +458,6 @@ void routing_manager_base::register_event(client_t _client, std::shared_ptr its_debounce = configuration_->get_debounce(host_->get_name(), _service, _instance, _notifier); if (its_debounce) { - VSOMEIP_WARNING << "Using debounce configuration for " - << " SOME/IP event " - << std::hex << std::setfill('0') - << std::setw(4) << _service << "." - << std::setw(4) << _instance << "." - << std::setw(4) << _notifier << "."; std::stringstream its_debounce_parameters; its_debounce_parameters << "(on_change=" << (its_debounce->on_change_ ? "true" : "false") @@ -433,8 +467,18 @@ void routing_manager_base::register_event(client_t _client, << ", " << std::hex << (int)i.second << ") "; its_debounce_parameters << "], interval=" << std::dec << its_debounce->interval_ << ")"; - VSOMEIP_WARNING << "Debounce parameters: " + + VSOMEIP_WARNING << "Using debounce configuration for " + << " SOME/IP event " + << 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 << "." + << " Debounce parameters: " << its_debounce_parameters.str(); + _epsilon_change_func = [its_debounce]( const std::shared_ptr &_old, const std::shared_ptr &_new) { @@ -503,28 +547,12 @@ void routing_manager_base::register_event(client_t _client, // Create a new callback for this client if filter interval is used register_debounce(its_debounce, _client, its_event); } else { - if (!_is_shadow && is_routing_manager()) { + if (_is_shadow || !is_routing_manager()) { _epsilon_change_func = [](const std::shared_ptr &_old, const std::shared_ptr &_new) { - bool is_change = (_old->get_length() != _new->get_length()); - if (!is_change) { - std::size_t its_pos = 0; - const byte_t *its_old_data = _old->get_data(); - const byte_t *its_new_data = _new->get_data(); - while (!is_change && its_pos < _old->get_length()) { - is_change = (*its_old_data++ != *its_new_data++); - its_pos++; - } - } - return is_change; - }; - } - else { - _epsilon_change_func = [](const std::shared_ptr &_old, - const std::shared_ptr &_new) { - (void)_old; - (void)_new; - return true; + (void)_old; + (void)_new; + return true; }; } } @@ -712,7 +740,7 @@ bool routing_manager_base::is_subscribe_to_any_event_allowed( auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); if (its_eventgroup) { for (const auto& e : its_eventgroup->get_events()) { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( _sec_client, _service, _instance, e->get_event())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client << " : routing_manager_base::is_subscribe_to_any_event_allowed: " @@ -734,7 +762,7 @@ void routing_manager_base::add_known_client(client_t _client, const std::string if (configuration_->is_security_enabled() && !configuration_->is_security_external()) { //Ignore if we have already loaded the policy extension policy_manager_impl::policy_loaded_e policy_loaded - = policy_manager_impl::get()->is_policy_extension_loaded(_client_host); + = configuration_->get_policy_manager()->is_policy_extension_loaded(_client_host); if (policy_loaded == policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_NOT_LOADED) { @@ -998,7 +1026,6 @@ void routing_manager_base::notify_one_current_value( bool routing_manager_base::send(client_t _client, std::shared_ptr _message, bool _force) { - bool is_sent(false); if (utility::is_request(_message->get_message_type())) { _message->set_client(_client); @@ -1166,10 +1193,10 @@ void routing_manager_base::remove_local(client_t _client, bool _remove_sec_client) { vsomeip_sec_client_t its_sec_client; - policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_sec_client); + configuration_->get_policy_manager()->get_client_to_sec_client_mapping(_client, its_sec_client); if (_remove_sec_client) { - policy_manager_impl::get()->remove_client_to_sec_client_mapping(_client); + configuration_->get_policy_manager()->remove_client_to_sec_client_mapping(_client); } for (auto its_subscription : _subscribed_eventgroups) { host_->on_subscription(std::get<0>(its_subscription), std::get<1>(its_subscription), @@ -1323,11 +1350,10 @@ bool routing_manager_base::send_local_notification(client_t _client, #ifdef USE_DLT bool has_local(false); #endif + (void)_client; bool has_remote(false); - method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); std::shared_ptr its_event = find_event(its_service, _instance, its_method); if (its_event && !its_event->is_shadow()) { @@ -1346,8 +1372,8 @@ bool routing_manager_base::send_local_notification(client_t _client, std::shared_ptr its_local_target = ep_mgr_->find_local(its_client); if (its_local_target) { - send_local(its_local_target, _client, _data, _size, - _instance, _reliable, protocol::id_e::SEND_ID, _status_check); + send_local(its_local_target, its_client, _data, _size, _instance, _reliable, + protocol::id_e::SEND_ID, _status_check); } } } @@ -1578,6 +1604,19 @@ routing_manager_base::get_subscriptions(const client_t _client) { return result; } + +void routing_manager_base::clear_shadow_subscriptions(void) { + std::lock_guard its_lock(events_mutex_); + for (const auto& its_service : events_) { + for (const auto& its_instance : its_service.second) { + for (const auto& its_event : its_instance.second) { + if (its_event.second->is_shadow()) + its_event.second->clear_subscribers(); + } + } + } +} + bool routing_manager_base::get_guest(client_t _client, boost::asio::ip::address &_address, port_t &_port) const { diff --git a/implementation/routing/src/routing_manager_client.cpp b/implementation/routing/src/routing_manager_client.cpp index dbb2bd2eb..e480be63a 100644 --- a/implementation/routing/src/routing_manager_client.cpp +++ b/implementation/routing/src/routing_manager_client.cpp @@ -1,8 +1,12 @@ -// Copyright (C) 2014-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2024 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/. +#if __GNUC__ > 11 +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) #include #endif @@ -29,6 +33,7 @@ #include "../../message/include/serializer.hpp" #include "../../protocol/include/assign_client_command.hpp" #include "../../protocol/include/assign_client_ack_command.hpp" +#include "../../protocol/include/config_command.hpp" #include "../../protocol/include/deregister_application_command.hpp" #include "../../protocol/include/distribute_security_policies_command.hpp" #include "../../protocol/include/dummy_command.hpp" @@ -62,12 +67,16 @@ #include "../../security/include/policy.hpp" #include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" #ifdef USE_DLT #include "../../tracing/include/connector_impl.hpp" #endif +#if defined(__QNX__) +#define HAVE_INET_PTON 1 +#include +#endif namespace vsomeip_v3 { routing_manager_client::routing_manager_client(routing_manager_host *_host, @@ -119,6 +128,10 @@ void routing_manager_client::init() { std::bind(&routing_manager_client::on_net_state_change, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + } else { + VSOMEIP_WARNING << __func__ << ": (" << its_guest_address.to_string() << ":" + << its_host_address.to_string() << ")" + << " local_link_connector not initialized."; } #else receiver_ = ep_mgr_->create_local_server(shared_from_this()); @@ -164,7 +177,8 @@ void routing_manager_client::stop() { while (state_ == inner_state_type_e::ST_REGISTERING) { std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); if (status == std::cv_status::timeout) { - VSOMEIP_WARNING << std::hex << get_client() << " registering timeout on stop"; + VSOMEIP_WARNING << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " registering timeout on stop"; break; } } @@ -175,7 +189,8 @@ void routing_manager_client::stop() { while (state_ == inner_state_type_e::ST_REGISTERED) { std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); if (status == std::cv_status::timeout) { - VSOMEIP_WARNING << std::hex << get_client() << " couldn't deregister application - timeout"; + VSOMEIP_WARNING << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " couldn't deregister application - timeout"; break; } } @@ -216,7 +231,7 @@ void routing_manager_client::stop() { if (configuration_->is_local_routing()) { std::stringstream its_client; its_client << utility::get_base_path(configuration_->get_network()) - << std::hex << get_client(); + << std::hex << get_client(); #ifdef _WIN32 ::_unlink(its_client.str().c_str()); #else @@ -362,7 +377,7 @@ void routing_manager_client::stop_offer_service(client_t _client, (void)_client; { - // Hold the mutex to ensure no placeholder event is created inbetween. + // Hold the mutex to ensure no placeholder event is created in between. std::lock_guard its_lock(stop_mutex_); routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor); @@ -646,7 +661,7 @@ void routing_manager_client::send_subscribe(client_t _client, return; } } else { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( get_sec_client(), _service, _instance, _event)) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client << " : routing_manager_proxy::subscribe: " @@ -674,8 +689,19 @@ void routing_manager_client::send_subscribe(client_t _client, if (its_error == protocol::error_e::ERROR_OK) { client_t its_target_client = find_local_client(_service, _instance); if (its_target_client != VSOMEIP_ROUTING_CLIENT) { - auto its_target = ep_mgr_->find_or_create_local(its_target_client); - its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + std::shared_ptr its_target = + ep_mgr_->find_or_create_local(its_target_client); + if (its_target) { + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else { + VSOMEIP_ERROR << std::hex << std::setfill('0') << __func__ + << ": no target available to send subscription." + << " client=" << std::setw(4) << _client + << " service=" << std::setw(4) << _service << "." << std::setw(4) + << _instance << "." << std::setw(2) + << static_cast(_major) << " event=" << std::setw(4) + << _event; + } } else { std::lock_guard its_lock(sender_mutex_); if (sender_) { @@ -828,21 +854,13 @@ bool routing_manager_client::send(client_t _client, const byte_t *_data, } if (client_side_logging_) { if (_size > VSOMEIP_MESSAGE_TYPE_POS) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); if (client_side_logging_filter_.empty() || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, ANY_INSTANCE))) || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, _instance)))) { - method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); - client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); + method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); + client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); VSOMEIP_INFO << "routing_manager_client::send: (" << std::hex << std::setfill('0') << std::setw(4) << get_client() << "): [" @@ -864,9 +882,7 @@ bool routing_manager_client::send(client_t _client, const byte_t *_data, std::shared_ptr its_target; if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { // Request - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); client_t its_client = find_local_client(its_service, _instance); if (its_client != VSOMEIP_ROUTING_CLIENT) { if (is_client_known(its_client)) { @@ -875,9 +891,7 @@ bool routing_manager_client::send(client_t _client, const byte_t *_data, } } else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { // Response - client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); + client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); if (its_client != VSOMEIP_ROUTING_CLIENT) { if (is_client_known(its_client)) { its_target = ep_mgr_->find_or_create_local(its_client); @@ -993,9 +1007,9 @@ void routing_manager_client::on_disconnect(const std::shared_ptr& _end is_connected_ = !(_endpoint == sender_); } if (!is_connected_) { - VSOMEIP_INFO << "routing_manager_client::on_disconnect: Client 0x" << std::hex - << get_client() << " calling host_->on_state " - << "with DEREGISTERED"; + VSOMEIP_INFO << "routing_manager_client::on_disconnect: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " calling host_->on_state with DEREGISTERED"; host_->on_state(state_type_e::ST_DEREGISTERED); } } @@ -1037,8 +1051,8 @@ void routing_manager_client::on_message( std::vector its_buffer(_data, _data + _size); protocol::error_e its_error; - auto its_security = policy_manager_impl::get(); - if (!its_security) + auto its_policy_manager = configuration_->get_policy_manager(); + if (!its_policy_manager) return; protocol::dummy_command its_dummy_command; @@ -1065,13 +1079,12 @@ void routing_manager_client::on_message( if (configuration_->is_security_enabled() && configuration_->is_local_routing() && !is_from_routing && _bound_client != its_client) { - VSOMEIP_WARNING << std::hex << std::setfill('0') - << "Client " << std::setw(4) << get_client() - << " received a message with command " << int(its_id) - << " from " << std::setw(4) << its_client - << " which doesn't match the bound client " - << std::setw(4) << _bound_client - << " ~> skip message!"; + VSOMEIP_WARNING << "Client " << std::hex << std::setw(4) << std::setfill('0') + << get_client() << " received a message with command " << int(its_id) + << " from " << std::hex << std::setw(4) << std::setfill('0') + << its_client << " which doesn't match the bound client " << std::hex + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; return; } @@ -1100,25 +1113,27 @@ void routing_manager_client::on_message( if (utility::is_notification(its_message->get_message_type())) { if (!is_response_allowed(_bound_client, its_message->get_service(), its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << " received a notification from client 0x" << _bound_client - << " which does not offer service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << " received a notification from client 0x" << _bound_client + << " which does not offer service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; return; } else { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + get_sec_client(), its_message->get_service(), its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << " isn't allowed to receive a notification from service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from client 0x" << _bound_client - << " ~> Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a notification from service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from client 0x" << _bound_client + << " ~> Skip message!"; return; } cache_event_payload(its_message); @@ -1127,49 +1142,53 @@ void routing_manager_client::on_message( if (configuration_->is_security_enabled() && configuration_->is_local_routing() && its_message->get_client() != _bound_client) { - VSOMEIP_WARNING << std::hex << std::setfill('0') - << "vSomeIP Security: Client 0x" << std::setw(4) << get_client() - << " received a request from client 0x" << std::setw(4) << its_message->get_client() - << " to service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " which doesn't match the bound client 0x" << std::setw(4) << _bound_client - << " ~> skip message!"; + VSOMEIP_WARNING << std::hex << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " received a request from client 0x" + << std::hex << std::setw(4) << std::setfill('0') << its_message->get_client() + << " to service/instance/method " << its_message->get_service() + << "/" << its_message->get_instance() << "/" << its_message->get_method() + << " which doesn't match the bound client 0x" + << std::hex << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; return; } - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(_sec_client, - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + _sec_client, its_message->get_service(), its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_message->get_client() - << " : routing_manager_client::on_message: " - << "isn't allowed to send a request to service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << its_message->get_client() + << " : routing_manager_client::on_message: " + << "isn't allowed to send a request to service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; return; } } else { // response if (!is_response_allowed(_bound_client, its_message->get_service(), its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << " received a response from client 0x" << _bound_client - << " which does not offer service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << " received a response from client 0x" << _bound_client + << " which does not offer service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; return; } else { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + get_sec_client(), its_message->get_service(), its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << " isn't allowed to receive a response from service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from client 0x" << _bound_client - << " ~> Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a response from service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from client 0x" << _bound_client + << " ~> Skip message!"; return; } } @@ -1178,30 +1197,31 @@ void routing_manager_client::on_message( if (!configuration_->is_remote_access_allowed()) { // if the message is from routing manager, check if // policy allows remote requests. - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << std::hex << "Security: Remote clients via routing manager with client ID 0x" << its_client - << " are not allowed to communicate with service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively with client 0x" << get_client() - << " ~> Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << std::hex << "Security: Remote clients via routing manager with client ID 0x" << its_client + << " are not allowed to communicate with service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively with client 0x" << get_client() + << " ~> Skip message!"; return; } else if (utility::is_notification(its_message->get_message_type())) { // As subscription is sent on eventgroup level, incoming remote event ID's // need to be checked as well if remote clients are allowed // and the local policy only allows specific events in the eventgroup to be received. - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + get_sec_client(), its_message->get_service(), its_message->get_instance(), its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << " isn't allowed to receive a notification from service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from remote clients via routing manager with client ID 0x" - << routing_host_id - << " ~> Skip message!"; + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a notification from service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from remote clients via routing manager with client ID 0x" + << routing_host_id + << " ~> Skip message!"; return; } cache_event_payload(its_message); @@ -1254,7 +1274,8 @@ void routing_manager_client::on_message( on_routing_info(_data, _size); } else { VSOMEIP_WARNING << "routing_manager_client::on_message: " - << std::hex << "Security: Client 0x" << get_client() + << "Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0')<< get_client() << " received an routing info from a client which isn't the routing manager" << " : Skip message!"; } @@ -1296,52 +1317,65 @@ void routing_manager_client::on_message( routing_manager_base::set_incoming_subscription_state(its_client, its_service, its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); #endif - // Remote subscriber: Notify routing manager initially + count subscribes - auto self = shared_from_this(); - host_->on_subscription(its_service, its_instance, its_eventgroup, - its_client, _sec_client, get_env(its_client), true, - [this, self, its_client, its_service, its_instance, - its_eventgroup, its_event, its_filter, its_pending_id, its_major] - (const bool _subscription_accepted) { - - std::uint32_t its_count(0); - if (_subscription_accepted) { - send_subscribe_ack(its_client, its_service, its_instance, - its_eventgroup, its_event, its_pending_id); - std::set its_already_subscribed_events; - bool inserted = insert_subscription(its_service, its_instance, its_eventgroup, - its_event, its_filter, VSOMEIP_ROUTING_CLIENT, &its_already_subscribed_events); - if (inserted) { - notify_remote_initially(its_service, its_instance, its_eventgroup, - its_already_subscribed_events); - } - #ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client, true); - #endif - its_count = get_remote_subscriber_count( - its_service, its_instance, its_eventgroup, true); - } else { - send_subscribe_nack(its_client, its_service, its_instance, - its_eventgroup, its_event, its_pending_id); - } - VSOMEIP_INFO << "SUBSCRIBE(" - << std::hex << std::setfill('0') - << std::setw(4) << its_client << "): [" - << std::setw(4) << its_service << "." - << std::setw(4) << its_instance << "." - << std::setw(4) << its_eventgroup << ":" - << std::setw(4) << its_event << ":" - << std::dec << (uint16_t)its_major << "] " - << std::boolalpha << (its_pending_id != PENDING_SUBSCRIPTION_ID) - << " " - << (_subscription_accepted ? - std::to_string(its_count) + " accepted." : "not accepted."); - + auto its_info = find_service(its_service, its_instance); + if (its_info) { + // Remote subscriber: Notify routing manager initially + count subscribes + auto self = shared_from_this(); + host_->on_subscription( + its_service, its_instance, its_eventgroup, its_client, _sec_client, + get_env(its_client), true, + [this, self, its_client, its_service, its_instance, its_eventgroup, + its_event, its_filter, its_pending_id, + its_major](const bool _subscription_accepted) { + std::uint32_t its_count(0); + if (_subscription_accepted) { + send_subscribe_ack(its_client, its_service, its_instance, + its_eventgroup, its_event, + its_pending_id); + std::set its_already_subscribed_events; + bool inserted = insert_subscription( + its_service, its_instance, its_eventgroup, + its_event, its_filter, VSOMEIP_ROUTING_CLIENT, + &its_already_subscribed_events); + if (inserted) { + notify_remote_initially(its_service, its_instance, + its_eventgroup, + its_already_subscribed_events); + } #ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event); + send_pending_notify_ones(its_service, its_instance, + its_eventgroup, its_client, true); +#endif + its_count = get_remote_subscriber_count( + its_service, its_instance, its_eventgroup, true); + } else { + send_subscribe_nack(its_client, its_service, its_instance, + its_eventgroup, its_event, + its_pending_id); + } + VSOMEIP_INFO + << "SUBSCRIBE(" << std::hex << std::setw(4) + << std::setfill('0') << its_client << "): [" << std::hex + << std::setw(4) << std::setfill('0') << its_service + << "." << std::hex << std::setw(4) << std::setfill('0') + << its_instance << "." << std::hex << std::setw(4) + << std::setfill('0') << its_eventgroup << ":" + << std::hex << std::setw(4) << std::setfill('0') + << its_event << ":" << std::dec << (uint16_t)its_major + << "] " << std::boolalpha + << (its_pending_id != PENDING_SUBSCRIPTION_ID) << " " + << (_subscription_accepted + ? std::to_string(its_count) + " accepted." + : "not accepted."); + }); + } else { + send_subscribe_nack(its_client, its_service, its_instance, its_eventgroup, + its_event, its_pending_id); + } +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::erase_incoming_subscription_state( + its_client, its_service, its_instance, its_eventgroup, its_event); #endif - }); } else if (is_client_known(its_client)) { its_lock.unlock(); if (!is_from_routing) { @@ -1355,7 +1389,7 @@ void routing_manager_client::on_message( return; } } else { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( _sec_client, its_service, its_instance, its_event)) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_client::on_message: " @@ -1388,28 +1422,40 @@ void routing_manager_client::on_message( (void) ep_mgr_->find_or_create_local(its_client); auto self = shared_from_this(); auto its_env = get_env(its_client); - host_->on_subscription(its_service, its_instance, - its_eventgroup, its_client, _sec_client, its_env, true, - [this, self, its_client, its_filter, _sec_client, its_env, its_service, - its_instance, its_eventgroup, its_event, its_major] - (const bool _subscription_accepted) { - if (!_subscription_accepted) { - send_subscribe_nack(its_client, its_service, its_instance, - its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); - } else { - send_subscribe_ack(its_client, its_service, its_instance, - its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); - routing_manager_base::subscribe(its_client, _sec_client, - its_service, its_instance, its_eventgroup, its_major, its_event, its_filter); + + auto its_info = find_service(its_service, its_instance); + if (its_info) { + host_->on_subscription( + its_service, its_instance, its_eventgroup, its_client, _sec_client, + its_env, true, + [this, self, its_client, its_filter, _sec_client, its_env, + its_service, its_instance, its_eventgroup, its_event, + its_major](const bool _subscription_accepted) { + if (!_subscription_accepted) { + send_subscribe_nack(its_client, its_service, its_instance, + its_eventgroup, its_event, + PENDING_SUBSCRIPTION_ID); + } else { + send_subscribe_ack(its_client, its_service, its_instance, + its_eventgroup, its_event, + PENDING_SUBSCRIPTION_ID); + routing_manager_base::subscribe( + its_client, _sec_client, its_service, its_instance, + its_eventgroup, its_major, its_event, its_filter); #ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client); + send_pending_notify_ones(its_service, its_instance, + its_eventgroup, its_client); #endif - } + } + }); + } else { + send_subscribe_nack(its_client, its_service, its_instance, its_eventgroup, + its_event, PENDING_SUBSCRIPTION_ID); + } #ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event); + routing_manager_base::erase_incoming_subscription_state( + its_client, its_service, its_instance, its_eventgroup, its_event); #endif - }); } else { if (_sec_client) { // Local & not yet known subscriber ~> set pending until subscriber gets known! @@ -1643,12 +1689,12 @@ void routing_manager_client::on_message( its_command.deserialize(its_buffer, its_error); if (its_error == protocol::error_e::ERROR_OK) { auto its_policy = its_command.get_policy(); - uint32_t its_uid; - uint32_t its_gid; + uid_t its_uid; + gid_t its_gid; if (its_policy->get_uid_gid(its_uid, its_gid)) { if (is_internal_policy_update - || its_security->is_policy_update_allowed(its_uid, its_policy)) { - its_security->update_security_policy(its_uid, its_gid, its_policy); + || its_policy_manager->is_policy_update_allowed(its_uid, its_policy)) { + its_policy_manager->update_security_policy(its_uid, its_gid, its_policy); send_update_security_policy_response(its_command.get_update_id()); } } else { @@ -1658,10 +1704,11 @@ void routing_manager_client::on_message( VSOMEIP_ERROR << "vSomeIP Security: Policy deserialization failed!"; } } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << " received a security policy update from a client which isn't the routing manager" - << " : Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << " received a security policy update from a client which isn't the routing manager" + << " : Skip message!"; } break; } @@ -1676,8 +1723,8 @@ void routing_manager_client::on_message( uid_t its_uid(its_command.get_uid()); gid_t its_gid(its_command.get_gid()); - if (its_security->is_policy_removal_allowed(its_uid)) { - its_security->remove_security_policy(its_uid, its_gid); + if (its_policy_manager->is_policy_removal_allowed(its_uid)) { + its_policy_manager->remove_security_policy(its_uid, its_gid); send_remove_security_policy_response(its_command.get_update_id()); } } else @@ -1686,10 +1733,11 @@ void routing_manager_client::on_message( << static_cast(its_error) << ")"; } else - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << "received a security policy removal from a client which isn't the routing manager" - << " : Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << "received a security policy removal from a client which isn't the routing manager" + << " : Skip message!"; break; } @@ -1703,8 +1751,8 @@ void routing_manager_client::on_message( uid_t its_uid; gid_t its_gid; p->get_uid_gid(its_uid, its_gid); - if (its_security->is_policy_update_allowed(its_uid, p)) - its_security->update_security_policy(its_uid, its_gid, p); + if (its_policy_manager->is_policy_update_allowed(its_uid, p)) + its_policy_manager->update_security_policy(its_uid, its_gid, p); } } else VSOMEIP_ERROR << __func__ @@ -1712,10 +1760,11 @@ void routing_manager_client::on_message( << static_cast(its_error) << ")"; } else - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << " received a security policy distribution command from a client which isn't the routing manager" - << " : Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << " received a security policy distribution command from a client which isn't the routing manager" + << " : Skip message!"; break; } @@ -1732,14 +1781,29 @@ void routing_manager_client::on_message( << static_cast(its_error) << ")"; } else - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_client::on_message: " - << "received a security credential update from a client which isn't the routing manager" - << " : Skip message!"; + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " : routing_manager_client::on_message: " + << "received a security credential update from a client which isn't the routing manager" + << " : Skip message!"; break; } #endif // !VSOMEIP_DISABLE_SECURITY + case protocol::id_e::CONFIG_ID: { + protocol::config_command its_command; + protocol::error_e its_command_error; + its_command.deserialize(its_buffer, its_command_error); + if (its_command_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ << ": config command deserialization failed (" << std::dec + << static_cast(its_command_error) << ")"; + break; + } + if (its_command.contains("hostname")) { + add_known_client(its_command.get_client(), its_command.at("hostname")); + } + break; + } default: break; } @@ -1754,13 +1818,13 @@ void routing_manager_client::on_routing_info( const byte_t *_data, uint32_t _size) { #if 0 std::stringstream msg; - msg << "rmp::on_routing_info(" << std::hex << get_client() << "): "; + msg << "rmp::on_routing_info(" << std::hex << std::setw(4) << std::setfill('0') << get_client() << "): "; for (uint32_t i = 0; i < _size; ++i) msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; VSOMEIP_INFO << msg.str(); #endif - auto its_security = policy_manager_impl::get(); - if (!its_security) + auto its_policy_manager = configuration_->get_policy_manager(); + if (!its_policy_manager) return; std::vector its_buffer(_data, _data + _size); @@ -1788,11 +1852,12 @@ void routing_manager_client::on_routing_info( } if (its_client == get_client()) { - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - << " (" << host_->get_name() << ") is registered."; + VSOMEIP_INFO << "Application/Client " + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " (" << host_->get_name() << ") is registered."; #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) - if (!its_security->check_credentials(get_client(), get_sec_client())) { - VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() + if (!its_policy_manager->check_credentials(get_client(), get_sec_client())) { + VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << std::setw(4) << std::setfill('0') << get_client() << " : routing_manager_client::on_routing_info: RIE_ADD_CLIENT: isn't allowed" << " to use the server endpoint due to credential check failed!"; deregister_application(); @@ -1828,8 +1893,8 @@ void routing_manager_client::on_routing_info( known_clients_.erase(its_client); } if (its_client == get_client()) { - its_security->remove_client_to_sec_client_mapping(its_client); - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() + its_policy_manager->remove_client_to_sec_client_mapping(its_client); + VSOMEIP_INFO << "Application/Client " << std::hex << std::setw(4) << std::setfill('0') << get_client() << " (" << host_->get_name() << ") is deregistered."; // inform host about its own registration state changes @@ -2026,8 +2091,8 @@ void routing_manager_client::on_offered_services_info( } void routing_manager_client::reconnect(const std::map &_clients) { - auto its_security = policy_manager_impl::get(); - if (!its_security) + auto its_policy_manager = configuration_->get_policy_manager(); + if (!its_policy_manager) return; // inform host about its own registration state changes @@ -2048,12 +2113,13 @@ void routing_manager_client::reconnect(const std::map &_c } } - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - << ": Reconnecting to routing manager."; + VSOMEIP_INFO << std::hex << "Application/Client " + << std::hex << std::setw(4) << std::setfill('0') << get_client() + <<": Reconnecting to routing manager."; #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) - if (!its_security->check_credentials(get_client(), get_sec_client())) { - VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() + if (!its_policy_manager->check_credentials(get_client(), get_sec_client())) { + VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << std::setw(4) << std::setfill('0') << get_client() << " : routing_manager_client::reconnect: isn't allowed" << " to use the server endpoint due to credential check failed!"; std::lock_guard its_lock(sender_mutex_); @@ -2072,6 +2138,9 @@ void routing_manager_client::reconnect(const std::map &_c void routing_manager_client::assign_client() { + VSOMEIP_INFO << __func__ << ": (" << std::hex << std::setw(4) << std::setfill('0') + << get_client() << ":" << host_->get_name() << ")"; + protocol::assign_client_command its_command; its_command.set_client(get_client()); its_command.set_name(host_->get_name()); @@ -2091,8 +2160,11 @@ void routing_manager_client::assign_client() { if (is_connected_) { std::lock_guard its_lock(sender_mutex_); if (sender_) { - if (state_ != inner_state_type_e::ST_DEREGISTERED) + if (state_ != inner_state_type_e::ST_DEREGISTERED) { + VSOMEIP_WARNING << __func__ << ": (" << std::hex << std::setw(4) << std::setfill('0') + << get_client() << ") Non-Deregistered State Set. Returning"; return; + } state_ = inner_state_type_e::ST_ASSIGNING; sender_->send(&its_buffer[0], static_cast(its_buffer.size())); @@ -2105,8 +2177,15 @@ void routing_manager_client::assign_client() { &routing_manager_client::assign_client_timeout_cbk, std::dynamic_pointer_cast(shared_from_this()), std::placeholders::_1)); + } else { + VSOMEIP_WARNING << __func__ << ": (" << std::hex << std::setw(4) << std::setfill('0') + << get_client() << ") sender not initialized. Ignoring client assignment"; } } + else { + VSOMEIP_WARNING << __func__ << ": (" << std::hex << std::setw(4) << std::setfill('0') + << get_client() << ") not connected. Ignoring client assignment"; + } } void routing_manager_client::register_application() { @@ -2144,18 +2223,34 @@ void routing_manager_client::register_application() { sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); register_application_timer_.cancel(); - register_application_timer_.expires_from_now(std::chrono::milliseconds(1000)); + register_application_timer_.expires_from_now(std::chrono::milliseconds(3000)); register_application_timer_.async_wait( std::bind( &routing_manager_client::register_application_timeout_cbk, std::dynamic_pointer_cast(shared_from_this()), std::placeholders::_1)); + + // Send a `config_command` to share our hostname with the other application. + protocol::config_command its_command_config; + its_command_config.set_client(get_client()); + its_command_config.insert("hostname", get_client_host()); + + std::vector its_buffer_config; + its_command_config.serialize(its_buffer_config, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + sender_->send(&its_buffer_config[0], + static_cast(its_buffer_config.size())); + } else { + VSOMEIP_ERROR << __func__ << ": config command serialization failed(" + << std::dec << int(its_error) << ")"; + } } } - } else - VSOMEIP_ERROR << __func__ - << ": register application command serialization failed(" - << std::dec << int(its_error) << ")"; + } else { + VSOMEIP_ERROR << __func__ << ": register application command serialization failed(" + << std::dec << int(its_error) << ")"; + } } void routing_manager_client::deregister_application() { @@ -2329,12 +2424,12 @@ void routing_manager_client::on_subscribe_ack(client_t _client, (void)_client; #if 0 VSOMEIP_ERROR << "routing_manager_client::" << __func__ - << "(" << std::hex << host_->get_client() << "):" + << "(" << std::hex << std::setw(4) << std::setfill('0') << host_->get_client() << "):" << "event=" - << std::hex << _service << "." - << std::hex << _instance << "." - << std::hex << _eventgroup << "." - << std::hex << _event; + << 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') << _event; #endif if (_event == ANY_EVENT) { auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); @@ -2430,20 +2525,20 @@ void routing_manager_client::send_pending_commands() { } void routing_manager_client::init_receiver() { -#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) - auto its_security = policy_manager_impl::get(); - if (!its_security) +#ifdef __linux__ + auto its_policy_manager = configuration_->get_policy_manager(); + if (!its_policy_manager) return; - its_security->store_client_to_sec_client_mapping(get_client(), get_sec_client()); - its_security->store_sec_client_to_client_mapping(get_sec_client(), get_client()); + its_policy_manager->store_client_to_sec_client_mapping(get_client(), get_sec_client()); + its_policy_manager->store_sec_client_to_client_mapping(get_sec_client(), get_client()); #endif if (!receiver_) { receiver_ = ep_mgr_->create_local_server(shared_from_this()); } else { std::uint16_t its_port = receiver_->get_local_port(); if (its_port != ILLEGAL_PORT) - VSOMEIP_INFO << "Reusing local server endpoint@" << its_port; + VSOMEIP_INFO << "Reusing local server endpoint@" << its_port << " endpoint: " << receiver_; } } @@ -2543,17 +2638,25 @@ routing_manager_client::assign_client_timeout_cbk( if (state_ != inner_state_type_e::ST_REGISTERED) { state_ = inner_state_type_e::ST_DEREGISTERED; register_again = true; + } else { + VSOMEIP_INFO << __func__ << ": Will not retry registry for Client [0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << "] : already registered "; } } if (register_again) { std::lock_guard its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " request client timeout! Trying again..."; + VSOMEIP_WARNING << "Client 0x" << std::hex << std::setw(4) << std::setfill('0') + << get_client() << " request client timeout! Trying again..."; if (sender_) { sender_->restart(); } } + } else if (_error != boost::asio::error::operation_aborted) { //ignore error when timer is deliberately cancelled + VSOMEIP_WARNING << __func__ << ": Ignoring Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " due to error_code: " << _error.value() ; } } @@ -2570,8 +2673,9 @@ void routing_manager_client::register_application_timeout_cbk( } if (register_again) { std::lock_guard its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " register timeout! Trying again..."; + VSOMEIP_WARNING << std::hex << "Client 0x" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " register timeout! Trying again..."; if (sender_) sender_->restart(); @@ -2679,8 +2783,9 @@ void routing_manager_client::register_client_error_handler(client_t _client, void routing_manager_client::handle_client_error(client_t _client) { if (_client != VSOMEIP_ROUTING_CLIENT) { - VSOMEIP_INFO << "Client 0x" << std::hex << get_client() - << " handles a client error(" << std::hex << _client << ")"; + VSOMEIP_INFO << "rmc::handle_client_error" << "Client 0x" << std::hex << std::setw(4) + << std::setfill('0') << get_client() << " handles a client error(" << std::hex + << std::setw(4) << std::setfill('0') << _client << ") not reconnecting"; remove_local(_client, true); } else { bool should_reconnect(true); @@ -2826,13 +2931,13 @@ void routing_manager_client::send_remove_security_policy_response( void routing_manager_client::on_update_security_credentials( const protocol::update_security_credentials_command &_command) { - auto its_security = policy_manager_impl::get(); - if (!its_security) + auto its_policy_manager = configuration_->get_policy_manager(); + if (!its_policy_manager) return; for (const auto &c : _command.get_credentials()) { std::shared_ptr its_policy(std::make_shared()); - boost::icl::interval_set its_gid_set; + boost::icl::interval_set its_gid_set; uid_t its_uid(c.first); gid_t its_gid(c.second); @@ -2843,7 +2948,7 @@ void routing_manager_client::on_update_security_credentials( its_policy->allow_who_ = true; its_policy->allow_what_ = true; - its_security->add_security_credentials(its_uid, its_gid, its_policy, get_client()); + its_policy_manager->add_security_credentials(its_uid, its_gid, its_policy, get_client()); } } #endif @@ -2864,27 +2969,34 @@ void routing_manager_client::on_client_assign_ack(const client_t &_client) { if (receiver_) { receiver_->start(); - VSOMEIP_INFO << std::hex << "Client " << get_client() - << " (" << host_->get_name() - << ") successfully connected to routing ~> registering.."; + VSOMEIP_INFO << "Client " + << std::hex << std::setw(4) << std::setfill('0') << get_client() + << " (" << host_->get_name() << ") successfully connected to routing ~> registering.."; register_application(); } else { + VSOMEIP_WARNING << __func__ << ": (" << host_->get_name() << ":" + << std::hex << std::setw(4) << std::setfill('0') + << _client << ") Receiver not started. Restarting"; state_ = inner_state_type_e::ST_DEREGISTERED; host_->set_client(VSOMEIP_CLIENT_UNSET); sender_->restart(); } + } else { + VSOMEIP_WARNING << __func__ << ": (" << host_->get_name() << ":" + << std::hex << std::setw(4) << std::setfill('0') + << _client << ") Not started. Discarding"; } } else { - VSOMEIP_ERROR << "Didn't receive valid clientID! Won't register application."; + VSOMEIP_ERROR << __func__ << ": (" << host_->get_name() << ":" + << std::hex << std::setw(4) << std::setfill('0') + << _client << ") Invalid clientID"; } } else { - VSOMEIP_WARNING << "Client " << std::hex << get_client() - << " received another client identifier (" - << std::hex << _client - << "). Ignoring it. (" - << (int)state_ << ")"; + VSOMEIP_WARNING << "Client " << std::hex << std::setw(4) << std::setfill('0') + << get_client() << " received another client identifier (" << _client + << "). Ignoring it. (" << static_cast(state_.load()) << ")"; } } diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 79f408045..9d45c656a 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -48,7 +48,7 @@ #include "../../service_discovery/include/defines.hpp" #include "../../service_discovery/include/runtime.hpp" #include "../../service_discovery/include/service_discovery.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" #ifdef USE_DLT #include "../../tracing/include/connector_impl.hpp" @@ -90,8 +90,8 @@ routing_manager_impl::routing_manager_impl(routing_manager_host *_host) : } routing_manager_impl::~routing_manager_impl() { - utility::remove_lockfile(configuration_->get_network()); utility::reset_client_ids(configuration_->get_network()); + utility::remove_lockfile(configuration_->get_network()); } boost::asio::io_context &routing_manager_impl::get_io() { @@ -423,7 +423,7 @@ bool routing_manager_impl::offer_service(client_t _client, // Check if the application hosted by routing manager is allowed to offer // offer_service requests of local proxies are checked in rms::on:message if (_client == get_client()) { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_offer( + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_offer( get_sec_client(), _service, _instance)) { VSOMEIP_WARNING << "routing_manager_impl::offer_service: " << std::hex << "Security: Client 0x" << _client @@ -649,7 +649,15 @@ void routing_manager_impl::release_service(client_t _client, service_t _service, std::shared_ptr its_info(find_service(_service, _instance)); if (its_info && !its_info->is_local()) { - if (!its_info->get_requesters_size()) { + if (0 == its_info->get_requesters_size()) { + auto its_eventgroups = find_eventgroups(_service, _instance); + for (const auto &eg : its_eventgroups) { + auto its_events = eg->get_events(); + for (auto &e : its_events) { + e->clear_subscribers(); + } + } + if (discovery_) { discovery_->release_service(_service, _instance); discovery_->unsubscribe_all(_service, _instance); @@ -671,7 +679,9 @@ void routing_manager_impl::release_service(client_t _client, service_t _service, eg_has_subscribers = true; } } - discovery_->unsubscribe(_service, _instance, its_id, _client); + if (discovery_) { + discovery_->unsubscribe(_service, _instance, its_id, _client); + } if (!eg_has_subscribers) { for (const auto &e : its_events) { e->unset_payload(true); @@ -692,6 +702,11 @@ void routing_manager_impl::subscribe( eventgroup_t _eventgroup, major_version_t _major, event_t _event, const std::shared_ptr &_filter) { + if (routing_state_ == routing_state_e::RS_SUSPENDED) { + VSOMEIP_INFO << "rmi::" << __func__ << " We are suspended --> do nothing."; + return; + } + VSOMEIP_INFO << "SUBSCRIBE(" << std::hex << std::setfill('0') << std::setw(4) << _client << "): [" @@ -877,22 +892,22 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]); bool is_notification = utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]); bool is_response = utility::is_response(_data[VSOMEIP_MESSAGE_TYPE_POS]); - - client_t its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); + client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + client_t its_target_client = get_client(); bool is_service_discovery = (its_service == sd::service && its_method == sd::method); if (is_request) { - its_target = ep_mgr_->find_local(its_service, _instance); + its_target_client = find_local_client(its_service, _instance); + its_target = find_local(its_target_client); } else if (!is_notification) { its_target = find_local(its_client); - } else if (is_notification && _client && !is_service_discovery) { // Selective notifications! + its_target_client = its_client; + } else if (is_notification && _client + && !is_service_discovery) { // Selective notifications! if (_client == get_client()) { #ifdef USE_DLT trace::header its_header; @@ -906,6 +921,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, return true; } its_target = find_local(_client); + its_target_client = _client; } if (its_target) { @@ -920,8 +936,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, _data, _size); } #endif - is_sent = send_local(its_target, get_client(), _data, _size, _instance, - _reliable, protocol::id_e::SEND_ID, _status_check); + is_sent = send_local(its_target, its_target_client, _data, _size, _instance, _reliable, + protocol::id_e::SEND_ID, _status_check); } else { // Check whether hosting application should get the message // If not, check routes to external @@ -936,10 +952,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, if (e2e_provider_) { if ( !is_service_discovery) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); #ifndef ANDROID if (e2e_provider_->is_protected({its_service, its_method})) { // Find out where the protected area starts @@ -970,9 +984,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, #endif is_sent = its_target->send(_data, _size); } else { - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); VSOMEIP_ERROR<< "Routing info for remote service could not be found! (" << std::hex << std::setfill('0') << std::setw(4) << its_client << "): [" @@ -987,8 +999,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, if (is_notification && !is_service_discovery) { (void)send_local_notification(get_client(), _data, _size, _instance, _reliable, _status_check, _force); - method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); + method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); std::shared_ptr its_event = find_event(its_service, _instance, its_method); if (its_event) { #ifdef USE_DLT @@ -1061,9 +1072,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, && !its_info->is_local()) { // We received a response/error but neither the hosting application // nor another local client could be found --> drop - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); VSOMEIP_ERROR << "routing_manager_impl::send: Received response/error for unknown client (" << std::hex << std::setfill('0') @@ -1085,9 +1094,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, #endif is_sent = its_target->send(_data, _size); } else { - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); VSOMEIP_ERROR << "Routing error. Endpoint for service (" << std::hex << std::setfill('0') << std::setw(4) << its_client << "): [" @@ -1100,9 +1107,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } } else { if (!is_notification) { - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); VSOMEIP_ERROR << "Routing error. Not hosting service (" << std::hex << std::setfill('0') << std::setw(4) << its_client << "): [" @@ -1133,12 +1138,8 @@ bool routing_manager_impl::send_to( length_t its_size = its_serializer->get_size(); e2e_buffer its_buffer; if (e2e_provider_) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - method_t its_method = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_METHOD_POS_MIN], - its_data[VSOMEIP_METHOD_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&its_data[VSOMEIP_SERVICE_POS_MIN]); + method_t its_method = bithelper::read_uint16_be(&its_data[VSOMEIP_METHOD_POS_MIN]); #ifndef ANDROID if (e2e_provider_->is_protected({its_service, its_method})) { auto its_base = e2e_provider_->get_protection_base({its_service, its_method}); @@ -1150,8 +1151,10 @@ bool routing_manager_impl::send_to( #endif } - const_cast(its_data)[VSOMEIP_CLIENT_POS_MIN] = VSOMEIP_WORD_BYTE1(_client); - const_cast(its_data)[VSOMEIP_CLIENT_POS_MAX] = VSOMEIP_WORD_BYTE0(_client); + uint8_t its_client[2] = {0}; + bithelper::write_uint16_le(_client, its_client); + const_cast(its_data)[VSOMEIP_CLIENT_POS_MIN] = its_client[1]; + const_cast(its_data)[VSOMEIP_CLIENT_POS_MAX] = its_client[0]; is_sent = send_to(_target, its_data, its_size, _message->get_instance()); @@ -1496,11 +1499,9 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, #endif if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) { its_message_type = static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]); - its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); + its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); if (its_service == VSOMEIP_SD_SERVICE) { - its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); + its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); if (discovery_ && its_method == sd::method) { if (configuration_->get_sd_port() == _remote_port) { if (!_remote_address.is_unspecified()) { @@ -1524,15 +1525,9 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, its_instance = ep_mgr_impl_->find_instance(its_service, _receiver); } if (its_instance == 0xFFFF) { - its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - const client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - const session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); + its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + const client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); boost::system::error_code ec; VSOMEIP_ERROR << "Received message on invalid port: [" << std::hex << std::setfill('0') @@ -1566,12 +1561,8 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, // Security checks if enabled! if (configuration_->is_security_enabled()) { if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - client_t requester = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); + client_t requester = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); if (!configuration_->is_offered_remote(its_service, its_instance)) { VSOMEIP_WARNING << std::hex << "Security: Received a remote request " << "for service/instance " << its_service << "/" << its_instance @@ -1596,9 +1587,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } } if (e2e_provider_) { - its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); + its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); #ifndef ANDROID if (e2e_provider_->is_checked({its_service, its_method})) { auto its_base = e2e_provider_->get_protection_base({its_service, its_method}); @@ -1664,9 +1653,7 @@ bool routing_manager_impl::on_message(service_t _service, instance_t _instance, if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { its_client = find_local_client(_service, _instance); } else { - its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); + its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); } #if 0 @@ -1699,8 +1686,7 @@ bool routing_manager_impl::on_message(service_t _service, instance_t _instance, void routing_manager_impl::on_notification(client_t _client, service_t _service, instance_t _instance, const byte_t *_data, length_t _size, bool _notify_one) { - event_t its_event_id = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); + event_t its_event_id = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); std::shared_ptr its_event = find_event(_service, _instance, its_event_id); if (its_event) { uint32_t its_length = utility::get_payload_size(_data, _size); @@ -1728,21 +1714,6 @@ void routing_manager_impl::on_notification(client_t _client, } } -bool routing_manager_impl::is_last_stop_callback(const uint32_t _callback_id) { - bool last_callback(false); - auto found_id = callback_counts_.find(_callback_id); - if (found_id != callback_counts_.end()) { - found_id->second--; - if (found_id->second == 0) { - last_callback = true; - } - } - if (last_callback) { - callback_counts_.erase(_callback_id); - } - return last_callback; -} - void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { { @@ -1799,69 +1770,52 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se if (its_info) { its_reliable_endpoint = its_info->get_endpoint(true); its_unreliable_endpoint = its_info->get_endpoint(false); - static std::atomic callback_id(0); - const uint32_t its_callback_id = ++callback_id; + // Create a ready_to_stop_t object to synchronize the stopping + // of the service on reliable and unreliable endpoints. struct ready_to_stop_t { - ready_to_stop_t() : reliable_(false), unreliable_(false){} + ready_to_stop_t(bool _reliable, bool _unreliable) + : reliable_(_reliable), unreliable_(_unreliable) { + } + + inline bool is_ready() const { + return reliable_ && unreliable_; + } + std::atomic reliable_; std::atomic unreliable_; }; - auto ready_to_stop = std::make_shared(); + auto ready_to_stop = std::make_shared( + its_reliable_endpoint == nullptr, its_unreliable_endpoint == nullptr); auto ptr = shared_from_this(); - auto callback = [&, its_callback_id, ptr, its_info, its_reliable_endpoint, its_unreliable_endpoint, + auto callback = [this, ptr, its_info, its_reliable_endpoint, its_unreliable_endpoint, ready_to_stop, _service, _instance, _major, _minor] - (std::shared_ptr _endpoint, service_t _stopped_service) { - (void)_stopped_service; - if (its_reliable_endpoint && its_reliable_endpoint == _endpoint) { + (std::shared_ptr _endpoint) { + + if (its_reliable_endpoint && its_reliable_endpoint == _endpoint) ready_to_stop->reliable_ = true; - } - if (its_unreliable_endpoint && its_unreliable_endpoint == _endpoint) { + + if (its_unreliable_endpoint && its_unreliable_endpoint == _endpoint) ready_to_stop->unreliable_ = true; - } - if ((its_unreliable_endpoint && !ready_to_stop->unreliable_) || - (its_reliable_endpoint && !ready_to_stop->reliable_)) { - { - std::lock_guard its_lock(callback_counts_mutex_); - if (is_last_stop_callback(its_callback_id)) { - erase_offer_command(_service, _instance); - } - } - return; - } if (discovery_) { - if (its_info->get_major() == _major && its_info->get_minor() == _minor) { + if (its_info->get_major() == _major && its_info->get_minor() == _minor) discovery_->stop_offer_service(its_info, true); - } } - del_routing_info(_service, _instance, (its_reliable_endpoint != nullptr), - (its_unreliable_endpoint != nullptr)); + del_routing_info(_service, _instance, + its_reliable_endpoint != nullptr, its_unreliable_endpoint != nullptr); for (const auto& ep: {its_reliable_endpoint, its_unreliable_endpoint}) { if (ep) { if (ep_mgr_impl_->remove_instance(_service, ep.get())) { - { - std::lock_guard its_lock(callback_counts_mutex_); - callback_counts_[its_callback_id]++; - } // last instance -> pass ANY_INSTANCE and shutdown completely ep->prepare_stop( - [&, _service, _instance, its_callback_id, ptr, its_reliable_endpoint, its_unreliable_endpoint] - (std::shared_ptr _endpoint, - service_t _stopped_service) { - (void)_stopped_service; + [this, ptr] (std::shared_ptr _endpoint_to_stop) { if (ep_mgr_impl_->remove_server_endpoint( - _endpoint->get_local_port(), - _endpoint->is_reliable())) { - _endpoint->stop(); - } - { - std::lock_guard its_lock(callback_counts_mutex_); - if (is_last_stop_callback(its_callback_id)) { - erase_offer_command(_service, _instance); - } + _endpoint_to_stop->get_local_port(), + _endpoint_to_stop->is_reliable())) { + _endpoint_to_stop->stop(); } }, ANY_SERVICE); } @@ -1869,37 +1823,17 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se clear_service_info(_service, _instance, ep->is_reliable()); } } - { - std::lock_guard its_lock(callback_counts_mutex_); - if (is_last_stop_callback(its_callback_id)) { - erase_offer_command(_service, _instance); - } - } + + if (ready_to_stop->is_ready()) + erase_offer_command(_service, _instance); }; - // determine callback count - for (const auto& ep : {its_reliable_endpoint, its_unreliable_endpoint}) { - if (ep) { - std::lock_guard its_lock(callback_counts_mutex_); - auto found_id = callback_counts_.find(its_callback_id); - if (found_id != callback_counts_.end()) { - found_id->second++; - } else { - callback_counts_[its_callback_id] = 1; - } - } - } - for (const auto& ep : {its_reliable_endpoint, its_unreliable_endpoint}) { - if (ep) { + for (const auto& ep : { its_reliable_endpoint, its_unreliable_endpoint }) { + if (ep) ep->prepare_stop(callback, _service); - } } if (!its_reliable_endpoint && !its_unreliable_endpoint) { - { - std::lock_guard its_lock(callback_counts_mutex_); - callback_counts_.erase(its_callback_id); - } erase_offer_command(_service, _instance); } @@ -1959,8 +1893,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + get_sec_client(), its_message->get_service(), its_message->get_instance(), its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " @@ -1987,8 +1921,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, return false; } - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(_sec_client, - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + _sec_client, its_message->get_service(), its_message->get_instance(), its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " @@ -2010,8 +1944,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + get_sec_client(), its_message->get_service(), its_message->get_instance(), its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " @@ -2038,8 +1972,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else if (utility::is_notification(its_message->get_message_type())) { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), - its_message->get_service(), its_message->get_instance(), + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( + get_sec_client(), its_message->get_service(), its_message->get_instance(), its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " @@ -2062,16 +1996,34 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, return is_delivered; } +#ifdef VSOMEIP_ENABLE_DEFAULT_EVENT_CACHING +bool +routing_manager_impl::has_subscribed_eventgroup( + service_t _service, instance_t _instance) const { + + std::lock_guard its_lock(eventgroups_mutex_); + auto found_service = eventgroups_.find(_service); + if (found_service != eventgroups_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) + for (const auto &its_eventgroup : found_instance->second) + for (const auto &e : its_eventgroup.second->get_events()) + if (!e->get_subscribers().empty()) + return true; + } + + return false; +} +#endif // VSOMEIP_ENABLE_DEFAULT_EVENT_CACHING + bool routing_manager_impl::deliver_notification( service_t _service, instance_t _instance, const byte_t *_data, length_t _length, bool _reliable, client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check, bool _is_from_remote) { - event_t its_event_id = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); - client_t its_client_id = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]); + event_t its_event_id = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + client_t its_client_id = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); std::shared_ptr its_event = find_event(_service, _instance, its_event_id); if (its_event) { @@ -2126,8 +2078,8 @@ bool routing_manager_impl::deliver_notification( } else { std::shared_ptr its_local_target = find_local(its_local_client); if (its_local_target) { - send_local(its_local_target, VSOMEIP_ROUTING_CLIENT, - _data, _length, _instance, _reliable, protocol::id_e::SEND_ID, _status_check); + send_local(its_local_target, VSOMEIP_ROUTING_CLIENT, _data, _length, + _instance, _reliable, protocol::id_e::SEND_ID, _status_check); } } } @@ -2153,6 +2105,42 @@ bool routing_manager_impl::deliver_notification( } } else { +#ifdef VSOMEIP_ENABLE_DEFAULT_EVENT_CACHING + if (has_subscribed_eventgroup(_service, _instance)) { + if (!is_suppress_event(_service, _instance, its_event_id)) { + VSOMEIP_WARNING << __func__ << ": Caching unregistered event [" + << 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') << its_event_id << "]"; + } + + routing_manager_base::register_event(host_->get_client(), + _service, _instance, its_event_id, { }, + event_type_e::ET_UNKNOWN, + _reliable ? reliability_type_e::RT_RELIABLE + : reliability_type_e::RT_UNRELIABLE, + std::chrono::milliseconds::zero(), false, true, nullptr, + true, true, true); + + its_event = find_event(_service, _instance, its_event_id); + if (its_event) { + auto its_length = utility::get_payload_size(_data, _length); + auto its_payload = runtime::get()->create_payload( + &_data[VSOMEIP_PAYLOAD_POS], its_length); + its_event->set_payload(its_payload, true); + } else + VSOMEIP_ERROR << __func__ << ": Event registration failed [" + << 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') << its_event_id << "]"; + } else if (!is_suppress_event(_service, _instance, its_event_id)) { + VSOMEIP_WARNING << __func__ << ": Dropping unregistered event [" + << 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') << its_event_id << "] " + << "Service has no subscribed eventgroup."; + } +#else if (!is_suppress_event(_service, _instance, its_event_id)) { VSOMEIP_WARNING << __func__ << ": Event [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." @@ -2160,6 +2148,7 @@ bool routing_manager_impl::deliver_notification( << std::hex << std::setw(4) << std::setfill('0') << its_event_id << "]" << " is not registered. The message is dropped."; } +#endif // VSOMEIP_ENABLE_DEFAULT_EVENT_CACHING } return true; } @@ -2198,8 +2187,18 @@ std::shared_ptr routing_manager_impl::create_service_discovery_endpoin if (!_reliable) { auto its_server_endpoint = std::dynamic_pointer_cast< udp_server_endpoint_impl>(its_service_endpoint); - if (its_server_endpoint) + if (its_server_endpoint) { + its_server_endpoint->set_unicast_sent_callback( + std::bind(&sd::service_discovery::sent_messages, discovery_.get(), + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + its_server_endpoint->set_receive_own_multicast_messages(true); + its_server_endpoint->set_sent_multicast_received_callback( + std::bind(&sd::service_discovery::sent_messages, discovery_.get(), + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); its_server_endpoint->join(_address); + } } } else { VSOMEIP_ERROR<< "Service Discovery endpoint could not be created. " @@ -2265,11 +2264,7 @@ bool routing_manager_impl::is_acl_message_allowed(endpoint *_receiver, const bool is_local = its_info && its_info->is_local(); message_acceptance_t message_acceptance { -#if VSOMEIP_BOOST_VERSION < 106600 - static_cast(_remote_address.to_v4().to_ulong()), -#else _remote_address.to_v4().to_uint(), -#endif _receiver->get_local_port(), is_local, _service, _instance }; if (!message_acceptance_handler_(message_acceptance)) { @@ -2807,6 +2802,14 @@ routing_manager_impl::expire_subscriptions( const auto its_info = its_eventgroup.second; for (auto its_subscription : its_info->get_remote_subscriptions()) { + if (its_subscription->is_forwarded()) { + VSOMEIP_WARNING << __func__ << ": New remote subscription replaced expired [" + << std::hex << std::setw(4) << std::setfill('0') << its_service.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup.first << "]"; + continue; + } + // Note: get_remote_subscription delivers a copied // set of subscriptions. Thus, its is possible to // to remove them within the loop. @@ -2855,6 +2858,7 @@ routing_manager_impl::expire_subscriptions( << std::boolalpha << its_ep_definition->is_reliable(); } } + its_subscription->set_expired(); on_remote_unsubscribe(its_subscription); } } @@ -2934,12 +2938,19 @@ void routing_manager_impl::on_remote_subscribe( // not exist or is still (partly) pending. remote_subscription_id_t its_id; std::set its_added; - update_remote_subscription_mutex_.lock(); + std::unique_lock its_update_lock{update_remote_subscription_mutex_}; + if (_subscription->is_expired()) { + VSOMEIP_WARNING << __func__ << ": remote subscription already expired"; + return; + } else { + _subscription->set_forwarded(); + } + auto its_result = its_eventgroupinfo->update_remote_subscription( _subscription, its_expiration, its_added, its_id, true); if (its_result) { if (!_subscription->is_pending()) { // resubscription without change - update_remote_subscription_mutex_.unlock(); + its_update_lock.unlock(); _callback(_subscription); } else if (!its_added.empty()) { // new clients for a selective subscription const client_t its_offering_client @@ -2947,7 +2958,6 @@ void routing_manager_impl::on_remote_subscribe( send_subscription(its_offering_client, its_service, its_instance, its_eventgroup, its_major, its_added, _subscription->get_id()); - update_remote_subscription_mutex_.unlock(); } else { // identical subscription is not yet processed std::stringstream its_warning; its_warning << __func__ << " a remote subscription is already pending [" @@ -2970,7 +2980,7 @@ void routing_manager_impl::on_remote_subscribe( its_warning << "]"; VSOMEIP_WARNING << its_warning.str(); - update_remote_subscription_mutex_.unlock(); + its_update_lock.unlock(); _callback(_subscription); } } else { // new subscription @@ -2979,7 +2989,7 @@ void routing_manager_impl::on_remote_subscribe( _subscription->set_all_client_states( remote_subscription_state_e::SUBSCRIPTION_NACKED); - update_remote_subscription_mutex_.unlock(); + its_update_lock.unlock(); _callback(_subscription); return; } @@ -2992,7 +3002,6 @@ void routing_manager_impl::on_remote_subscribe( send_subscription(its_offering_client, its_service, its_instance, its_eventgroup, its_major, _subscription->get_clients(), its_id); - update_remote_subscription_mutex_.unlock(); } } @@ -3028,7 +3037,7 @@ void routing_manager_impl::on_remote_unsubscribe( remote_subscription_id_t its_id(0); std::set its_removed; - update_remote_subscription_mutex_.lock(); + std::unique_lock its_update_lock{update_remote_subscription_mutex_}; auto its_result = its_info->update_remote_subscription( _subscription, std::chrono::steady_clock::now(), its_removed, its_id, false); @@ -3040,8 +3049,6 @@ void routing_manager_impl::on_remote_unsubscribe( its_service, its_instance, its_eventgroup, its_major, its_removed, its_id); } - - update_remote_subscription_mutex_.unlock(); } void routing_manager_impl::on_subscribe_ack_with_multicast( @@ -3183,8 +3190,7 @@ void routing_manager_impl::on_subscribe_nack(client_t _client, return_code_e routing_manager_impl::check_error(const byte_t *_data, length_t _size, instance_t _instance) { - service_t its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); if (_size >= VSOMEIP_PAYLOAD_POS) { if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]) @@ -3237,25 +3243,16 @@ void routing_manager_impl::send_error(return_code_e _return_code, session_t its_session = 0; major_version_t its_version = 0; - if (_size >= VSOMEIP_CLIENT_POS_MAX) { - its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - } - if (_size >= VSOMEIP_SERVICE_POS_MAX) { - its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - } - if (_size >= VSOMEIP_METHOD_POS_MAX) { - its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); - } - if (_size >= VSOMEIP_SESSION_POS_MAX) { - its_session = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); - } - if( _size >= VSOMEIP_INTERFACE_VERSION_POS) { + if (_size >= VSOMEIP_CLIENT_POS_MAX) + its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); + if (_size >= VSOMEIP_SERVICE_POS_MAX) + its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); + if (_size >= VSOMEIP_METHOD_POS_MAX) + its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + if (_size >= VSOMEIP_SESSION_POS_MAX) + its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); + if( _size >= VSOMEIP_INTERFACE_VERSION_POS) its_version = _data[VSOMEIP_INTERFACE_VERSION_POS]; - } auto error_message = runtime::get()->create_message(_reliable); error_message->set_client(its_client); @@ -3351,6 +3348,12 @@ routing_manager_impl::expire_subscriptions(bool _force) { << std::setw(4) << its_instance.first << "." << std::setw(4) << its_eventgroup.first << "]"; continue; + } else if (s->is_forwarded()) { + VSOMEIP_WARNING << __func__ << ": New remote subscription replaced expired [" + << std::hex << std::setw(4) << std::setfill('0') << its_service.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup.first << "]"; + continue; } for (auto its_client : s->get_clients()) { if (_force) { @@ -3372,6 +3375,7 @@ routing_manager_impl::expire_subscriptions(bool _force) { } for (auto &s : its_expired_subscriptions) { + s.first->set_expired(); auto its_info = s.first->get_eventgroupinfo(); if (its_info) { auto its_service = its_info->get_service(); @@ -3379,7 +3383,7 @@ routing_manager_impl::expire_subscriptions(bool _force) { auto its_eventgroup = its_info->get_eventgroup(); remote_subscription_id_t its_id; - update_remote_subscription_mutex_.lock(); + std::unique_lock its_update_lock{update_remote_subscription_mutex_}; auto its_result = its_info->update_remote_subscription( s.first, std::chrono::steady_clock::now(), s.second, its_id, false); @@ -3421,7 +3425,6 @@ routing_manager_impl::expire_subscriptions(bool _force) { its_service, its_instance, its_eventgroup, s.second, s.first->get_id()); } - update_remote_subscription_mutex_.unlock(); if (s.first->get_unreliable()) { VSOMEIP_INFO << (_force ? "Removed" : "Expired") << " subscription [" @@ -3682,7 +3685,7 @@ void routing_manager_impl::register_client_error_handler(client_t _client, } void routing_manager_impl::handle_client_error(client_t _client) { - VSOMEIP_INFO << "routing_manager_impl::" << __func__ << " Client 0x" << std::hex << get_client() + VSOMEIP_INFO << "rmi::" << __func__ << " Client 0x" << std::hex << get_client() << " handles a client error(" << std::hex << _client << ")"; if (stub_) stub_->update_registration(_client, registration_type_e::DEREGISTER_ON_ERROR, @@ -3755,6 +3758,10 @@ void routing_manager_impl::send_subscribe(client_t _client, service_t _service, } } +routing_state_e routing_manager_impl::get_routing_state() { + return routing_manager_base::get_routing_state(); +} + void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { { std::lock_guard its_lock(routing_state_mutex_); @@ -3776,6 +3783,9 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { // stop processing of incoming SD messages discovery_->stop(); + // stop all endpoints + ep_mgr_->suspend(); + VSOMEIP_INFO << "rmi::" << __func__ << " Inform all applications that we are going to suspend"; send_suspend(); @@ -3797,6 +3807,13 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { << std::hex << std::setw(4) << std::setfill('0') << its_service.first << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance.first << "]"; + // Remove the service from the offer_commands_ and prepare_stop_handlers_ to force the next offer to be processed + offer_commands_.erase(std::make_pair(its_service.first, its_instance.first)); + if (has_reliable) + its_instance.second->get_endpoint(true)->remove_stop_handler(its_service.first); + if (has_unreliable) + its_instance.second->get_endpoint(false)->remove_stop_handler(its_service.first); + del_routing_info(its_service.first, its_instance.first, has_reliable, has_unreliable); std::lock_guard its_lock(pending_offers_mutex_); @@ -3804,12 +3821,6 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { if (its_pending_offer != pending_offers_.end()) its_pending_offer->second.erase(its_instance.first); - // Remove the service from the offer_commands_ and prepare_stop_handlers_ to force the next offer to be processed - offer_commands_.erase(std::make_pair(its_service.first, its_instance.first)); - if (has_reliable) - its_instance.second->get_endpoint(true)->remove_stop_handler(its_service.first); - if (has_unreliable) - its_instance.second->get_endpoint(false)->remove_stop_handler(its_service.first); } VSOMEIP_WARNING << "Service " << std::hex << std::setfill('0') @@ -3832,6 +3843,9 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { remote_subscription_state_.clear(); } + // Remove all subscribers to shadow events + clear_shadow_subscriptions(); + // send StopSubscribes and clear subscribed_ map discovery_->unsubscribe_all_on_suspend(); @@ -3880,6 +3894,9 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { routing_state_handler_(_routing_state); } + // start all endpoints + ep_mgr_->resume(); + // start processing of SD messages (incoming remote offers should lead to new subscribe messages) discovery_->start(); @@ -4550,7 +4567,7 @@ routing_manager_impl::on_unsubscribe_ack(client_t _client, std::shared_ptr its_info = find_eventgroup(_service, _instance, _eventgroup); if (its_info) { - update_remote_subscription_mutex_.lock(); + std::unique_lock its_update_lock{update_remote_subscription_mutex_}; const auto its_subscription = its_info->get_remote_subscription(_id); if (its_subscription) { its_info->remove_remote_subscription(_id); @@ -4583,7 +4600,6 @@ routing_manager_impl::on_unsubscribe_ack(client_t _client, << std::setw(4) << _instance << "." << std::setw(4) << _eventgroup << "]"; } - update_remote_subscription_mutex_.unlock(); } else { VSOMEIP_ERROR << __func__ << ": Received StopSubscribe for unknown eventgroup: (" @@ -4730,7 +4746,7 @@ void routing_manager_impl::service_endpoint_connected( _major, _minor); } - std::shared_ptr its_timer = + auto its_timer = std::make_shared(io_); boost::system::error_code ec; its_timer->expires_from_now(std::chrono::milliseconds(3), ec); @@ -4837,7 +4853,7 @@ routing_manager_impl::send_expired_subscription(client_t _offering_client, #ifndef VSOMEIP_DISABLE_SECURITY bool routing_manager_impl::update_security_policy_configuration( - uint32_t _uid, uint32_t _gid, + uid_t _uid, gid_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, const security_update_handler_t &_handler) { @@ -4851,7 +4867,7 @@ routing_manager_impl::update_security_policy_configuration( bool routing_manager_impl::remove_security_policy_configuration( - uint32_t _uid, uint32_t _gid, + uid_t _uid, gid_t _gid, const security_update_handler_t &_handler) { if (stub_) diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index d0015c3f7..a5c7ece86 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -54,9 +54,10 @@ #include "../../protocol/include/update_security_credentials_command.hpp" #include "../../protocol/include/update_security_policy_command.hpp" #include "../../protocol/include/update_security_policy_response_command.hpp" +#include "../../protocol/include/config_command.hpp" #include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #include "../../utility/include/utility.hpp" namespace vsomeip_v3 { @@ -346,7 +347,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, its_major = its_command.get_major(); its_minor = its_command.get_minor(); - if (VSOMEIP_SEC_OK == security::is_client_allowed_to_offer( + if (VSOMEIP_SEC_OK == configuration_->get_security()->is_client_allowed_to_offer( _sec_client, its_service, its_instance)) { host_->offer_service(its_client, its_service, its_instance, its_major, its_minor); @@ -412,7 +413,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << " which violates the security policy ~> Skip subscribe!"; } } else { - if (VSOMEIP_SEC_OK == security::is_client_allowed_to_access_member( + if (VSOMEIP_SEC_OK == configuration_->get_security()->is_client_allowed_to_access_member( _sec_client, its_service, its_instance, its_notifier)) { host_->subscribe(its_client, _sec_client, its_service, its_instance, its_eventgroup, its_major, its_notifier, its_filter); @@ -553,15 +554,9 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, auto its_message_data(its_command.get_message()); if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { - its_service = VSOMEIP_BYTES_TO_WORD( - its_message_data[VSOMEIP_SERVICE_POS_MIN], - its_message_data[VSOMEIP_SERVICE_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - its_message_data[VSOMEIP_METHOD_POS_MIN], - its_message_data[VSOMEIP_METHOD_POS_MAX]); - its_client = VSOMEIP_BYTES_TO_WORD( - its_message_data[VSOMEIP_CLIENT_POS_MIN], - its_message_data[VSOMEIP_CLIENT_POS_MAX]); + its_service = bithelper::read_uint16_be(&its_message_data[VSOMEIP_SERVICE_POS_MIN]); + its_method = bithelper::read_uint16_be(&its_message_data[VSOMEIP_METHOD_POS_MIN]); + its_client = bithelper::read_uint16_be(&its_message_data[VSOMEIP_CLIENT_POS_MIN]); its_instance = its_command.get_instance(); is_reliable = its_command.is_reliable(); @@ -570,7 +565,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, // Allow response messages from local proxies as answer to remote requests // but check requests sent by local proxies to remote against policy. if (utility::is_request(its_message_data[VSOMEIP_MESSAGE_TYPE_POS])) { - if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + if (VSOMEIP_SEC_OK != configuration_->get_security()->is_client_allowed_to_access_member( _sec_client, its_service, its_instance, its_method)) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_stub::on_message: " @@ -581,11 +576,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, } } // reduce by size of instance, flush, reliable, client and is_valid_crc flag - auto its_contained_size = VSOMEIP_BYTES_TO_LONG( - its_message_data[VSOMEIP_LENGTH_POS_MIN], - its_message_data[VSOMEIP_LENGTH_POS_MIN+1], - its_message_data[VSOMEIP_LENGTH_POS_MIN+2], - its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + uint32_t its_contained_size = bithelper::read_uint32_be(&its_message_data[VSOMEIP_LENGTH_POS_MIN]); if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; break; @@ -609,16 +600,11 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { its_client = its_command.get_target(); - its_service = VSOMEIP_BYTES_TO_WORD( - its_message_data[VSOMEIP_SERVICE_POS_MIN], - its_message_data[VSOMEIP_SERVICE_POS_MAX]); + its_service = bithelper::read_uint16_be(&its_message_data[VSOMEIP_SERVICE_POS_MIN]); its_instance = its_command.get_instance(); - auto its_contained_size = VSOMEIP_BYTES_TO_LONG( - its_message_data[VSOMEIP_LENGTH_POS_MIN], - its_message_data[VSOMEIP_LENGTH_POS_MIN+1], - its_message_data[VSOMEIP_LENGTH_POS_MIN+2], - its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + uint32_t its_contained_size = bithelper::read_uint32_be(&its_message_data[VSOMEIP_LENGTH_POS_MIN]); + if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!"; break; @@ -643,7 +629,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, std::set its_allowed_requests; for (const auto &r : its_requests) { - if (VSOMEIP_SEC_OK == security::is_client_allowed_to_request( + if (VSOMEIP_SEC_OK == configuration_->get_security()->is_client_allowed_to_request( _sec_client, r.service_, r.instance_)) { host_->request_service(its_client, r.service_, r.instance_, r.major_, r.minor_); @@ -809,6 +795,20 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, break; } #endif // !VSOMEIP_DISABLE_SECURITY + case protocol::id_e::CONFIG_ID: { + protocol::config_command its_command; + protocol::error_e its_command_error; + its_command.deserialize(its_buffer, its_command_error); + if (its_command_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ << ": config command deserialization failed (" << std::dec + << static_cast(its_command_error) << ")"; + break; + } + if (its_command.contains("hostname")) { + add_known_client(its_command.get_client(), its_command.at("hostname")); + } + break; + } default: VSOMEIP_WARNING << __func__ << ": Received an unhandled command (" << std::dec << static_cast(its_id) << ")"; @@ -825,6 +825,8 @@ void routing_manager_stub::on_register_application(client_t _client) { if (endpoint) { VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client << ". Last registration might have been taken too long."; + endpoint->stop(); + endpoint->start(); } else { endpoint = host_->find_or_create_local(_client); { @@ -836,7 +838,7 @@ void routing_manager_stub::on_register_application(client_t _client) { vsomeip_sec_client_t its_sec_client; std::set > its_policies; - bool has_mapping = policy_manager_impl::get() + bool has_mapping = configuration_->get_policy_manager() ->get_client_to_sec_client_mapping(_client, its_sec_client); if (has_mapping) { if (its_sec_client.port == VSOMEIP_SEC_PORT_UNUSED) { @@ -1128,7 +1130,7 @@ void routing_manager_stub::on_stop_offer_service(client_t _client, } void routing_manager_stub::send_client_credentials(const client_t _target, - std::set> &_credentials) { + std::set> &_credentials) { std::shared_ptr its_endpoint = host_->find_local(_target); if (its_endpoint) { @@ -1207,7 +1209,7 @@ void routing_manager_stub::send_client_routing_info(const client_t _target, } void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _service, instance_t _instance) { - std::set> its_credentials; + std::set> its_credentials; std::set its_requesting_clients; // search for clients which shall receive the credentials for (auto its_requesting_client : service_requests_) { @@ -1222,14 +1224,14 @@ void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _s // search for UID / GID linked with the client ID that offers the requested services vsomeip_sec_client_t its_sec_client; - if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_hoster, its_sec_client)) { - std::pair its_uid_gid; + if (configuration_->get_policy_manager()->get_client_to_sec_client_mapping(_hoster, its_sec_client)) { + std::pair its_uid_gid; its_uid_gid.first = its_sec_client.user; its_uid_gid.second = its_sec_client.group; its_credentials.insert(its_uid_gid); for (auto its_requesting_client : its_requesting_clients) { vsomeip_sec_client_t its_requester_sec_client; - if (policy_manager_impl::get()->get_client_to_sec_client_mapping( + if (configuration_->get_policy_manager()->get_client_to_sec_client_mapping( its_requesting_client, its_requester_sec_client)) { if (!utility::compare(its_sec_client, its_requester_sec_client)) send_client_credentials(its_requesting_client, its_credentials); @@ -1597,8 +1599,8 @@ void routing_manager_stub::create_local_receiver() { if (local_receiver_) { return; } -#if defined(__linux__) || defined(ANDROID) - else if (!policy_manager_impl::get()->check_credentials(get_client(), host_->get_sec_client())) { +#ifdef __linux__ + else if (!configuration_->get_policy_manager()->check_credentials(get_client(), host_->get_sec_client())) { VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_stub::create_local_receiver: isn't allowed" << " to create a server endpoint due to credential check failed!"; @@ -1794,7 +1796,7 @@ void routing_manager_stub::update_registration(client_t _client, "registering." : "deregistering."); if (_type != registration_type_e::REGISTER) { - policy_manager_impl::get()->remove_client_to_sec_client_mapping(_client); + configuration_->get_policy_manager()->remove_client_to_sec_client_mapping(_client); } else { if (_port > 0 && _port < ILLEGAL_PORT) host_->add_guest(_client, _address, _port); @@ -1843,9 +1845,9 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set

its_guard(routing_info_mutex_); - std::set> its_credentials; + std::set> its_credentials; vsomeip_sec_client_t its_requester_sec_client; - if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_requester_sec_client)) { + if (configuration_->get_policy_manager()->get_client_to_sec_client_mapping(_client, its_requester_sec_client)) { // determine credentials of offering clients using current routing info std::set its_offering_clients; @@ -1861,7 +1863,7 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set

get_client_to_sec_client_mapping(its_offering_client, its_sec_client)) { + if (configuration_->get_policy_manager()->get_client_to_sec_client_mapping(its_offering_client, its_sec_client)) { if (its_sec_client.port == VSOMEIP_SEC_PORT_UNUSED && !utility::compare(its_sec_client, its_requester_sec_client)) { @@ -2051,7 +2053,7 @@ bool routing_manager_stub::send_provided_event_resend_request( } #ifndef VSOMEIP_DISABLE_SECURITY -bool routing_manager_stub::is_policy_cached(uint32_t _uid) { +bool routing_manager_stub::is_policy_cached(uid_t _uid) { { std::lock_guard its_lock(updated_security_policies_mutex_); if (updated_security_policies_.find(_uid) @@ -2065,7 +2067,7 @@ bool routing_manager_stub::is_policy_cached(uint32_t _uid) { } } -void routing_manager_stub::policy_cache_add(uint32_t _uid, const std::shared_ptr& _payload) { +void routing_manager_stub::policy_cache_add(uid_t _uid, const std::shared_ptr& _payload) { // cache security policy payload for later distribution to new registering clients { std::lock_guard its_lock(updated_security_policies_mutex_); @@ -2073,7 +2075,7 @@ void routing_manager_stub::policy_cache_add(uint32_t _uid, const std::shared_ptr } } -void routing_manager_stub::policy_cache_remove(uint32_t _uid) { +void routing_manager_stub::policy_cache_remove(uid_t _uid) { { std::lock_guard its_lock(updated_security_policies_mutex_); updated_security_policies_.erase(_uid); @@ -2081,7 +2083,7 @@ void routing_manager_stub::policy_cache_remove(uint32_t _uid) { } bool routing_manager_stub::send_update_security_policy_request(client_t _client, pending_security_update_id_t _update_id, - uint32_t _uid, const std::shared_ptr& _payload) { + uid_t _uid, const std::shared_ptr& _payload) { (void)_uid; std::shared_ptr its_endpoint = host_->find_local(_client); @@ -2161,7 +2163,7 @@ bool routing_manager_stub::send_cached_security_policies(client_t _client) { bool routing_manager_stub::send_remove_security_policy_request( client_t _client, pending_security_update_id_t _update_id, - uint32_t _uid, uint32_t _gid) { + uid_t _uid, gid_t _gid) { protocol::remove_security_policy_command its_command; its_command.set_client(_client); @@ -2212,7 +2214,7 @@ routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid, // Check whether clients with uid/gid are already registered. // If yes, update their policy std::unordered_set its_clients; - policy_manager_impl::get()->get_clients(_uid, _gid, its_clients); + configuration_->get_policy_manager()->get_clients(_uid, _gid, its_clients); if (!its_clients.empty()) return send_requester_policies(its_clients, _policies); @@ -2299,17 +2301,15 @@ routing_manager_stub::send_requester_policies(const std::unordered_set its_message.push_back(0); uint32_t its_policy_size = static_cast(its_policy_data.size() + sizeof(uint32_t)); - its_message.push_back(VSOMEIP_LONG_BYTE0(its_policy_size)); - its_message.push_back(VSOMEIP_LONG_BYTE1(its_policy_size)); - its_message.push_back(VSOMEIP_LONG_BYTE2(its_policy_size)); - its_message.push_back(VSOMEIP_LONG_BYTE3(its_policy_size)); - its_policy_id = pending_security_update_add(_clients); - its_message.push_back(VSOMEIP_LONG_BYTE0(its_policy_id)); - its_message.push_back(VSOMEIP_LONG_BYTE1(its_policy_id)); - its_message.push_back(VSOMEIP_LONG_BYTE2(its_policy_id)); - its_message.push_back(VSOMEIP_LONG_BYTE3(its_policy_id)); + uint8_t new_its_policy_size[4] = {0}; + bithelper::write_uint32_le(its_policy_size, new_its_policy_size); + its_message.insert(its_message.end(), new_its_policy_size, new_its_policy_size + sizeof(new_its_policy_size)); + its_policy_id = pending_security_update_add(_clients); + uint8_t new_its_policy_id[4] = {0}; + bithelper::write_uint32_le(its_policy_id, new_its_policy_id); + its_message.insert(its_message.end(), new_its_policy_id, new_its_policy_id + sizeof(new_its_policy_id)); its_message.insert(its_message.end(), its_policy_data.begin(), its_policy_data.end()); for (const auto c : _clients) { @@ -2380,7 +2380,7 @@ void routing_manager_stub::on_security_update_timeout( } bool routing_manager_stub::update_security_policy_configuration( - uint32_t _uid, uint32_t _gid, + uid_t _uid, gid_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, const security_update_handler_t &_handler) { @@ -2391,11 +2391,11 @@ bool routing_manager_stub::update_security_policy_configuration( policy_cache_add(_uid, _payload); // update security policy from configuration - policy_manager_impl::get()->update_security_policy(_uid, _gid, _policy); + configuration_->get_policy_manager()->update_security_policy(_uid, _gid, _policy); // Build requester policies for the services offered by the new policy std::set > its_requesters; - policy_manager_impl::get()->get_requester_policies(_policy, its_requesters); + configuration_->get_policy_manager()->get_requester_policies(_policy, its_requesters); // and add them to the requester policy cache add_requester_policies(_uid, _gid, its_requesters); @@ -2448,13 +2448,13 @@ bool routing_manager_stub::update_security_policy_configuration( } bool routing_manager_stub::remove_security_policy_configuration( - uint32_t _uid, uint32_t _gid, const security_update_handler_t &_handler) { + uid_t _uid, gid_t _gid, const security_update_handler_t &_handler) { bool ret(true); // remove security policy from configuration (only if there was a updateACL call before) if (is_policy_cached(_uid)) { - if (!policy_manager_impl::get()->remove_security_policy(_uid, _gid)) { + if (!configuration_->get_policy_manager()->remove_security_policy(_uid, _gid)) { _handler(security_update_state_e::SU_UNKNOWN_USER_ID); ret = false; } else { @@ -2619,6 +2619,10 @@ void routing_manager_stub::send_suspend() const { << std::dec << int(its_error) << ")"; } +routing_state_e routing_manager_stub::get_routing_state() { + return host_->get_routing_state(); +} + void routing_manager_stub::remove_subscriptions(port_t _local_port, const boost::asio::ip::address &_remote_address, diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp index fc099678e..51afab567 100644 --- a/implementation/routing/src/serviceinfo.cpp +++ b/implementation/routing/src/serviceinfo.cpp @@ -7,18 +7,12 @@ namespace vsomeip_v3 { -serviceinfo::serviceinfo(service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor, - ttl_t _ttl, bool _is_local) - : service_(_service), - instance_(_instance), - major_(_major), - minor_(_minor), - ttl_(0), - reliable_(nullptr), - unreliable_(nullptr), - is_local_(_is_local), - is_in_mainphase_(false) { +serviceinfo::serviceinfo(service_t _service, instance_t _instance, major_version_t _major, + minor_version_t _minor, ttl_t _ttl, bool _is_local) : + service_(_service), + instance_(_instance), major_(_major), minor_(_minor), ttl_(0), reliable_(nullptr), + unreliable_(nullptr), is_local_(_is_local), is_in_mainphase_(false), + accepting_remote_subscription_(false) { std::chrono::seconds ttl = static_cast (_ttl); ttl_ = std::chrono::duration_cast(ttl); @@ -120,4 +114,26 @@ void serviceinfo::set_is_in_mainphase(bool _in_mainphase) { is_in_mainphase_ = _in_mainphase; } +bool serviceinfo::is_accepting_remote_subscriptions() const { + return accepting_remote_subscription_; +} + +void serviceinfo::set_accepting_remote_subscriptions(bool _accepting_remote_subscriptions) { + accepting_remote_subscription_ = _accepting_remote_subscriptions; + if (!_accepting_remote_subscriptions) { + std::lock_guard its_lock(accepting_remote_mutex); + accepting_remote_subscription_from_.clear(); + } +} + +void serviceinfo::add_remote_ip(std::string _remote_ip) { + std::lock_guard its_lock(accepting_remote_mutex); + accepting_remote_subscription_from_.insert(_remote_ip); +} + +std::set> serviceinfo::get_remote_ip_accepting_sub() { + std::lock_guard its_lock(accepting_remote_mutex); + return accepting_remote_subscription_from_; +} + } // namespace vsomeip_v3 diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index c647b5316..082c21471 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -8,18 +8,25 @@ #include #include +#include #include +#include #include #include #include #include #include +#include #include +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include +#include +#endif -#if VSOMEIP_BOOST_VERSION >= 106600 #include -#endif #include #include #include @@ -148,6 +155,7 @@ class application_impl: public application, VSOMEIP_EXPORT void set_sec_client_port(port_t _port); VSOMEIP_EXPORT diagnosis_t get_diagnosis() const; VSOMEIP_EXPORT std::shared_ptr get_configuration() const; + VSOMEIP_EXPORT std::shared_ptr get_policy_manager() const; VSOMEIP_EXPORT std::shared_ptr get_public_configuration() const; VSOMEIP_EXPORT boost::asio::io_context &get_io(); @@ -237,12 +245,15 @@ class application_impl: public application, handler_registration_type_e _type); private: - using members_methods_t = std::map >; - using members_methods_iterator_t = members_methods_t::const_iterator; - using members_instances_t = std::map; - using members_instances_iterator_t = members_instances_t::const_iterator; - using members_t = std::map; - using members_iterator_t = members_t::const_iterator; + + using members_key_t = std::uint64_t; + using members_t = std::unordered_map>; + + static members_key_t to_members_key(service_t _service, instance_t _instance, method_t _method) { + return (static_cast(_service) << 0) | + (static_cast(_instance) << 16) | + (static_cast(_method) << 32); + } // // Types @@ -299,10 +310,9 @@ class application_impl: public application, major_version_t _major, minor_version_t _minor) const; void register_availability_handler_unlocked(service_t _service, - instance_t _instance, availability_state_handler_t _handler, + instance_t _instance, const availability_state_handler_t &_handler, major_version_t _major, minor_version_t _minor); - void main_dispatch(); void dispatch(); void invoke_handler(std::shared_ptr &_handler); @@ -337,12 +347,24 @@ class application_impl: public application, bool is_local_endpoint(const boost::asio::ip::address &_unicast, port_t _port); - void find_service_handlers(std::deque &, - service_t _service, instance_t _instance, method_t _method) const; - void find_instance_handlers(std::deque &, - const members_iterator_t &_it, instance_t _instance, method_t _method) const; - void find_method_handlers(std::deque &, - const members_instances_iterator_t &_it, method_t _method) const; + const std::deque& find_handlers(service_t _service, instance_t _instance, method_t _method) const; + + void invoke_availability_handler(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor); + + void increment_active_threads(); + void decrement_active_threads(); + std::uint16_t get_active_threads() const; + + using availability_state_t = std::map>>>; + + availability_state_e get_availability_state(const availability_state_t& _availability_state, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) const; + void set_availability_state(availability_state_t& _availability_state, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, availability_state_e _state) const; // // Attributes @@ -362,12 +384,8 @@ class application_impl: public application, boost::asio::io_context io_; std::set > io_threads_; -#if VSOMEIP_BOOST_VERSION >= 106600 std::shared_ptr > work_; -#else - std::shared_ptr work_; -#endif // Proxy to or the Routing Manager itself std::shared_ptr routing_; @@ -391,8 +409,9 @@ class application_impl: public application, mutable std::mutex members_mutex_; // Availability handlers - typedef std::map>> availability_major_minor_t; + using stateful_availability_t = std::pair; + using availability_major_minor_t = + std::map>; std::map> availability_; mutable std::mutex availability_mutex_; @@ -438,11 +457,23 @@ class application_impl: public application, // Mutex to protect access to dispatchers_ & elapsed_dispatchers_ mutable std::mutex dispatcher_mutex_; + // Map of promises/futures to check status of dispatcher threads +#ifdef _WIN32 + std::map>> dispatchers_control_; +#else + std::map>> dispatchers_control_; +#endif + // Condition to wakeup the dispatcher thread mutable std::condition_variable dispatcher_condition_; std::size_t max_dispatchers_; std::size_t max_dispatch_time_; + // Counter for dispatcher threads + std::atomic dispatcher_counter_; + + std::size_t max_detached_thread_wait_time; + std::condition_variable stop_cv_; std::mutex start_stop_mutex_; bool stopped_; @@ -450,7 +481,7 @@ class application_impl: public application, std::condition_variable block_stop_cv_; std::mutex block_stop_mutex_; - bool block_stopping_; + std::atomic_bool block_stopping_; static uint32_t app_counter__; static std::mutex app_counter_mutex__; @@ -478,7 +509,7 @@ class application_impl: public application, std::map > > - > subscription_state_; + > subscriptions_state_; std::mutex watchdog_timer_mutex_; boost::asio::steady_timer watchdog_timer_; diff --git a/implementation/runtime/include/runtime_impl.hpp b/implementation/runtime/include/runtime_impl.hpp index b618ec473..2c4ed5b52 100644 --- a/implementation/runtime/include/runtime_impl.hpp +++ b/implementation/runtime/include/runtime_impl.hpp @@ -20,7 +20,7 @@ class runtime_impl: public runtime { static std::shared_ptr get(); - virtual ~runtime_impl(); + virtual ~runtime_impl() = default; std::shared_ptr create_application( const std::string &_name); diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index db880b42d..e632770ab 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -48,41 +48,43 @@ configuration::~configuration() {} uint32_t application_impl::app_counter__ = 0; std::mutex application_impl::app_counter_mutex__; -application_impl::application_impl(const std::string &_name, const std::string &_path) - : runtime_(runtime::get()), - client_(VSOMEIP_CLIENT_UNSET), - session_(0), - is_initialized_(false), - name_(_name), - path_(_path), -#if VSOMEIP_BOOST_VERSION >= 106600 - work_(std::make_shared >(io_.get_executor())), -#else - work_(std::make_shared(io_)), -#endif - routing_(0), - state_(state_type_e::ST_DEREGISTERED), - security_mode_(security_mode_e::SM_ON), +application_impl::application_impl(const std::string& _name, const std::string& _path) : + runtime_(runtime::get()), client_(VSOMEIP_CLIENT_UNSET), session_(0), is_initialized_(false), + name_(_name), path_(_path), + work_(std::make_shared< + boost::asio::executor_work_guard>( + io_.get_executor())), + routing_(nullptr), state_(state_type_e::ST_DEREGISTERED), + security_mode_(security_mode_e::SM_ON), #ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING - signals_(io_, SIGINT, SIGTERM), - catched_signal_(false), + signals_(io_, SIGINT, SIGTERM), catched_signal_(false), #endif - is_dispatching_(false), - max_dispatchers_(VSOMEIP_MAX_DISPATCHERS), - max_dispatch_time_(VSOMEIP_MAX_DISPATCH_TIME), - stopped_(false), - block_stopping_(false), - is_routing_manager_host_(false), - stopped_called_(false), - watchdog_timer_(io_), - client_side_logging_(false), - has_session_handling_(true) -{ + is_dispatching_(false), max_dispatchers_(VSOMEIP_MAX_DISPATCHERS), + max_dispatch_time_(VSOMEIP_MAX_DISPATCH_TIME), dispatcher_counter_(0), + max_detached_thread_wait_time(VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS), stopped_(false), + block_stopping_(false), is_routing_manager_host_(false), stopped_called_(false), + watchdog_timer_(io_), client_side_logging_(false), has_session_handling_(true) { } application_impl::~application_impl() { runtime_->remove_application(name_); + +#ifndef VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS + if(configuration_) { + auto its_plugin = plugin_manager::get()->get_plugin( + plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); + if (its_plugin) { + auto its_configuration_plugin + = std::dynamic_pointer_cast(its_plugin); + if (its_configuration_plugin) { + bool its_removed = its_configuration_plugin->remove_configuration(name_); + if (!its_removed) { + VSOMEIP_WARNING << __func__ <<": Unable to remove configuration entry stored for " << name_; + } + } + } + } +#endif try { if (stop_thread_.joinable()) { stop_thread_.detach(); @@ -178,11 +180,7 @@ bool application_impl::init() { } else { auto its_guest_address = configuration_->get_routing_guest_address(); if (its_guest_address.is_v4()) { -#if VSOMEIP_BOOST_VERSION < 106600 - sec_client_.host = htonl(static_cast(its_guest_address.to_v4().to_ulong())); -#else sec_client_.host = htonl(its_guest_address.to_v4().to_uint()); -#endif } sec_client_.port = VSOMEIP_SEC_PORT_UNSET; } @@ -190,9 +188,9 @@ bool application_impl::init() { // Set security mode if (configuration_->is_security_enabled()) { if (configuration_->is_security_external()) { - if (security::load()) { + if (configuration_->get_security()->load()) { VSOMEIP_INFO << "Using external security implementation!"; - auto its_result = security::initialize(); + auto its_result = configuration_->get_security()->initialize(); if (VSOMEIP_SEC_POLICY_OK != its_result) VSOMEIP_ERROR << "Intializing external security implementation failed (" << std::dec << its_result << ')'; @@ -264,6 +262,7 @@ bool application_impl::init() { // the main dispatcher max_dispatchers_ = its_configuration->get_max_dispatchers(name_) + 1; max_dispatch_time_ = its_configuration->get_max_dispatch_time(name_); + max_detached_thread_wait_time = its_configuration->get_max_detached_thread_wait_time(name_); has_session_handling_ = its_configuration->has_session_handling(name_); if (!has_session_handling_) @@ -425,10 +424,21 @@ void application_impl::start() { { std::lock_guard its_lock(dispatcher_mutex_); is_dispatching_ = true; - auto its_main_dispatcher = std::make_shared( - &application_impl::main_dispatch, shared_from_this() - ); + std::packaged_task dispatcher_task_( + std::bind(&application_impl::main_dispatch, shared_from_this())); + std::future dispatcher_future_ = dispatcher_task_.get_future(); + auto its_main_dispatcher = std::make_shared(std::move(dispatcher_task_)); +#ifdef _WIN32 + dispatchers_control_[its_main_dispatcher->get_id()] = { + OpenThread(THREAD_ALL_ACCESS, false, + GetThreadId(its_main_dispatcher->native_handle())), + std::move(dispatcher_future_)}; +#else + dispatchers_control_[its_main_dispatcher->get_id()] = { + its_main_dispatcher->native_handle(), std::move(dispatcher_future_)}; +#endif dispatchers_[its_main_dispatcher->get_id()] = its_main_dispatcher; + increment_active_threads(); } if (stop_thread_.joinable()) { @@ -440,8 +450,7 @@ void application_impl::start() { routing_->start(); for (size_t i = 0; i < io_thread_count - 1; i++) { - std::shared_ptr its_thread - = std::make_shared([this, i, io_thread_nice_level] { + auto its_thread = std::make_shared([this, i, io_thread_nice_level] { VSOMEIP_INFO << "io thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex @@ -457,9 +466,7 @@ void application_impl::start() { << client_ << "_io" << std::setw(2) << i+1; pthread_setname_np(pthread_self(),s.str().c_str()); } - if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) { - VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id(); - } + utility::set_thread_niceness(io_thread_nice_level); #endif while(true) { try { @@ -486,12 +493,11 @@ void application_impl::start() { on_application_state_change(name_, application_plugin_state_e::STATE_STARTED); } } - } - - app_counter_mutex__.lock(); - app_counter__++; - app_counter_mutex__.unlock(); + { + std::lock_guard its_app_lock(app_counter_mutex__); + app_counter__++; + } VSOMEIP_INFO << "io thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::this_thread::get_id() @@ -499,11 +505,7 @@ void application_impl::start() { << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; -#if defined(__linux__) || defined(ANDROID) - if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) { - VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id(); - } -#endif + utility::set_thread_niceness(io_thread_nice_level); while(true) { try { io_.run(); @@ -515,7 +517,6 @@ void application_impl::start() { VSOMEIP_ERROR << "application_impl::start() caught exception: " << e.what(); } } - { std::lock_guard its_lock_start_stop(block_stop_mutex_); block_stopping_ = true; @@ -526,18 +527,10 @@ void application_impl::start() { std::lock_guard its_lock(start_stop_mutex_); stopped_ = false; } - - app_counter_mutex__.lock(); - app_counter__--; - -#ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING - if (catched_signal_ && !app_counter__) { - app_counter_mutex__.unlock(); - VSOMEIP_INFO << "Exiting vsomeip application..."; - exit(0); + { + std::lock_guard its_app_lock(app_counter_mutex__); + app_counter__--; } -#endif - app_counter_mutex__.unlock(); } void application_impl::stop() { @@ -563,18 +556,21 @@ void application_impl::stop() { block = false; } } - auto its_plugins = configuration_->get_plugins(name_); - auto its_app_plugin_info = its_plugins.find(plugin_type_e::APPLICATION_PLUGIN); - if (its_app_plugin_info != its_plugins.end()) { - for (const auto& its_library : its_app_plugin_info->second) { - auto its_application_plugin = plugin_manager::get()->get_plugin( - plugin_type_e::APPLICATION_PLUGIN, its_library); - if (its_application_plugin) { - std::dynamic_pointer_cast(its_application_plugin)-> - on_application_state_change(name_, application_plugin_state_e::STATE_STOPPED); + + if (configuration_) { + auto its_plugins = configuration_->get_plugins(name_); + auto its_app_plugin_info = its_plugins.find(plugin_type_e::APPLICATION_PLUGIN); + if (its_app_plugin_info != its_plugins.end()) { + for (const auto& its_library : its_app_plugin_info->second) { + auto its_application_plugin = plugin_manager::get()->get_plugin( + plugin_type_e::APPLICATION_PLUGIN, its_library); + if (its_application_plugin) { + std::dynamic_pointer_cast(its_application_plugin)-> + on_application_state_change(name_, application_plugin_state_e::STATE_STOPPED); + } } - } + } } { @@ -584,9 +580,8 @@ void application_impl::stop() { if (block) { std::unique_lock block_stop_lock(block_stop_mutex_); - while (!block_stopping_) { - block_stop_cv_.wait(block_stop_lock); - } + block_stop_cv_.wait_for(block_stop_lock, std::chrono::milliseconds(1000), + [this] { return block_stopping_.load(); }); block_stopping_ = false; } } @@ -614,12 +609,23 @@ void application_impl::stop_offer_service(service_t _service, instance_t _instan void application_impl::request_service(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { + invoke_availability_handler(_service, _instance, _major, _minor); if (routing_) routing_->request_service(client_, _service, _instance, _major, _minor); } void application_impl::release_service(service_t _service, instance_t _instance) { + { + std::lock_guard its_subscriptions_state_guard(subscriptions_state_mutex_); + auto found_service = subscriptions_state_.find(_service); + if (found_service != subscriptions_state_.end()) { + found_service->second.erase(_instance); + if (found_service->second.empty()) { + subscriptions_state_.erase(_service); + } + } + } if (routing_) routing_->release_service(client_, _service, _instance); } @@ -899,20 +905,25 @@ void application_impl::send(std::shared_ptr _message) { void application_impl::notify(service_t _service, instance_t _instance, event_t _event, std::shared_ptr _payload, bool _force) const { - if (routing_) - routing_->notify(_service, _instance, _event, _payload, _force); + if (routing_) { + auto its_payload { + runtime::get()->create_payload(_payload->get_data(), _payload->get_length())}; + routing_->notify(_service, _instance, _event, its_payload, _force); + } } void application_impl::notify_one(service_t _service, instance_t _instance, event_t _event, std::shared_ptr _payload, client_t _client, bool _force) const { if (routing_) { - routing_->notify_one(_service, _instance, _event, _payload, _client, - _force + auto its_payload { + runtime::get()->create_payload(_payload->get_data(), _payload->get_length())}; + routing_->notify_one(_service, _instance, _event, its_payload, _client, _force #ifdef VSOMEIP_ENABLE_COMPAT - , false + , + false #endif - ); + ); } } @@ -950,34 +961,73 @@ void application_impl::register_availability_handler(service_t _service, _handler, _major, _minor); } +void application_impl::invoke_availability_handler( + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + std::lock_guard availability_lock(availability_mutex_); + auto found_service = availability_.find(_service); + if (found_service != availability_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_major = found_instance->second.find(_major); + if (found_major == found_instance->second.end()) { + found_major = found_instance->second.find(ANY_MAJOR); + } + if (found_major != found_instance->second.end()) { + auto found_minor = found_major->second.find(_minor); + if (found_minor == found_major->second.end()) { + found_minor = found_major->second.find(ANY_MINOR); + } + if (found_minor != found_major->second.end()) { + auto its_state { is_available_unlocked(_service, _instance, _major, _minor) }; + if (availability_state_e::AS_UNKNOWN != its_state + && get_availability_state(found_minor->second.second, + _service, _instance, _major, _minor) + != its_state) { + auto its_handler {found_minor->second.first}; + set_availability_state(found_minor->second.second, _service, _instance, + _major, _minor, its_state); + + std::lock_guard handlers_lock(handlers_mutex_); + auto its_sync_handler = std::make_shared( + [its_handler, _service, _instance, its_state]() { + its_handler(_service, _instance, its_state); + }); + its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; + its_sync_handler->service_id_ = _service; + its_sync_handler->instance_id_ = _instance; + handlers_.push_back(its_sync_handler); + dispatcher_condition_.notify_one(); + } + } + } + } + } +} + void application_impl::register_availability_handler_unlocked(service_t _service, - instance_t _instance, availability_state_handler_t _handler, + instance_t _instance, const availability_state_handler_t &_handler, major_version_t _major, minor_version_t _minor) { - if (state_ == state_type_e::ST_REGISTERED) { - available_t its_available; - auto are_available = are_available_unlocked(its_available, _service, _instance, _major, _minor); - availability_[_service][_instance][_major][_minor] - = std::make_pair(_handler, true); + auto its_state {is_available_unlocked(_service, _instance, _major, _minor)}; - std::lock_guard handlers_lock(handlers_mutex_); + availability_state_t its_availability_state; + set_availability_state(its_availability_state, _service, _instance, _major, _minor, its_state); - std::shared_ptr its_sync_handler - = std::make_shared([_handler, are_available, its_available]() { - for(const auto& available_services_it : its_available) - for(const auto& available_instances_it : available_services_it.second) - _handler(available_services_it.first, available_instances_it.first, are_available); - }); - its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; - its_sync_handler->service_id_ = _service; - its_sync_handler->instance_id_ = _instance; - handlers_.push_back(its_sync_handler); + availability_[_service][_instance][_major][_minor] = + std::make_pair(_handler, its_availability_state); - dispatcher_condition_.notify_one(); - } else { - availability_[_service][_instance][_major][_minor] - = std::make_pair(_handler, false); - } + std::scoped_lock handlers_lock(handlers_mutex_); + auto its_sync_handler = + std::make_shared([_handler, _service, _instance, its_state]() { + _handler(_service, _instance, its_state); + }); + its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; + its_sync_handler->service_id_ = _service; + its_sync_handler->instance_id_ = _instance; + handlers_.push_back(its_sync_handler); + dispatcher_condition_.notify_one(); } void application_impl::unregister_availability_handler(service_t _service, @@ -1116,25 +1166,25 @@ void application_impl::on_subscription_status( bool entry_found(false); { std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_service = subscription_state_.find(_service); - if (its_service == subscription_state_.end()) - its_service = subscription_state_.find(ANY_SERVICE); - - if (its_service != subscription_state_.end()) { + auto its_service = subscriptions_state_.find(_service); + if (its_service == subscriptions_state_.end()) { + its_service = subscriptions_state_.find(ANY_SERVICE); + } + if (its_service != subscriptions_state_.end()) { auto its_instance = its_service->second.find(_instance); - if (its_instance == its_service->second.end()) + if (its_instance == its_service->second.end()) { its_instance = its_service->second.find(ANY_INSTANCE); - + } if (its_instance != its_service->second.end()) { auto its_eventgroup = its_instance->second.find(_eventgroup); - if (its_eventgroup == its_instance->second.end()) + if (its_eventgroup == its_instance->second.end()) { its_eventgroup = its_instance->second.find(ANY_EVENTGROUP); - + } if (its_eventgroup != its_instance->second.end()) { auto its_event = its_eventgroup->second.find(_event); - if (its_event == its_eventgroup->second.end()) + if (its_event == its_eventgroup->second.end()) { its_event = its_eventgroup->second.find(ANY_EVENT); - + } if (its_event != its_eventgroup->second.end()) { entry_found = true; its_event->second = (_error ? @@ -1305,8 +1355,7 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t { std::unique_lock handlers_lock(handlers_mutex_); for (auto &handler : handlers) { - std::shared_ptr its_sync_handler - = std::make_shared([handler, _service, + auto its_sync_handler = std::make_shared([handler, _service, _instance, _eventgroup, _event, _error]() { handler(_service, _instance, @@ -1379,16 +1428,7 @@ void application_impl::register_message_handler(service_t _service, void application_impl::unregister_message_handler(service_t _service, instance_t _instance, method_t _method) { std::lock_guard its_lock(members_mutex_); - auto found_service = members_.find(_service); - if (found_service != members_.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - auto found_method = found_instance->second.find(_method); - if (found_method != found_instance->second.end()) { - found_instance->second.erase(_method); - } - } - } + members_.erase(to_members_key(_service, _instance, _method)); } void application_impl::offer_event(service_t _service, instance_t _instance, @@ -1477,7 +1517,6 @@ session_t application_impl::get_session(bool _is_request) { } const vsomeip_sec_client_t *application_impl::get_sec_client() const { - return &sec_client_; } @@ -1490,6 +1529,14 @@ std::shared_ptr application_impl::get_configuration() const { return configuration_; } +std::shared_ptr application_impl::get_policy_manager() const { +#ifndef VSOMEIP_DISABLE_SECURITY + return configuration_->get_policy_manager(); +#endif + VSOMEIP_WARNING << __func__ << ": manager is not available when security is disabled."; + return {}; +} + diagnosis_t application_impl::get_diagnosis() const { return configuration_->get_diagnosis_address(); } @@ -1499,29 +1546,7 @@ boost::asio::io_context &application_impl::get_io() { } void application_impl::on_state(state_type_e _state) { - { - std::lock_guard availability_lock(availability_mutex_); - if (state_ != _state) { - state_ = _state; - if (state_ == state_type_e::ST_REGISTERED) { - for (const auto &its_service : availability_) { - for (const auto &its_instance : its_service.second) { - for (const auto &its_major : its_instance.second) { - for (const auto &its_minor : its_major.second) { - if (!its_minor.second.second) { - register_availability_handler_unlocked( - its_service.first, - its_instance.first, - its_minor.second.first, - its_major.first, its_minor.first); - } - } - } - } - } - } - } - } + bool has_state_handler(false); state_handler_t handler = nullptr; { @@ -1533,8 +1558,7 @@ void application_impl::on_state(state_type_e _state) { } if (has_state_handler) { std::lock_guard its_lock(handlers_mutex_); - std::shared_ptr its_sync_handler - = std::make_shared([handler, _state]() { + auto its_sync_handler = std::make_shared([handler, _state]() { handler(_state); }); its_sync_handler->handler_type_ = handler_type_e::STATE; @@ -1543,6 +1567,36 @@ void application_impl::on_state(state_type_e _state) { } } +availability_state_e +application_impl::get_availability_state(const availability_state_t& _availability_state, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) const { + availability_state_e its_state {availability_state_e::AS_UNKNOWN}; + + if (auto found_service = _availability_state.find(_service); + found_service != _availability_state.end()) { + if (auto found_instance = found_service->second.find(_instance); + found_instance != found_service->second.end()) { + if (auto found_major = found_instance->second.find(_major); + found_major != found_instance->second.end()) { + if (auto found_minor = found_major->second.find(_minor); + found_minor != found_major->second.end()) { + its_state = found_minor->second; + } + } + } + } + + return its_state; +} + +void application_impl::set_availability_state(availability_state_t& _availability_state, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, + availability_state_e _state) const { + _availability_state[_service][_instance][_major][_minor] = _state; +} + void application_impl::on_availability(service_t _service, instance_t _instance, availability_state_e _state, major_version_t _major, minor_version_t _minor) { @@ -1570,31 +1624,51 @@ void application_impl::on_availability(service_t _service, instance_t _instance, } auto find_matching_handler = - [&](const availability_major_minor_t& _av_ma_mi_it) { + [&](availability_major_minor_t& _av_ma_mi_it) { auto found_major = _av_ma_mi_it.find(_major); if (found_major != _av_ma_mi_it.end()) { for (std::int32_t mi = static_cast(_minor); mi >= 0; mi--) { - const auto found_minor = found_major->second.find(static_cast(mi)); + auto found_minor = found_major->second.find(static_cast(mi)); if (found_minor != found_major->second.end()) { - its_handlers.push_back(found_minor->second.first); + if (get_availability_state(found_minor->second.second, _service, _instance, + _major, _minor) != _state) { + its_handlers.push_back(found_minor->second.first); + set_availability_state(found_minor->second.second, _service, _instance, + _major, _minor, _state); + } } } - const auto found_any_minor = found_major->second.find(ANY_MINOR); + auto found_any_minor = found_major->second.find(ANY_MINOR); if (found_any_minor != found_major->second.end()) { - its_handlers.push_back(found_any_minor->second.first); + if (get_availability_state(found_any_minor->second.second, _service, _instance, + _major, _minor) != _state) { + its_handlers.push_back(found_any_minor->second.first); + set_availability_state(found_any_minor->second.second, _service, _instance, + _major, _minor, _state); + } } } found_major = _av_ma_mi_it.find(ANY_MAJOR); if (found_major != _av_ma_mi_it.end()) { for (std::int32_t mi = static_cast(_minor); mi >= 0; mi--) { - const auto found_minor = found_major->second.find(static_cast(mi)); + auto found_minor = found_major->second.find(static_cast(mi)); if (found_minor != found_major->second.end()) { - its_handlers.push_back(found_minor->second.first); + if (get_availability_state(found_minor->second.second, _service, _instance, + _major, _minor) != _state) { + its_handlers.push_back(found_minor->second.first); + set_availability_state(found_minor->second.second, _service, _instance, + _major, _minor, _state); + } } } - const auto found_any_minor = found_major->second.find(ANY_MINOR); + auto found_any_minor = found_major->second.find(ANY_MINOR); if (found_any_minor != found_major->second.end()) { - its_handlers.push_back(found_any_minor->second.first); + if (get_availability_state(found_any_minor->second.second, _service, _instance, + _major, _minor) != _state) { + its_handlers.push_back(found_any_minor->second.first); + set_availability_state(found_any_minor->second.second, _service, _instance, + _major, _minor, _state); + } } } }; @@ -1624,8 +1698,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance, { std::lock_guard handlers_lock(handlers_mutex_); for (const auto &handler : its_handlers) { - std::shared_ptr its_sync_handler = - std::make_shared( + auto its_sync_handler = std::make_shared( [handler, _service, _instance, _state]() { handler(_service, _instance, _state); @@ -1654,8 +1727,8 @@ void application_impl::on_availability(service_t _service, instance_t _instance, } { std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_service = subscription_state_.find(_service); - if (its_service != subscription_state_.end()) { + auto its_service = subscriptions_state_.find(_service); + if (its_service != subscriptions_state_.end()) { auto its_instance = its_service->second.find(_instance); if (its_instance != its_service->second.end()) { for (auto &its_eventgroup : its_instance->second) { @@ -1675,44 +1748,29 @@ void application_impl::on_availability(service_t _service, instance_t _instance, } } -void application_impl::find_service_handlers( - std::deque &_handlers, - service_t _service, instance_t _instance, method_t _method) const { +const std::deque& application_impl::find_handlers(service_t _service, instance_t _instance, method_t _method) const { - auto its_service_it = members_.find(_service); - if (its_service_it != members_.end()) { - find_instance_handlers(_handlers, its_service_it, - _instance, _method); - if (_handlers.empty()) { - find_instance_handlers(_handlers, its_service_it, - ANY_INSTANCE, _method); - } - } -} - -void application_impl::find_instance_handlers( - std::deque &_handlers, - const members_iterator_t &_it, - instance_t _instance, method_t _method) const { + // The (ordered!) sequence of queries to attempt + const std::array queries { + to_members_key(_service, _instance, _method), + to_members_key(_service, _instance, ANY_METHOD), + to_members_key(_service, ANY_INSTANCE, _method), + to_members_key(_service, ANY_INSTANCE, ANY_METHOD), + to_members_key(ANY_SERVICE, _instance, _method), + to_members_key(ANY_SERVICE, _instance, ANY_METHOD), + to_members_key(ANY_SERVICE, ANY_INSTANCE, _method), + to_members_key(ANY_SERVICE, ANY_INSTANCE, ANY_METHOD) + }; - auto its_instance_it = _it->second.find(_instance); - if (its_instance_it != _it->second.end()) { - find_method_handlers(_handlers, its_instance_it, _method); - if (_handlers.empty()) { - find_method_handlers(_handlers, its_instance_it, ANY_METHOD); + for (const auto query : queries) { + const auto& search = members_.find(query); + if (search != members_.end()) { + return search->second; } } -} -void application_impl::find_method_handlers( - std::deque &_handlers, - const members_instances_iterator_t &_it, - method_t _method) const { - - auto its_method_it = _it->second.find(_method); - if (its_method_it != _it->second.end()) { - _handlers = its_method_it->second; - } + static const std::deque empty; + return empty; } void application_impl::on_message(std::shared_ptr &&_message) { @@ -1736,15 +1794,12 @@ void application_impl::on_message(std::shared_ptr &&_message) { { std::lock_guard its_lock(members_mutex_); - std::deque its_handlers; - find_service_handlers(its_handlers, its_service, its_instance, its_method); - if (its_handlers.empty()) - find_service_handlers(its_handlers, ANY_SERVICE, its_instance, its_method); + const auto its_handlers = find_handlers(its_service, its_instance, its_method); - if (its_handlers.size()) { + if (!its_handlers.empty()) { std::lock_guard its_lock(handlers_mutex_); for (const auto &handler : its_handlers) { - std::shared_ptr its_sync_handler = + auto its_sync_handler = std::make_shared([handler, _message]() { handler(_message); }); @@ -1766,6 +1821,7 @@ routing_manager * application_impl::get_routing_manager() const { } void application_impl::main_dispatch() { + utility::set_thread_niceness(configuration_->get_io_thread_nice_level(name_)); #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) { std::stringstream s; @@ -1941,8 +1997,7 @@ void application_impl::reschedule_availability_handler( void application_impl::invoke_handler(std::shared_ptr &_handler) { const std::thread::id its_id = std::this_thread::get_id(); - std::shared_ptr its_sync_handler - = std::make_shared(_handler->service_id_, + auto its_sync_handler = std::make_shared(_handler->service_id_, _handler->instance_id_, _handler->method_id_, _handler->session_id_, _handler->eventgroup_id_, _handler->handler_type_); @@ -1963,9 +2018,24 @@ void application_impl::invoke_handler(std::shared_ptr &_handler) { if (dispatcher_mutex_.try_lock()) { if (dispatchers_.size() < max_dispatchers_) { if (is_dispatching_) { - auto its_dispatcher = std::make_shared( - std::bind(&application_impl::dispatch, shared_from_this())); + std::packaged_task dispatcher_task_( + std::bind(&application_impl::dispatch, shared_from_this())); + std::future dispatcher_future_ = + dispatcher_task_.get_future(); + auto its_dispatcher = + std::make_shared(std::move(dispatcher_task_)); +#ifdef _WIN32 + dispatchers_control_[its_dispatcher->get_id()] = { + OpenThread(THREAD_ALL_ACCESS, false, + GetThreadId(its_dispatcher->native_handle())), + std::move(dispatcher_future_)}; +#else + dispatchers_control_[its_dispatcher->get_id()] = { + its_dispatcher->native_handle(), + std::move(dispatcher_future_)}; +#endif dispatchers_[its_dispatcher->get_id()] = its_dispatcher; + increment_active_threads(); } else { VSOMEIP_INFO << "Won't start new dispatcher " "thread as Client=" << std::hex @@ -2072,9 +2142,12 @@ void application_impl::remove_elapsed_dispatchers() { if (is_dispatching_) { std::lock_guard its_lock(dispatcher_mutex_); for (auto id : elapsed_dispatchers_) { - auto its_dispatcher = dispatchers_.find(id); - if (its_dispatcher->second->joinable()) + if (auto its_dispatcher = dispatchers_.find(id); its_dispatcher->second->joinable()) { + dispatchers_control_.erase(id); its_dispatcher->second->join(); + decrement_active_threads(); + } + dispatchers_.erase(id); } elapsed_dispatchers_.clear(); @@ -2148,7 +2221,9 @@ void application_impl::shutdown() { for (const auto& its_dispatcher : dispatchers_) { if (its_dispatcher.second->get_id() != stop_caller_id_) { if (its_dispatcher.second->joinable()) { + dispatchers_control_.erase(its_dispatcher.second->get_id()); its_dispatcher.second->join(); + decrement_active_threads(); } } else { // If the caller of stop() is one of our dispatchers @@ -2162,6 +2237,7 @@ void application_impl::shutdown() { // after it will return to "main_dispatch" it will be // properly shutdown anyways because "is_dispatching_" // was set to "false" here. + its_dispatcher.second->detach(); } } @@ -2182,6 +2258,65 @@ void application_impl::shutdown() { << " catched exception: " << e.what(); } + try { + while (get_active_threads() > 0) { + auto its_dispatcher_control_ = dispatchers_control_.begin(); + bool os_flag_ = false; + + if (its_dispatcher_control_ != dispatchers_control_.end()) { + if (std::get<1>(its_dispatcher_control_->second) + .wait_for(std::chrono::seconds(max_detached_thread_wait_time)) + == std::future_status::timeout) { + +#ifdef _WIN32 + TerminateThread(std::get<0>(its_dispatcher_control_->second), 0); +#else + pthread_t thread_to_kill = std::get<0>(its_dispatcher_control_->second); + + // Using pthread_cancel for UNIX based systems and pthread_kill(SIGKILL) + // for android since pthread_cancel is not implemented on android. + // The major difference is that pthread_cancel allows for signal handling + // and proper resource cleanup to be done on the application side + // while pthread_kill(SIGKILL) stops the thread immediately. + // This should not however be an issue since this will only be called + // if the thread is already stuck for some time during app->stop() +#if defined(ANDROID) + os_flag_ = true; + if (pthread_kill(thread_to_kill, SIGKILL) != 0) { +#elif defined(__linux__) || defined(__QNX__) + if (pthread_cancel(thread_to_kill) != 0) { +#endif + VSOMEIP_ERROR + << "[OS=" << (os_flag_ ? "ANDROID" : "UNIX") << "] " + << "Failed to kill detached thread with id: " << std::hex + << its_dispatcher_control_->first + << "; Number of threads still active : " << get_active_threads(); + } else { + decrement_active_threads(); + VSOMEIP_INFO + << "[OS=" << (os_flag_ ? "ANDROID" : "UNIX") << "] " + << "Force killed thread with id: " << std::hex + << its_dispatcher_control_->first + << "; Number of threads still active : " << get_active_threads(); + dispatchers_control_.erase(its_dispatcher_control_); + } +#endif + } else { + decrement_active_threads(); + VSOMEIP_INFO << "[OS=" << (os_flag_ ? "ANDROID" : "UNIX") << "] " + << "Detached thread with id: " << std::hex + << its_dispatcher_control_->first << " exited successfully" + << "; Number of threads still active : " << get_active_threads(); + dispatchers_control_.erase(its_dispatcher_control_); + } + } + } + } catch (const std::exception& e) { + VSOMEIP_ERROR << "application_impl::" << __func__ + << ": waiting for detached threads to finish execution, " + << " catched exception: " << e.what(); + } + try { work_.reset(); io_.stop(); @@ -2305,8 +2440,8 @@ void application_impl::remove_subscription(service_t _service, { std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_service = subscription_state_.find(_service); - if (its_service != subscription_state_.end()) { + auto its_service = subscriptions_state_.find(_service); + if (its_service != subscriptions_state_.end()) { auto its_instance = its_service->second.find(_instance); if (its_instance != its_service->second.end()) { if (_event == ANY_EVENT) { @@ -2324,7 +2459,7 @@ void application_impl::remove_subscription(service_t _service, its_service->second.erase(its_instance); } if (its_service->second.empty()) - subscription_state_.erase(its_service); + subscriptions_state_.erase(its_service); } } @@ -2411,8 +2546,8 @@ bool application_impl::check_subscription_state(service_t _service, instance_t _ bool has_found(false); std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_service = subscription_state_.find(_service); - if (its_service != subscription_state_.end()) { + auto its_service = subscriptions_state_.find(_service); + if (its_service != subscriptions_state_.end()) { auto its_instance = its_service->second.find(_instance); if (its_instance != its_service->second.end()) { auto its_eventgroup = its_instance->second.find(_eventgroup); @@ -2435,7 +2570,7 @@ bool application_impl::check_subscription_state(service_t _service, instance_t _ } if (!has_found) { - subscription_state_[_service][_instance][_eventgroup][_event] + subscriptions_state_[_service][_instance][_eventgroup][_event] = subscription_state_e::IS_SUBSCRIBING; } } @@ -2547,8 +2682,7 @@ void application_impl::on_offered_services_info(std::vector its_lock(handlers_mutex_); - std::shared_ptr its_sync_handler - = std::make_shared([handler, _services]() { + auto its_sync_handler = std::make_shared([handler, _services]() { handler(_services); }); its_sync_handler->handler_type_ = handler_type_e::OFFERED_SERVICES_INFO; @@ -2573,8 +2707,7 @@ void application_impl::watchdog_cbk(boost::system::error_code const &_error) { if (handler) { std::lock_guard its_lock(handlers_mutex_); - std::shared_ptr its_sync_handler - = std::make_shared([handler]() { handler(); }); + auto its_sync_handler = std::make_shared([handler]() { handler(); }); its_sync_handler->handler_type_ = handler_type_e::WATCHDOG; handlers_.push_back(its_sync_handler); dispatcher_condition_.notify_one(); @@ -2955,20 +3088,38 @@ void application_impl::register_message_handler_ext( const message_handler_t &_handler, handler_registration_type_e _type) { + const auto key = to_members_key(_service, _instance, _method); + std::lock_guard its_lock(members_mutex_); switch (_type) { case handler_registration_type_e::HRT_REPLACE: - members_[_service][_instance][_method].clear(); + members_[key].clear(); [[gnu::fallthrough]]; case handler_registration_type_e::HRT_APPEND: - members_[_service][_instance][_method].push_back(_handler); + members_[key].push_back(_handler); break; case handler_registration_type_e::HRT_PREPEND: - members_[_service][_instance][_method].push_front(_handler); + members_[key].push_front(_handler); break; default: ; } } +void application_impl::increment_active_threads() { + dispatcher_counter_++; + VSOMEIP_DEBUG << "Thread created. Number of active threads for " << name_ << " : " + << get_active_threads(); +} + +void application_impl::decrement_active_threads() { + dispatcher_counter_--; + VSOMEIP_DEBUG << "Thread destroyed. Number of active threads for " << name_ << " : " + << get_active_threads(); +} + +std::uint16_t application_impl::get_active_threads() const { + return dispatcher_counter_; +} + } // namespace vsomeip_v3 diff --git a/implementation/runtime/src/runtime.cpp b/implementation/runtime/src/runtime.cpp index b2fab889e..b9605f358 100644 --- a/implementation/runtime/src/runtime.cpp +++ b/implementation/runtime/src/runtime.cpp @@ -7,8 +7,12 @@ #include "../include/runtime_impl.hpp" +#include + namespace vsomeip_v3 { +static std::mutex get_mutex_; + std::string runtime::get_property(const std::string &_name) { return runtime_impl::get_property(_name); } @@ -18,6 +22,7 @@ void runtime::set_property(const std::string &_name, const std::string &_value) } std::shared_ptr runtime::get() { + std::scoped_lock lk {get_mutex_}; return runtime_impl::get(); } diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp index bb005aa76..3886f7e22 100644 --- a/implementation/runtime/src/runtime_impl.cpp +++ b/implementation/runtime/src/runtime_impl.cpp @@ -30,33 +30,27 @@ std::shared_ptr runtime_impl::get() { return the_runtime_; } -runtime_impl::~runtime_impl() { -} - -std::shared_ptr runtime_impl::create_application( - const std::string &_name) { +std::shared_ptr runtime_impl::create_application(const std::string& _name) { return create_application(_name, ""); } -std::shared_ptr runtime_impl::create_application( - const std::string &_name, const std::string &_path) { +std::shared_ptr runtime_impl::create_application(const std::string& _name, + const std::string& _path) { + std::scoped_lock its_lock {applications_mutex_}; static std::uint32_t postfix_id = 0; - std::lock_guard its_lock(applications_mutex_); std::string its_name = _name; auto found_application = applications_.find(_name); - if( found_application != applications_.end()) { + if (found_application != applications_.end()) { its_name += "_" + std::to_string(postfix_id++); } - std::shared_ptr application - = std::make_shared(its_name, _path); + std::shared_ptr application = std::make_shared(its_name, _path); applications_[its_name] = application; return application; } std::shared_ptr runtime_impl::create_message(bool _reliable) const { - std::shared_ptr its_message = - std::make_shared(); + auto its_message = std::make_shared(); its_message->set_protocol_version(VSOMEIP_PROTOCOL_VERSION); its_message->set_return_code(return_code_e::E_OK); its_message->set_reliable(_reliable); @@ -65,8 +59,7 @@ std::shared_ptr runtime_impl::create_message(bool _reliable) const { } std::shared_ptr runtime_impl::create_request(bool _reliable) const { - std::shared_ptr its_request = - std::make_shared(); + auto its_request = std::make_shared(); its_request->set_protocol_version(VSOMEIP_PROTOCOL_VERSION); its_request->set_message_type(message_type_e::MT_REQUEST); its_request->set_return_code(return_code_e::E_OK); @@ -77,8 +70,7 @@ std::shared_ptr runtime_impl::create_request(bool _reliable) const { std::shared_ptr runtime_impl::create_response( const std::shared_ptr &_request) const { - std::shared_ptr its_response = - std::make_shared(); + auto its_response = std::make_shared(); its_response->set_service(_request->get_service()); its_response->set_instance(_request->get_instance()); its_response->set_method(_request->get_method()); @@ -93,8 +85,7 @@ std::shared_ptr runtime_impl::create_response( std::shared_ptr runtime_impl::create_notification( bool _reliable) const { - std::shared_ptr its_notification = std::make_shared< - message_impl>(); + auto its_notification = std::make_shared(); its_notification->set_protocol_version(VSOMEIP_PROTOCOL_VERSION); its_notification->set_message_type(message_type_e::MT_NOTIFICATION); its_notification->set_return_code(return_code_e::E_OK); @@ -119,7 +110,7 @@ std::shared_ptr runtime_impl::create_payload( std::shared_ptr runtime_impl::get_application( const std::string &_name) const { - std::lock_guard its_lock(applications_mutex_); + std::scoped_lock its_lock {applications_mutex_}; auto found_application = applications_.find(_name); if(found_application != applications_.end()) return found_application->second.lock(); @@ -128,11 +119,10 @@ std::shared_ptr runtime_impl::get_application( void runtime_impl::remove_application( const std::string &_name) { - std::lock_guard its_lock(applications_mutex_); + std::scoped_lock its_lock {applications_mutex_}; auto found_application = applications_.find(_name); if(found_application != applications_.end()) { applications_.erase(_name); } } - } // namespace vsomeip_v3 diff --git a/implementation/security/include/policy.hpp b/implementation/security/include/policy.hpp index 3c9760c70..fd222430c 100644 --- a/implementation/security/include/policy.hpp +++ b/implementation/security/include/policy.hpp @@ -14,6 +14,9 @@ #include #include +#if defined(__QNX__) +#include +#endif #include #include diff --git a/implementation/security/include/policy_manager_impl.hpp b/implementation/security/include/policy_manager_impl.hpp index 35c1108ca..1b75a5a8d 100644 --- a/implementation/security/include/policy_manager_impl.hpp +++ b/implementation/security/include/policy_manager_impl.hpp @@ -37,8 +37,6 @@ class VSOMEIP_IMPORT_EXPORT policy_manager_impl POLICY_PATH_INEXISTENT = 0x2 }; - static std::shared_ptr get(); - policy_manager_impl(); #ifndef VSOMEIP_DISABLE_SECURITY @@ -47,23 +45,23 @@ class VSOMEIP_IMPORT_EXPORT policy_manager_impl void print_policy(const std::shared_ptr &_policy) const; bool parse_uid_gid(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid) const; + uid_t &_uid, gid_t &_gid) const; bool parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, + uid_t &_uid, gid_t &_gid, const std::shared_ptr &_policy) const; - bool is_policy_update_allowed(uint32_t _uid, + bool is_policy_update_allowed(uid_t _uid, std::shared_ptr &_policy) const; - bool is_policy_removal_allowed(uint32_t _uid) const; + bool is_policy_removal_allowed(uid_t _uid) const; // extension void load(const configuration_element &_element, const bool _lazy_load = false); - void update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr& _policy); - bool remove_security_policy(uint32_t _uid, uint32_t _gid); + void update_security_policy(uid_t _uid, uid_t _gid, const std::shared_ptr& _policy); + bool remove_security_policy(uid_t _uid, uid_t _gid); - void add_security_credentials(uint32_t _uid, uint32_t _gid, + void add_security_credentials(uid_t _uid, uid_t _gid, const std::shared_ptr& _credentials_policy, client_t _client); void get_requester_policies(const std::shared_ptr _policy, @@ -106,7 +104,7 @@ class VSOMEIP_IMPORT_EXPORT policy_manager_impl const vsomeip_sec_client_t *_sec_client); bool check_routing_credentials( const vsomeip_sec_client_t *_sec_client) const; - void set_routing_credentials(uint32_t _uid, uint32_t _gid, + void set_routing_credentials(uid_t _uid, gid_t _gid, const std::string &_name); bool is_client_allowed(const vsomeip_sec_client_t *_sec_client, diff --git a/implementation/security/include/security.hpp b/implementation/security/include/security.hpp index 0eda37f54..5736776fd 100644 --- a/implementation/security/include/security.hpp +++ b/implementation/security/include/security.hpp @@ -6,29 +6,38 @@ #ifndef VSOMEIP_V3_SECURITY_HPP_ #define VSOMEIP_V3_SECURITY_HPP_ +#include +#include + #include #include +#include "policy_manager_impl.hpp" + namespace vsomeip_v3 { class VSOMEIP_IMPORT_EXPORT security { public: - static bool load(); + security(std::shared_ptr _policy_manager); + bool load(); - static decltype(&vsomeip_sec_policy_initialize) initialize; - static decltype(&vsomeip_sec_policy_authenticate_router) authenticate_router; - static decltype(&vsomeip_sec_policy_is_client_allowed_to_offer) is_client_allowed_to_offer; - static decltype(&vsomeip_sec_policy_is_client_allowed_to_request) is_client_allowed_to_request; - static decltype(&vsomeip_sec_policy_is_client_allowed_to_access_member) is_client_allowed_to_access_member; - static decltype(&vsomeip_sec_sync_client) sync_client; + std::function initialize; + std::function authenticate_router; + std::function is_client_allowed_to_offer; + std::function is_client_allowed_to_request; + std::function is_client_allowed_to_access_member; + std::function sync_client; private: - static decltype(vsomeip_sec_policy_initialize) default_initialize; - static decltype(vsomeip_sec_policy_authenticate_router) default_authenticate_router; - static decltype(vsomeip_sec_policy_is_client_allowed_to_offer) default_is_client_allowed_to_offer; - static decltype(vsomeip_sec_policy_is_client_allowed_to_request) default_is_client_allowed_to_request; - static decltype(vsomeip_sec_policy_is_client_allowed_to_access_member) default_is_client_allowed_to_access_member; - static decltype(vsomeip_sec_sync_client) default_sync_client; + + decltype(vsomeip_sec_policy_initialize) default_initialize; + decltype(vsomeip_sec_policy_authenticate_router) default_authenticate_router; + decltype(vsomeip_sec_policy_is_client_allowed_to_offer) default_is_client_allowed_to_offer; + decltype(vsomeip_sec_policy_is_client_allowed_to_request) default_is_client_allowed_to_request; + decltype(vsomeip_sec_policy_is_client_allowed_to_access_member) default_is_client_allowed_to_access_member; + decltype(vsomeip_sec_sync_client) default_sync_client; + + std::shared_ptr policy_manager_; }; } // namespace vsomeip_v3 diff --git a/implementation/security/src/policy.cpp b/implementation/security/src/policy.cpp index da0bbd869..afe84691b 100644 --- a/implementation/security/src/policy.cpp +++ b/implementation/security/src/policy.cpp @@ -3,12 +3,16 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#if __GNUC__ > 11 +#pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif + #include #include #include "../include/policy.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { @@ -40,12 +44,18 @@ policy::deserialize_uid_gid(const byte_t * &_data, uint32_t &_size, bool its_result; - its_result = deserialize_u32(_data, _size, _uid); - if (its_result == false) + uint32_t raw_uid; + its_result = deserialize_u32(_data, _size, raw_uid); + if (its_result) + _uid = static_cast(raw_uid); + else return false; - its_result = deserialize_u32(_data, _size, _gid); - if (its_result == false) + uint32_t raw_gid; + its_result = deserialize_u32(_data, _size, raw_gid); + if (its_result) + _gid = static_cast(raw_gid); + else return false; return true; @@ -268,7 +278,7 @@ policy::deserialize_u16(const byte_t * &_data, uint32_t &_size, if (_size < sizeof(uint16_t)) return false; - _value = VSOMEIP_BYTES_TO_WORD(_data[0], _data[1]); + _value = bithelper::read_uint16_be(_data); _data += sizeof(uint16_t); _size -= static_cast(sizeof(uint16_t)); @@ -283,7 +293,7 @@ policy::deserialize_u32(const byte_t * &_data, uint32_t &_size, if (_size < sizeof(uint32_t)) return false; - _value = VSOMEIP_BYTES_TO_LONG(_data[0], _data[1], _data[2], _data[3]); + _value = bithelper::read_uint32_be(_data); _data += sizeof(uint32_t); _size -= static_cast(sizeof(uint32_t)); @@ -419,28 +429,25 @@ void policy::serialize_u16(uint16_t _value, std::vector &_data) const { - _data.push_back(VSOMEIP_WORD_BYTE1(_value)); - _data.push_back(VSOMEIP_WORD_BYTE0(_value)); + uint8_t new_buffer[2] = {0}; + bithelper::write_uint16_be(_value, new_buffer); + _data.insert(_data.end(), new_buffer, new_buffer + sizeof(new_buffer)); } void policy::serialize_u32(uint32_t _value, std::vector &_data) const { - _data.push_back(VSOMEIP_LONG_BYTE3(_value)); - _data.push_back(VSOMEIP_LONG_BYTE2(_value)); - _data.push_back(VSOMEIP_LONG_BYTE1(_value)); - _data.push_back(VSOMEIP_LONG_BYTE0(_value)); + uint8_t new_buffer[4] = {0}; + bithelper::write_uint32_be(_value, new_buffer); + _data.insert(_data.end(), new_buffer, new_buffer + sizeof(new_buffer)); } void policy::serialize_u32_at(uint32_t _value, std::vector &_data, size_t _pos) const { - _data[_pos] = VSOMEIP_LONG_BYTE3(_value); - _data[_pos+1] = VSOMEIP_LONG_BYTE2(_value); - _data[_pos+2] = VSOMEIP_LONG_BYTE1(_value); - _data[_pos+3] = VSOMEIP_LONG_BYTE0(_value); + bithelper::write_uint32_be(_value, &_data[_pos]); } void diff --git a/implementation/security/src/policy_manager.cpp b/implementation/security/src/policy_manager.cpp deleted file mode 100644 index ad1b52e49..000000000 --- a/implementation/security/src/policy_manager.cpp +++ /dev/null @@ -1,17 +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/policy_manager_impl.hpp" - -#ifndef VSOMEIP_DISABLE_SECURITY -namespace vsomeip_v3 { - -std::shared_ptr -policy_manager::get() { - return policy_manager_impl::get(); -} - -} // namespace vsomeip_v3 -#endif diff --git a/implementation/security/src/policy_manager_impl.cpp b/implementation/security/src/policy_manager_impl.cpp index 2dead74af..e518d27ba 100644 --- a/implementation/security/src/policy_manager_impl.cpp +++ b/implementation/security/src/policy_manager_impl.cpp @@ -111,6 +111,7 @@ policy_manager_impl::check_credentials(client_t _client, has_id = (has_uid && has_gid); if ((has_id && p->allow_who_) || (!has_id && !p->allow_who_)) { + // Code is unaccessible due to logic checks. if (!store_client_to_sec_client_mapping(_client, _sec_client)) { std::string security_mode_text = "!"; if (!check_credentials_) { @@ -186,7 +187,7 @@ policy_manager_impl::check_routing_credentials( } void -policy_manager_impl::set_routing_credentials(uint32_t _uid, uint32_t _gid, +policy_manager_impl::set_routing_credentials(uid_t _uid, gid_t _gid, const std::string &_name) { if (is_configured_) { @@ -416,7 +417,7 @@ policy_manager_impl::load(const configuration_element &_element, const bool _laz } bool -policy_manager_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { +policy_manager_impl::remove_security_policy(uid_t _uid, gid_t _gid) { boost::unique_lock its_lock(any_client_policies_mutex_); bool was_removed(false); if (!any_client_policies_.empty()) { @@ -454,7 +455,7 @@ policy_manager_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { } void -policy_manager_impl::update_security_policy(uint32_t _uid, uint32_t _gid, +policy_manager_impl::update_security_policy(uid_t _uid, gid_t _gid, const std::shared_ptr &_policy) { boost::unique_lock its_lock(any_client_policies_mutex_); @@ -508,7 +509,7 @@ policy_manager_impl::update_security_policy(uint32_t _uid, uint32_t _gid, } void -policy_manager_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, +policy_manager_impl::add_security_credentials(uid_t _uid, gid_t _gid, const std::shared_ptr &_policy, client_t _client) { bool was_found(false); @@ -540,7 +541,7 @@ policy_manager_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, } bool -policy_manager_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const { +policy_manager_impl::is_policy_update_allowed(uid_t _uid, std::shared_ptr &_policy) const { bool is_uid_allowed(false); { @@ -593,7 +594,7 @@ policy_manager_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr its_lock(uid_whitelist_mutex_); for (auto its_uid_range : uid_whitelist_) { if (its_uid_range.lower() <= _uid && _uid <= its_uid_range.upper()) { @@ -615,7 +616,7 @@ policy_manager_impl::is_policy_removal_allowed(uint32_t _uid) const { bool policy_manager_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const { + uid_t &_uid, gid_t &_gid, const std::shared_ptr &_policy) const { bool is_valid = _policy->deserialize(_buffer, _buffer_size); if (is_valid) @@ -1125,9 +1126,8 @@ void policy_manager_impl::get_requester_policies(const std::shared_ptr _policy, std::set > &_requesters) const { - std::lock_guard its_lock(_policy->mutex_); + std::scoped_lock its_lock {any_client_policies_mutex_, _policy->mutex_}; for (const auto &o : _policy->offers_) { - boost::unique_lock its_policies_lock(any_client_policies_mutex_); for (const auto &p : any_client_policies_) { if (p == _policy) continue; @@ -1186,7 +1186,6 @@ policy_manager_impl::get_requester_policies(const std::shared_ptr _polic if (!its_policy->requests_.empty()) { _requesters.insert(its_policy); - its_policy->print(); } } } @@ -1309,7 +1308,7 @@ policy_manager_impl::print_policy(const std::shared_ptr &_policy) const bool policy_manager_impl::parse_uid_gid(const byte_t* &_buffer, - uint32_t &_buffer_size, uint32_t &_uid, uint32_t &_gid) const { + uint32_t &_buffer_size, uid_t &_uid, gid_t &_gid) const { const auto its_policy = std::make_shared(); return (its_policy @@ -1448,43 +1447,4 @@ policy_manager_impl::get_sec_client_to_clients_mapping( return false; } -//////////////////////////////////////////////////////////////////////////////// -// Manage the security object -//////////////////////////////////////////////////////////////////////////////// -static std::shared_ptr *the_policy_manager_ptr__(nullptr); -static std::mutex the_policy_manager_mutex__; - -std::shared_ptr -policy_manager_impl::get() { -#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) - std::lock_guard its_lock(the_policy_manager_mutex__); -#endif - if(the_policy_manager_ptr__ == nullptr) { - the_policy_manager_ptr__ = new std::shared_ptr(); - } - if (the_policy_manager_ptr__ != nullptr) { - if (!(*the_policy_manager_ptr__)) { - *the_policy_manager_ptr__ = std::make_shared(); - } - return *the_policy_manager_ptr__; - } - return nullptr; -} - -#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) -static void security_teardown(void) __attribute__((destructor)); -static void security_teardown(void) -{ - if (the_policy_manager_ptr__ != nullptr) { - // TODO: This mutex is causing a crash due to changes in the way mutexes are defined. - // Since this function only runs on the main thread, no mutex should be needed. Leaving a - // comment pending a refactor. - // std::lock_guard its_lock(the_policy_manager_mutex__); - the_policy_manager_ptr__->reset(); - delete the_policy_manager_ptr__; - the_policy_manager_ptr__ = nullptr; - } -} -#endif - } // namespace vsomeip_v3 diff --git a/implementation/security/src/security.cpp b/implementation/security/src/security.cpp index 19ff73dad..e17e34730 100644 --- a/implementation/security/src/security.cpp +++ b/implementation/security/src/security.cpp @@ -4,14 +4,15 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "../include/security.hpp" -#include "../include/policy_manager_impl.hpp" #include +#include #ifdef ANDROID #include "../../configuration/include/internal_android.hpp" #else #include "../../configuration/include/internal.hpp" #endif -#include "../../plugin/include/plugin_manager.hpp" +#include "../../configuration/include/configuration_plugin.hpp" +#include "../../configuration/include/configuration_impl.hpp" #include #include @@ -21,51 +22,95 @@ #include #endif -#define VSOMEIP_SEC_POLICY_SYMDEF(sym) symdef_t{\ - "vsomeip_sec_policy_"#sym, nullptr, reinterpret_cast(&sym) \ -} +template +std::function security_load_function(void *_library, std::string const &_name) { + void *its_function; +#ifdef _WIN32 + its_function = GetProcAddress(reinterpret_cast(_library), _name.c_str()); +#else + its_function = dlsym(_library, _name.c_str()); +#endif + if (!its_function) { + VSOMEIP_ERROR << __func__ + << ": security library misses \"" + << _name + << "\" function."; + return nullptr; + } -#define VSOMEIP_SEC_SYMDEF(sym) symdef_t{\ - "vsomeip_sec_"#sym, nullptr, reinterpret_cast(&sym) \ + return reinterpret_cast(its_function); } +#define VSOMEIP_SECURITY_LOAD_IMPL(symbol, variable) \ + auto variable = security_load_function(its_library, #symbol); \ + if (!variable) { \ + its_manager->unload_library(its_library); \ + return false; \ + } + +#define VSOMEIP_SECURITY_LOAD(name) \ + VSOMEIP_SECURITY_LOAD_IMPL(vsomeip_sec_##name, loaded_##name) + +#define VSOMEIP_SECURITY_POLICY_LOAD(name) \ + VSOMEIP_SECURITY_LOAD_IMPL(vsomeip_sec_policy_##name, loaded_##name) + +#define VSOMEIP_SECURITY_ASSIGN_FUNCTION(name) \ + name = loaded_##name + namespace vsomeip_v3 { -bool -security::load() { - using symdef_t = std::tuple; - std::array symbol_table{ - VSOMEIP_SEC_POLICY_SYMDEF(initialize), - VSOMEIP_SEC_POLICY_SYMDEF(authenticate_router), - VSOMEIP_SEC_POLICY_SYMDEF(is_client_allowed_to_offer), - VSOMEIP_SEC_POLICY_SYMDEF(is_client_allowed_to_request), - VSOMEIP_SEC_POLICY_SYMDEF(is_client_allowed_to_access_member), - VSOMEIP_SEC_SYMDEF(sync_client) +security::security(std::shared_ptr _policy_manager): + policy_manager_(_policy_manager) { + + initialize = [&]() -> vsomeip_sec_policy_result_t { + return default_initialize(); }; - if (auto manager = plugin_manager::get()) { - if (auto lib = manager->load_library(VSOMEIP_SEC_LIBRARY)) { - // First we load the symbols into the 2nd tuple element - for (auto& symdef : symbol_table) { - auto name = std::get<0>(symdef); - auto& symbol = std::get<1>(symdef); - if (!(symbol = manager->load_symbol(lib, name))) { - VSOMEIP_ERROR << __func__ - << ": security library misses " - << std::quoted(name) - << " function."; - manager->unload_library(lib); - return false; - } - } - - // Now that we have all symbols loaded, - // assign the 2nd tuple element to the 3rd - for (auto& symdef : symbol_table) { - auto symbol = std::get<1>(symdef); - auto& stub = std::get<2>(symdef); - *stub = symbol; - } + authenticate_router = [&](const vsomeip_sec_client_t *_server) -> vsomeip_sec_acl_result_t { + return default_authenticate_router(_server); + }; + + is_client_allowed_to_offer = [&](const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, vsomeip_sec_instance_id_t _instance) -> vsomeip_sec_acl_result_t { + return default_is_client_allowed_to_offer(_client, _service, _instance); + }; + + is_client_allowed_to_request = [&](const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, vsomeip_sec_instance_id_t _instance) -> vsomeip_sec_acl_result_t { + return default_is_client_allowed_to_request(_client, _service, _instance); + }; + + is_client_allowed_to_access_member = [&](const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, vsomeip_sec_instance_id_t _instance, + vsomeip_sec_member_id_t _member) -> vsomeip_sec_acl_result_t { + return default_is_client_allowed_to_access_member(_client, _service, + _instance, _member); + }; + + sync_client = [&](vsomeip_sec_client_t *_client) { + return default_sync_client(_client); + }; +} + +bool +security::load() { + if (auto its_manager = plugin_manager::get()) { + if (auto its_library = its_manager->load_library(VSOMEIP_SEC_LIBRARY)) { + + VSOMEIP_SECURITY_POLICY_LOAD(initialize); + VSOMEIP_SECURITY_POLICY_LOAD(authenticate_router); + VSOMEIP_SECURITY_POLICY_LOAD(is_client_allowed_to_offer); + VSOMEIP_SECURITY_POLICY_LOAD(is_client_allowed_to_request); + VSOMEIP_SECURITY_POLICY_LOAD(is_client_allowed_to_access_member); + VSOMEIP_SECURITY_LOAD(sync_client); + + // All symbols could be loaded, assign them + VSOMEIP_SECURITY_ASSIGN_FUNCTION(initialize); + VSOMEIP_SECURITY_ASSIGN_FUNCTION(authenticate_router); + VSOMEIP_SECURITY_ASSIGN_FUNCTION(is_client_allowed_to_offer); + VSOMEIP_SECURITY_ASSIGN_FUNCTION(is_client_allowed_to_request); + VSOMEIP_SECURITY_ASSIGN_FUNCTION(is_client_allowed_to_access_member); + VSOMEIP_SECURITY_ASSIGN_FUNCTION(sync_client); // Symbol loading complete, success! return true; @@ -81,82 +126,61 @@ security::load() { return false; } -decltype(security::initialize) -security::initialize = security::default_initialize; - -decltype(security::authenticate_router) -security::authenticate_router = security::default_authenticate_router; - -decltype(security::is_client_allowed_to_offer) -security::is_client_allowed_to_offer = security::default_is_client_allowed_to_offer; - -decltype(security::is_client_allowed_to_request) -security::is_client_allowed_to_request = security::default_is_client_allowed_to_request; - -decltype(security::is_client_allowed_to_access_member) -security::is_client_allowed_to_access_member = security::default_is_client_allowed_to_access_member; - -decltype(security::sync_client) -security::sync_client = security::default_sync_client; - // // Default interface implementation // vsomeip_sec_policy_result_t -security::default_initialize(void) { +security::default_initialize() { return VSOMEIP_SEC_POLICY_OK; } vsomeip_sec_acl_result_t -security::default_authenticate_router( - const vsomeip_sec_client_t *_server) { +security::default_authenticate_router(const vsomeip_sec_client_t *_server) { + if (_server && _server->port != VSOMEIP_SEC_PORT_UNUSED) return VSOMEIP_SEC_OK; - if (policy_manager_impl::get()->check_routing_credentials(_server)) + if (policy_manager_->check_routing_credentials(_server)) return VSOMEIP_SEC_OK; else return VSOMEIP_SEC_PERM_DENIED; } vsomeip_sec_acl_result_t -security::default_is_client_allowed_to_offer( - const vsomeip_sec_client_t *_client, - vsomeip_sec_service_id_t _service, - vsomeip_sec_instance_id_t _instance) { +security::default_is_client_allowed_to_offer(const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, vsomeip_sec_instance_id_t _instance) { + if (_client && _client->port != VSOMEIP_SEC_PORT_UNUSED) return VSOMEIP_SEC_OK; - if (policy_manager_impl::get()->is_offer_allowed(_client, _service, _instance)) + if (policy_manager_->is_offer_allowed(_client, _service, _instance)) return VSOMEIP_SEC_OK; else return VSOMEIP_SEC_PERM_DENIED; } vsomeip_sec_acl_result_t -security::default_is_client_allowed_to_request( - const vsomeip_sec_client_t *_client, - vsomeip_sec_service_id_t _service, - vsomeip_sec_instance_id_t _instance) { +security::default_is_client_allowed_to_request(const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, vsomeip_sec_instance_id_t _instance) { + if (_client && _client->port != VSOMEIP_SEC_PORT_UNUSED) return VSOMEIP_SEC_OK; - if (policy_manager_impl::get()->is_client_allowed(_client, _service, _instance, 0x00, true)) + if (policy_manager_->is_client_allowed(_client, _service, _instance, 0x00, true)) return VSOMEIP_SEC_OK; else return VSOMEIP_SEC_PERM_DENIED; } vsomeip_sec_acl_result_t -security::default_is_client_allowed_to_access_member( - const vsomeip_sec_client_t *_client, - vsomeip_sec_service_id_t _service, - vsomeip_sec_instance_id_t _instance, +security::default_is_client_allowed_to_access_member(const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, vsomeip_sec_instance_id_t _instance, vsomeip_sec_member_id_t _member) { + if (_client && _client->port != VSOMEIP_SEC_PORT_UNUSED) return VSOMEIP_SEC_OK; - if (policy_manager_impl::get()->is_client_allowed(_client, _service, _instance, _member, false)) + if (policy_manager_->is_client_allowed(_client, _service, _instance, _member, false)) return VSOMEIP_SEC_OK; else return VSOMEIP_SEC_PERM_DENIED; @@ -164,7 +188,6 @@ security::default_is_client_allowed_to_access_member( void security::default_sync_client(vsomeip_sec_client_t *_client) { - (void)_client; } diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index d180960f8..34a33f277 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -52,6 +52,10 @@ class service_discovery { const boost::asio::ip::address &_sender, bool _is_multicast) = 0; + virtual void + sent_messages(const byte_t* _data, length_t _size, + const boost::asio::ip::address& _remote_address = boost::asio::ip::address()) = 0; + virtual void on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr &_endpoint) = 0; diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index c5d3d2a7c..14d2267d8 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -11,12 +11,7 @@ #include #include -#if VSOMEIP_BOOST_VERSION < 106600 -# include -# define io_context io_service -#else -# include -#endif +#include #include "../../routing/include/function_types.hpp" #include "../../routing/include/types.hpp" diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index 961876f13..d07fcb1f7 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -85,9 +85,12 @@ class service_discovery_impl: public service_discovery, bool send(bool _is_announcing); - void on_message(const byte_t *_data, length_t _length, - const boost::asio::ip::address &_sender, - bool _is_multicast); + void on_message(const byte_t* _data, length_t _length, const boost::asio::ip::address& _sender, + bool _is_multicast); + + void + sent_messages(const byte_t* _data, length_t _size, + const boost::asio::ip::address& _remote_address = boost::asio::ip::address()); void on_endpoint_connected( service_t _service, instance_t _instance, @@ -149,19 +152,21 @@ class service_discovery_impl: public service_discovery, 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, const sd_acceptance_state_t& _sd_ac_state); + + void process_serviceentry(std::shared_ptr& _entry, + const std::vector>& _options, + bool _unicast_flag, + std::vector>& _resubscribes, + bool _received_via_multicast, + const sd_acceptance_state_t& _sd_ac_state); + void check_sent_offers(const message_impl::entries_t& _entries, + const boost::asio::ip::address& _remote_address) const; void process_offerservice_serviceentry( service_t _service, instance_t _instance, major_version_t _major, - minor_version_t _minor, ttl_t _ttl, - const boost::asio::ip::address &_reliable_address, - uint16_t _reliable_port, - const boost::asio::ip::address &_unreliable_address, - uint16_t _unreliable_port, - std::vector > &_resubscribes, - bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state); + minor_version_t _minor, ttl_t _ttl, const boost::asio::ip::address& _reliable_address, + uint16_t _reliable_port, const boost::asio::ip::address& _unreliable_address, + uint16_t _unreliable_port, std::vector>& _resubscribes, + bool _received_via_multicast, 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, @@ -180,18 +185,16 @@ class service_discovery_impl: public service_discovery, bool _is_multicast, 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, + 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, - const boost::asio::ip::address &_first_address, uint16_t _first_port, - bool _is_first_reliable, - const boost::asio::ip::address &_second_address, uint16_t _second_port, - bool _is_second_reliable, - std::shared_ptr &_acknowledgement, + const boost::asio::ip::address& _first_address, uint16_t _first_port, + bool _is_first_reliable, const boost::asio::ip::address& _second_address, + uint16_t _second_port, bool _is_second_reliable, + 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); + const std::set& _clients, const sd_acceptance_state_t& _sd_ac_state, + const std::shared_ptr& _info, const boost::asio::ip::address& _sender); void handle_eventgroup_subscription_ack(service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, uint8_t _counter, @@ -317,10 +320,10 @@ class service_discovery_impl: public service_discovery, bool update_remote_offer_type(service_t _service, instance_t _instance, reliability_type_e _offer_type, - const boost::asio::ip::address &_reliable_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); + const boost::asio::ip::address& _unreliable_address, + std::uint16_t _unreliable_port, bool _received_via_multicast); void remove_remote_offer_type(service_t _service, instance_t _instance, const boost::asio::ip::address &_reliable_address, std::uint16_t _reliable_port, @@ -330,11 +333,19 @@ class service_discovery_impl: public service_discovery, void remove_remote_offer_type_by_ip(const boost::asio::ip::address &_address, std::uint16_t _port, bool _reliable); - std::shared_ptr create_subscription( - major_version_t _major, ttl_t _ttl, - const std::shared_ptr &_reliable, - const std::shared_ptr &_unreliable, - const std::shared_ptr &_info); + // Returns true if the state changes from unicast -> multicast, false any of the other 3 cases + bool set_offer_multicast_state(service_t _service, instance_t _instance, + reliability_type_e _offer_type, + const boost::asio::ip::address& _reliable_address, + port_t _reliable_port, + const boost::asio::ip::address& _unreliable_address, + std::uint16_t _unreliable_port, bool _received_via_multicast); + + std::shared_ptr + create_subscription(major_version_t _major, ttl_t _ttl, + const std::shared_ptr& _reliable, + const std::shared_ptr& _unreliable, + const std::shared_ptr& _info) const; std::shared_ptr get_remote_subscription( const service_t _service, const instance_t _instance, @@ -360,6 +371,9 @@ class service_discovery_impl: public service_discovery, reliability_type_e get_eventgroup_reliability( service_t _service, instance_t _instance, eventgroup_t _eventgroup, const std::shared_ptr& _subscription); + void deserialize_data(const byte_t* _data, const length_t& _size, + std::shared_ptr& _message); + private: boost::asio::io_context &io_; service_discovery_host *host_; @@ -385,6 +399,7 @@ class service_discovery_impl: public service_discovery, std::recursive_mutex subscribed_mutex_; std::mutex serialize_mutex_; + std::mutex deserialize_mutex_; // Sessions std::map > sessions_sent_; @@ -463,9 +478,31 @@ class service_discovery_impl: public service_discovery, mutable std::mutex remote_offer_types_mutex_; std::map, reliability_type_e> remote_offer_types_; + + struct remote_offer_info_t { + std::pair service_info; + + // The goal of this flag is to handle the SOMEIPSD_00577 requirement + // To do so we will keep track of the last received offer for a given service+instance pair + // The transition between unicast > multicast should be less strict in validations + // and not trigger a [StopSubscribe][Subscribe] + // It shall be mutable to allow the value to be updated within a std::set + mutable bool offer_received_via_multicast; + + remote_offer_info_t(service_t _service, instance_t _instance, + bool _received_via_multicast = true) : + service_info(std::make_pair(_service, _instance)), + offer_received_via_multicast(_received_via_multicast) { } + + // Use the service_info pair as the key for unique values within a std::set + bool operator<(const remote_offer_info_t& other) const { + return service_info < other.service_info; + } + }; + std::map, - std::set>>> 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/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index 52d42620a..768384b21 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -40,7 +40,7 @@ #include "../../routing/include/event.hpp" #include "../../routing/include/eventgroupinfo.hpp" #include "../../routing/include/serviceinfo.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace sd { @@ -151,6 +151,8 @@ service_discovery_impl::init() { offer_debounce_time_ = std::chrono::milliseconds( configuration_->get_sd_offer_debounce_time()); ttl_timer_runtime_ = cyclic_offer_delay_ / 2; + find_debounce_time_ = std::chrono::milliseconds( + configuration_->get_sd_find_debounce_time()); ttl_factor_offers_ = configuration_->get_ttl_factor_offers(); ttl_factor_subscriptions_ = configuration_->get_ttl_factor_subscribes(); @@ -1047,8 +1049,7 @@ service_discovery_impl::insert_subscription_ack( entry_data_t its_data; - std::shared_ptr its_entry - = std::make_shared(); + auto its_entry = std::make_shared(); its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP_ACK); its_entry->set_service(its_service); its_entry->set_instance(its_instance); @@ -1130,6 +1131,7 @@ service_discovery_impl::on_message( if(is_suspended_) { return; } + // ignore all SD messages with source address equal to node's unicast address if (!check_source_address(_sender)) { return; @@ -1151,15 +1153,14 @@ service_discovery_impl::on_message( } current_remote_address_ = _sender; - deserializer_->set_data(_data, _length); - std::shared_ptr its_message( - deserializer_->deserialize_sd_message()); - deserializer_->reset(); + std::shared_ptr its_message; + deserialize_data(_data, _length, its_message); if (its_message) { // ignore all messages which are sent with invalid header fields if(!check_static_header_fields(its_message)) { return; } + // Expire all subscriptions / services in case of reboot if (is_reboot(_sender, _is_multicast, its_message->get_reboot_flag(), its_message->get_session())) { @@ -1305,14 +1306,51 @@ service_discovery_impl::on_message( } } +void service_discovery_impl::sent_messages(const byte_t* _data, length_t _size, + const boost::asio::ip::address& _remote_address) { + std::shared_ptr its_message; + deserialize_data(_data, _size, its_message); + if (its_message) { + const message_impl::entries_t& its_entries = its_message->get_entries(); + check_sent_offers(its_entries, _remote_address); + } +} + // Entry processing -void -service_discovery_impl::process_serviceentry( - std::shared_ptr &_entry, - const std::vector > &_options, - bool _unicast_flag, - std::vector > &_resubscribes, - bool _received_via_mcast, +void service_discovery_impl::check_sent_offers(const message_impl::entries_t& _entries, + const boost::asio::ip::address& _remote_address) const { + + // only the offers messages sent by itself to multicast or unicast will be verified + // the another messages sent by itself will be ignored here + // the multicast offers are checked when SD receive its + // the unicast offers are checked in the send_cbk method, when SD send its + for (auto iter = _entries.begin(); iter != _entries.end(); iter++) { + if ((*iter)->get_type() == entry_type_e::OFFER_SERVICE && (*iter)->get_ttl() > 0) { + auto its_service = (*iter)->get_service(); + auto its_instance = (*iter)->get_instance(); + + std::shared_ptr its_info = + host_->get_offered_service(its_service, its_instance); + if (its_info) { + if (_remote_address.is_unspecified()) { + // enable proccess remote subscription for the services + // SD has already sent the offers for this service to multicast ip + its_info->set_accepting_remote_subscriptions(true); + } else { + if (!its_info->is_accepting_remote_subscriptions()) { + // enable to proccess remote subscription from remote ip for the services + its_info->add_remote_ip(_remote_address.to_string()); + } + } + } + } + } +} + +void service_discovery_impl::process_serviceentry( + std::shared_ptr& _entry, + const std::vector>& _options, bool _unicast_flag, + std::vector>& _resubscribes, bool _received_via_multicast, const sd_acceptance_state_t& _sd_ac_state) { // Read service info from entry @@ -1389,24 +1427,23 @@ service_discovery_impl::process_serviceentry( } if (0 < its_ttl) { - switch(its_type) { - case entry_type_e::FIND_SERVICE: - process_findservice_serviceentry(its_service, its_instance, - its_major, its_minor, _unicast_flag); - break; - case entry_type_e::OFFER_SERVICE: - 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, _sd_ac_state); - break; - case entry_type_e::UNKNOWN: - default: - VSOMEIP_ERROR << __func__ << ": Unsupported service entry type"; + switch (its_type) { + case entry_type_e::FIND_SERVICE: + process_findservice_serviceentry(its_service, its_instance, its_major, its_minor, + _unicast_flag); + break; + case entry_type_e::OFFER_SERVICE: + 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_multicast, _sd_ac_state); + break; + case entry_type_e::UNKNOWN: + default: + VSOMEIP_ERROR << __func__ << ": Unsupported service entry type"; } } else if (its_type != entry_type_e::FIND_SERVICE - && (_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_)) { + && (_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_)) { // stop sending find service in repetition phase update_request(its_service, its_instance); @@ -1422,17 +1459,13 @@ service_discovery_impl::process_serviceentry( } } -void -service_discovery_impl::process_offerservice_serviceentry( - service_t _service, instance_t _instance, major_version_t _major, - minor_version_t _minor, ttl_t _ttl, - const boost::asio::ip::address &_reliable_address, - uint16_t _reliable_port, - const boost::asio::ip::address &_unreliable_address, - uint16_t _unreliable_port, - std::vector > &_resubscribes, - bool _received_via_mcast, const sd_acceptance_state_t& _sd_ac_state) { - std::shared_ptr < runtime > its_runtime = runtime_.lock(); +void service_discovery_impl::process_offerservice_serviceentry( + service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, + ttl_t _ttl, const boost::asio::ip::address& _reliable_address, uint16_t _reliable_port, + const boost::asio::ip::address& _unreliable_address, uint16_t _unreliable_port, + std::vector>& _resubscribes, bool _received_via_multicast, + const sd_acceptance_state_t& _sd_ac_state) { + std::shared_ptr its_runtime = runtime_.lock(); if (!its_runtime) return; @@ -1523,13 +1556,11 @@ service_discovery_impl::process_offerservice_serviceentry( } } - 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::setfill('0') - << std::setw(4) << _service << "." - << std::setw(4) << _instance << "]"; + if (update_remote_offer_type(_service, _instance, offer_type, _reliable_address, _reliable_port, + _unreliable_address, _unreliable_port, _received_via_multicast)) { + 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); @@ -1554,8 +1585,12 @@ service_discovery_impl::process_offerservice_serviceentry( } } + const bool was_previously_offered_by_unicast = set_offer_multicast_state( + _service, _instance, offer_type, _reliable_address, _reliable_port, _unreliable_address, + _unreliable_port, _received_via_multicast); + // No need to resubscribe for unicast offers - if (_received_via_mcast) { + if (_received_via_multicast) { auto found_service = subscribed_.find(_service); if (found_service != subscribed_.end()) { auto found_instance = found_service->second.find(_instance); @@ -1564,32 +1599,38 @@ service_discovery_impl::process_offerservice_serviceentry( for (const auto& its_eventgroup : found_instance->second) { auto its_subscription = its_eventgroup.second; std::shared_ptr its_reliable, its_unreliable; - get_subscription_endpoints(_service, _instance, - its_reliable, its_unreliable); + get_subscription_endpoints(_service, _instance, its_reliable, + its_unreliable); its_subscription->set_endpoint(its_reliable, true); its_subscription->set_endpoint(its_unreliable, false); for (const auto& its_client : its_subscription->get_clients()) { if (its_subscription->get_state(its_client) - == subscription_state_e::ST_ACKNOWLEDGED) { + == subscription_state_e::ST_ACKNOWLEDGED) { its_subscription->set_state(its_client, - subscription_state_e::ST_RESUBSCRIBING); - } else { + subscription_state_e::ST_RESUBSCRIBING); + } else if (its_subscription->get_state(its_client) + != subscription_state_e::ST_ACKNOWLEDGED + && was_previously_offered_by_unicast) { its_subscription->set_state(its_client, + subscription_state_e::ST_RESUBSCRIBING); + } else { + its_subscription->set_state( + its_client, subscription_state_e::ST_RESUBSCRIBING_NOT_ACKNOWLEDGED); } } - const reliability_type_e its_reliability = - get_eventgroup_reliability(_service, _instance, - its_eventgroup.first, its_subscription); + 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_reliability); + auto its_data = + create_eventgroup_entry(_service, _instance, its_eventgroup.first, + its_subscription, its_reliability); if (its_data.entry_) { add_entry_data(_resubscribes, its_data); } for (const auto its_client : its_subscription->get_clients()) { its_subscription->set_state(its_client, - subscription_state_e::ST_NOT_ACKNOWLEDGED); + subscription_state_e::ST_NOT_ACKNOWLEDGED); } } } @@ -1597,11 +1638,10 @@ service_discovery_impl::process_offerservice_serviceentry( } } - host_->add_routing_info(_service, _instance, - _major, _minor, + host_->add_routing_info(_service, _instance, _major, _minor, _ttl * get_ttl_factor(_service, _instance, ttl_factor_offers_), - _reliable_address, _reliable_port, - _unreliable_address, _unreliable_port); + _reliable_address, _reliable_port, _unreliable_address, + _unreliable_port); } void @@ -2254,12 +2294,11 @@ service_discovery_impl::process_eventgroupentry( } if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) { - handle_eventgroup_subscription(its_service, its_instance, - its_eventgroup, its_major, its_ttl, 0, 0, - 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, _sd_ac_state, its_info); + handle_eventgroup_subscription( + its_service, its_instance, its_eventgroup, its_major, its_ttl, 0, 0, + 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, _sd_ac_state, its_info, _sender); } else { if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) { //this type is used for ACK and NACK messages if (its_ttl > 0) { @@ -2275,20 +2314,16 @@ service_discovery_impl::process_eventgroupentry( } } -void -service_discovery_impl::handle_eventgroup_subscription( - service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, +void service_discovery_impl::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, - const boost::asio::ip::address &_first_address, uint16_t _first_port, - bool _is_first_reliable, - const boost::asio::ip::address &_second_address, uint16_t _second_port, - bool _is_second_reliable, - std::shared_ptr &_acknowledgement, + const boost::asio::ip::address& _first_address, uint16_t _first_port, + bool _is_first_reliable, const boost::asio::ip::address& _second_address, + uint16_t _second_port, bool _is_second_reliable, + 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) { + const std::set& _clients, const sd_acceptance_state_t& _sd_ac_state, + const std::shared_ptr& _info, const boost::asio::ip::address& _sender) { (void)_counter; (void)_reserved; @@ -2345,6 +2380,24 @@ service_discovery_impl::handle_eventgroup_subscription( #endif + if (_ttl > 0) { + std::shared_ptr its_info = host_->get_offered_service(_service, _instance); + bool send_nack = false; + if (!its_info) { + send_nack = true; + } else { + if (!its_info->is_accepting_remote_subscriptions()) { // offer not sent to multicast ip + auto its_remote_ips = + its_info->get_remote_ip_accepting_sub(); // offer not sent to unicast + if (its_remote_ips.find(_sender.to_string()) == its_remote_ips.end()) + send_nack = true; + } + } + if (send_nack) { + insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); + return; + } + } std::shared_ptr its_subscriber; std::shared_ptr its_reliable; @@ -2583,6 +2636,7 @@ bool service_discovery_impl::is_tcp_connected(service_t _service, bool service_discovery_impl::send( const std::vector > &_messages) { + bool its_result(true); std::lock_guard its_lock(serialize_mutex_); for (const auto &m : _messages) { @@ -2768,12 +2822,10 @@ service_discovery_impl::check_ipv4_address( << its_address; is_valid = false; } else { - const std::uint32_t self = VSOMEIP_BYTES_TO_LONG(its_unicast_address[0], - its_unicast_address[1], its_unicast_address[2], its_unicast_address[3]); - const std::uint32_t remote = VSOMEIP_BYTES_TO_LONG(endpoint_address[0], - endpoint_address[1], endpoint_address[2], endpoint_address[3]); - const std::uint32_t netmask = VSOMEIP_BYTES_TO_LONG(its_netmask[0], - its_netmask[1], its_netmask[2], its_netmask[3]); + const std::uint32_t self = bithelper::read_uint32_be(&its_unicast_address[0]); + const std::uint32_t remote = bithelper::read_uint32_be(&endpoint_address[0]); + const std::uint32_t netmask = bithelper::read_uint32_be(&its_netmask[0]); + if ((self & netmask) != (remote & netmask)) { VSOMEIP_ERROR<< "Subscriber's IP isn't in the same subnet as host's IP: " << its_address; @@ -2872,8 +2924,7 @@ service_discovery_impl::on_find_debounce_timer_expired( // Sent out finds for the first time as initial wait phase ended std::vector> its_messages; - std::shared_ptr its_message( - std::make_shared()); + auto its_message = std::make_shared(); its_messages.push_back(its_message); // Serialize and send FindService (increments sent counter in requested_ map) insert_find_entries(its_messages, repetition_phase_finds); @@ -2882,8 +2933,7 @@ service_discovery_impl::on_find_debounce_timer_expired( std::chrono::milliseconds its_delay(repetitions_base_delay_); std::uint8_t its_repetitions(1); - std::shared_ptr its_timer = std::make_shared< - boost::asio::steady_timer>(host_->get_io()); + auto its_timer = std::make_shared(host_->get_io()); { std::lock_guard its_lock(find_repetition_phase_timers_mutex_); find_repetition_phase_timers_[its_timer] = repetition_phase_finds; @@ -2947,7 +2997,7 @@ service_discovery_impl::on_offer_debounce_timer_expired( // Sent out offers for the first time as initial wait phase ended std::vector> its_messages; - std::shared_ptr its_message(std::make_shared()); + auto its_message = std::make_shared(); its_messages.push_back(its_message); insert_offer_entries(its_messages, repetition_phase_offers, true); @@ -2968,8 +3018,7 @@ service_discovery_impl::on_offer_debounce_timer_expired( its_repetitions = 0; } - std::shared_ptr its_timer = std::make_shared< - boost::asio::steady_timer>(host_->get_io()); + auto its_timer = std::make_shared(host_->get_io()); { std::lock_guard its_lock(repetition_phase_timers_mutex_); @@ -3031,8 +3080,7 @@ service_discovery_impl::on_repetition_phase_timer_expired( } } std::vector> its_messages; - std::shared_ptr its_message( - std::make_shared()); + auto its_message = std::make_shared(); its_messages.push_back(its_message); insert_offer_entries(its_messages, its_timer_pair->second, true); @@ -3075,8 +3123,7 @@ service_discovery_impl::on_find_repetition_phase_timer_expired( if (_repetition <= repetitions_max_) { // Sent findService entries in one message, double time to wait and start timer again. std::vector> its_messages; - std::shared_ptr its_message( - std::make_shared()); + auto its_message = std::make_shared(); its_messages.push_back(its_message); insert_find_entries(its_messages, its_timer_pair->second); send(its_messages); @@ -3123,6 +3170,8 @@ service_discovery_impl::stop_offer_service( const std::shared_ptr &_info, bool _send) { std::lock_guard its_lock(offer_mutex_); _info->set_ttl(0); + // disable accepting remote subscriptions + _info->set_accepting_remote_subscriptions(false); const service_t its_service = _info->get_service(); const instance_t its_instance = _info->get_instance(); bool stop_offer_required(false); @@ -3191,8 +3240,7 @@ service_discovery_impl::send_stop_offer(const std::shared_ptr &_inf if (_info->get_endpoint(false) || _info->get_endpoint(true)) { std::vector > its_messages; - std::shared_ptr its_current_message( - std::make_shared()); + auto its_current_message = std::make_shared(); its_messages.push_back(its_current_message); insert_offer_service(its_messages, _info); @@ -3207,8 +3255,7 @@ bool service_discovery_impl::send_collected_stop_offers(const std::vector> &_infos) { std::vector > its_messages; - std::shared_ptr its_current_message( - std::make_shared()); + auto its_current_message = std::make_shared(); its_messages.push_back(its_current_message); // pack multiple stop offers together @@ -3378,9 +3425,9 @@ service_discovery_impl::check_stop_subscribe_subscribe( message_impl::entries_t::const_iterator _end, const message_impl::options_t& _options) const { - return (*_iter)->get_ttl() == 0 - && (*_iter)->get_type() == entry_type_e::STOP_SUBSCRIBE_EVENTGROUP - && has_opposite(_iter, _end, _options); + return (*_iter)->get_ttl() == 0 + && (*_iter)->get_type() == entry_type_e::STOP_SUBSCRIBE_EVENTGROUP + && has_opposite(_iter, _end, _options); } bool @@ -3570,49 +3617,44 @@ service_discovery_impl::get_remote_offer_type( } -bool -service_discovery_impl::update_remote_offer_type( - service_t _service, instance_t _instance, - reliability_type_e _offer_type, - const boost::asio::ip::address &_reliable_address, - std::uint16_t _reliable_port, - const boost::asio::ip::address &_unreliable_address, - std::uint16_t _unreliable_port) { +bool service_discovery_impl::update_remote_offer_type( + service_t _service, instance_t _instance, reliability_type_e _offer_type, + const boost::asio::ip::address& _reliable_address, std::uint16_t _reliable_port, + const boost::asio::ip::address& _unreliable_address, std::uint16_t _unreliable_port, + bool _received_via_multicast) { bool ret(false); std::lock_guard its_lock(remote_offer_types_mutex_); - const std::pair its_si_pair = std::make_pair(_service, _instance); - auto found_si = remote_offer_types_.find(its_si_pair); + const remote_offer_info_t its_service_instance(_service, _instance, _received_via_multicast); + auto found_si = remote_offer_types_.find(its_service_instance.service_info); if (found_si != remote_offer_types_.end()) { if (found_si->second != _offer_type ) { found_si->second = _offer_type; ret = true; } } else { - remote_offer_types_[its_si_pair] = _offer_type; + remote_offer_types_[its_service_instance.service_info] = _offer_type; } switch (_offer_type) { - case reliability_type_e::RT_UNRELIABLE: - remote_offers_by_ip_[_unreliable_address][std::make_pair(false, - _unreliable_port)].insert(its_si_pair); - break; - case reliability_type_e::RT_RELIABLE: - remote_offers_by_ip_[_reliable_address][std::make_pair(true, - _reliable_port)].insert(its_si_pair); - break; - case reliability_type_e::RT_BOTH: - 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 reliability_type_e::RT_UNKNOWN: - default: - VSOMEIP_WARNING << __func__ << ": unknown offer type [" - << std::hex << std::setfill('0') - << std::setw(4) << _service << "." - << std::setw(4) << _instance << "]" - << static_cast(_offer_type); - break; + case reliability_type_e::RT_UNRELIABLE: + remote_offers_by_ip_[_unreliable_address][std::make_pair(false, _unreliable_port)].insert( + its_service_instance); + break; + case reliability_type_e::RT_RELIABLE: + remote_offers_by_ip_[_reliable_address][std::make_pair(true, _reliable_port)].insert( + its_service_instance); + break; + case reliability_type_e::RT_BOTH: + remote_offers_by_ip_[_unreliable_address][std::make_pair(false, _unreliable_port)].insert( + its_service_instance); + remote_offers_by_ip_[_unreliable_address][std::make_pair(true, _reliable_port)].insert( + its_service_instance); + break; + case reliability_type_e::RT_UNKNOWN: + default: + VSOMEIP_WARNING << __func__ << ": unknown offer type [" << std::hex << std::setw(4) + << std::setfill('0') << _service << "." << std::hex << std::setw(4) + << std::setfill('0') << _instance << "]" << static_cast(_offer_type); + break; } return ret; } @@ -3625,19 +3667,17 @@ service_discovery_impl::remove_remote_offer_type( 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); + const remote_offer_info_t its_service_instance(_service, _instance); + + remote_offer_types_.erase(its_service_instance.service_info); - auto delete_from_remote_offers_by_ip = [&]( - const boost::asio::ip::address& _address, std::uint16_t _port, - bool _reliable) { + 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)); + 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.erase(its_service_instance)) { if (found_port->second.empty()) { found_address->second.erase(found_port); if (found_address->second.empty()) { @@ -3670,8 +3710,8 @@ void service_discovery_impl::remove_remote_offer_type_by_ip( 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); + for (const auto& si : port.second) { + remote_offer_types_.erase(si.service_info); } } remote_offers_by_ip_.erase(_address); @@ -3680,7 +3720,7 @@ void service_discovery_impl::remove_remote_offer_type_by_ip( 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); + remote_offer_types_.erase(si.service_info); } found_address->second.erase(found_port); if (found_address->second.empty()) { @@ -3691,12 +3731,59 @@ void service_discovery_impl::remove_remote_offer_type_by_ip( } } +bool service_discovery_impl::set_offer_multicast_state( + service_t _service, instance_t _instance, reliability_type_e _offer_type, + const boost::asio::ip::address& _reliable_address, port_t _reliable_port, + const boost::asio::ip::address& _unreliable_address, std::uint16_t _unreliable_port, + bool _received_via_multicast) { + + bool was_unicast = false; + + auto check_offer_info = [this, &was_unicast, _received_via_multicast]( + const boost::asio::ip::address& address, bool reliable, + port_t port, service_t service_id, instance_t instance_id) { + 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()) { + auto found_offer_info = found_port->second.find({service_id, instance_id}); + if (found_offer_info != found_port->second.end()) { + if (!found_offer_info->offer_received_via_multicast) { + was_unicast = true; + found_offer_info->offer_received_via_multicast = _received_via_multicast; + } + } + } + } + }; + + switch (_offer_type) { + case reliability_type_e::RT_UNRELIABLE: + check_offer_info(_unreliable_address, false, _unreliable_port, _service, _instance); + break; + case reliability_type_e::RT_RELIABLE: + check_offer_info(_reliable_address, true, _reliable_port, _service, _instance); + break; + case reliability_type_e::RT_BOTH: + check_offer_info(_unreliable_address, false, _unreliable_port, _service, _instance); + check_offer_info(_reliable_address, true, _reliable_port, _service, _instance); + break; + case reliability_type_e::RT_UNKNOWN: + default: + VSOMEIP_WARNING << __func__ << ": unknown offer type [" << std::hex << std::setw(4) + << std::setfill('0') << _service << "." << std::hex << std::setw(4) + << std::setfill('0') << _instance << "]" << static_cast(_offer_type); + break; + } + + return was_unicast; +} + std::shared_ptr -service_discovery_impl::create_subscription( - major_version_t _major, ttl_t _ttl, - const std::shared_ptr &_reliable, - const std::shared_ptr &_unreliable, - const std::shared_ptr &_info) { +service_discovery_impl::create_subscription(major_version_t _major, ttl_t _ttl, + const std::shared_ptr& _reliable, + const std::shared_ptr& _unreliable, + const std::shared_ptr& _info) const { auto its_subscription = std::make_shared(); its_subscription->set_major(_major); its_subscription->set_ttl(_ttl); @@ -3902,5 +3989,13 @@ reliability_type_e service_discovery_impl::get_eventgroup_reliability( return its_reliability; } +void service_discovery_impl::deserialize_data(const byte_t* _data, const length_t& _size, + std::shared_ptr& _message) { + std::lock_guard its_lock(deserialize_mutex_); + deserializer_->set_data(_data, _size); + _message = std::shared_ptr(deserializer_->deserialize_sd_message()); + deserializer_->reset(); +} + } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/tracing/include/connector_impl.hpp b/implementation/tracing/include/connector_impl.hpp index e5c90d2ad..8ea7d610b 100644 --- a/implementation/tracing/include/connector_impl.hpp +++ b/implementation/tracing/include/connector_impl.hpp @@ -71,6 +71,8 @@ class connector_impl : public connector { std::shared_ptr get_channel_impl(const std::string &_id) const; + std::mutex configure_mutex_; + #ifdef USE_DLT #ifndef ANDROID std::map> contexts_; diff --git a/implementation/tracing/src/connector_impl.cpp b/implementation/tracing/src/connector_impl.cpp index 8af23c3fa..02c103268 100644 --- a/implementation/tracing/src/connector_impl.cpp +++ b/implementation/tracing/src/connector_impl.cpp @@ -16,7 +16,7 @@ #include "../include/connector_impl.hpp" #include "../include/defines.hpp" #include "../../configuration/include/trace.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" #ifdef ANDROID #include @@ -37,7 +37,10 @@ namespace trace { const char *VSOMEIP_TC_DEFAULT_CHANNEL_ID = "TC"; +static std::mutex connector_impl_get; + std::shared_ptr connector_impl::get() { + std::scoped_lock lk {connector_impl_get}; static std::shared_ptr instance = std::make_shared(); return instance; } @@ -67,6 +70,7 @@ connector_impl::~connector_impl() { } void connector_impl::configure(const std::shared_ptr &_configuration) { + std::scoped_lock lk {configure_mutex_}; if (_configuration) { is_enabled_ = _configuration->is_enabled_; is_sd_enabled_ = _configuration->is_sd_enabled_; @@ -97,21 +101,25 @@ void connector_impl::configure(const std::shared_ptr &_configuration } VSOMEIP_INFO << "vsomeip tracing " - << (is_enabled_ ? "enabled " : "not enabled. ") - << ". vsomeip service discovery tracing " - << (is_sd_enabled_ ? "enabled " : "not enabled. "); + << (is_enabled_ ? "enabled." : "not enabled.") + << " vsomeip service discovery tracing " + << (is_sd_enabled_ ? "enabled." : "not enabled."); } void connector_impl::reset() { + // reset to default + { + std::scoped_lock its_lock_channels(channels_mutex_); + channels_.clear(); + } #ifdef USE_DLT #ifndef ANDROID - std::lock_guard its_contexts_lock(contexts_mutex_); - contexts_.clear(); + { + std::scoped_lock its_contexts_lock(contexts_mutex_); + contexts_.clear(); + } #endif #endif - // reset to default - std::lock_guard its_lock_channels(channels_mutex_); - channels_.clear(); } void connector_impl::set_enabled(const bool _enabled) { @@ -138,29 +146,34 @@ bool connector_impl::is_sd_message(const byte_t *_data, uint16_t _data_size) con return false; } -std::shared_ptr connector_impl::add_channel( - const trace_channel_t &_id, const std::string &_name) { - std::lock_guard its_channels_lock(channels_mutex_); +std::shared_ptr connector_impl::add_channel(const trace_channel_t& _id, + const std::string& _name) { - // check whether we already know the requested channel - if (channels_.find(_id) != channels_.end()) - return nullptr; + std::shared_ptr its_channel; + { + std::scoped_lock its_channels_lock(channels_mutex_); - // create new channel - std::shared_ptr its_channel - = std::make_shared(_id, _name); + // check whether we already know the requested channel + if (channels_.find(_id) != channels_.end()) + return nullptr; - // add channel - channels_[_id] = its_channel; + // create new channel + its_channel = std::make_shared(_id, _name); + + // add channel + channels_[_id] = its_channel; + } // register context #ifdef USE_DLT #ifndef ANDROID - std::lock_guard its_contexts_lock(contexts_mutex_); - std::shared_ptr its_context = std::make_shared(); - contexts_[_id] = its_context; - DLT_REGISTER_CONTEXT_LL_TS(*(its_context.get()), _id.c_str(), _name.c_str(), - DLT_LOG_INFO, DLT_TRACE_STATUS_ON); + { + std::scoped_lock its_contexts_lock(contexts_mutex_); + std::shared_ptr its_context = std::make_shared(); + contexts_[_id] = its_context; + DLT_REGISTER_CONTEXT_LL_TS(*(its_context.get()), _id.c_str(), _name.c_str(), DLT_LOG_INFO, + DLT_TRACE_STATUS_ON); + } #endif #endif @@ -168,21 +181,28 @@ std::shared_ptr connector_impl::add_channel( } bool connector_impl::remove_channel(const trace_channel_t &_id) { + if (_id == VSOMEIP_TC_DEFAULT_CHANNEL_ID) { // the default channel can not be removed return false; } - std::lock_guard its_channels_lock(channels_mutex_); - bool has_removed = (channels_.erase(_id) == 1); + bool has_removed {false}; + { + std::scoped_lock its_channels_lock(channels_mutex_); + has_removed = (channels_.erase(_id) == 1); + } + if (has_removed) { // unregister context #ifdef USE_DLT #ifndef ANDROID - std::lock_guard its_contexts_lock(contexts_mutex_); - auto its_context = contexts_.find(_id); - if (its_context != contexts_.end()) { - DLT_UNREGISTER_CONTEXT(*(its_context->second.get())); + { + std::scoped_lock its_contexts_lock(contexts_mutex_); + auto its_context = contexts_.find(_id); + if (its_context != contexts_.end()) { + DLT_UNREGISTER_CONTEXT(*(its_context->second.get())); + } } #endif #endif @@ -192,13 +212,13 @@ bool connector_impl::remove_channel(const trace_channel_t &_id) { } std::shared_ptr connector_impl::get_channel(const std::string &_id) const { - std::lock_guard its_channels_lock(channels_mutex_); + std::scoped_lock its_channels_lock(channels_mutex_); auto its_channel = channels_.find(_id); return (its_channel != channels_.end() ? its_channel->second : nullptr); } std::shared_ptr connector_impl::get_channel_impl(const std::string &_id) const { - std::lock_guard its_channels_lock(channels_mutex_); + std::scoped_lock its_channels_lock(channels_mutex_); auto its_channel = channels_.find(_id); return (its_channel != channels_.end() ? its_channel->second : nullptr); } @@ -214,31 +234,24 @@ void connector_impl::trace(const byte_t *_header, uint16_t _header_size, return; // no data // Clip - const uint16_t its_data_size - = uint16_t(_data_size > USHRT_MAX ? USHRT_MAX : _data_size); + uint16_t its_data_size = uint16_t(_data_size > USHRT_MAX ? USHRT_MAX : _data_size); if (is_sd_message(_data, its_data_size) && !is_sd_enabled_) return; // tracing of service discovery messages is disabled! - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); + service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); // Instance is not part of the SOME/IP header, read it from the trace // header - instance_t its_instance = VSOMEIP_BYTES_TO_WORD( - _header[VSOMEIP_TC_INSTANCE_POS_MIN], - _header[VSOMEIP_TC_INSTANCE_POS_MAX]); - - method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - - // Forward to channel if the filter set of the channel allows - std::lock_guard its_channels_lock(channels_mutex_); - #ifndef ANDROID - std::lock_guard its_contexts_lock(contexts_mutex_); - #endif + instance_t its_instance = bithelper::read_uint16_be(&_header[VSOMEIP_TC_INSTANCE_POS_MIN]); + method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); + +// Forward to channel if the filter set of the channel allows +#ifndef ANDROID + std::scoped_lock its_lock(channels_mutex_, contexts_mutex_); +#else + std::scoped_lock its_lock(channels_mutex_); +#endif for (auto its_channel : channels_) { auto ftype = its_channel.second->matches(its_service, its_instance, its_method); if (ftype.first) { diff --git a/implementation/tracing/src/header.cpp b/implementation/tracing/src/header.cpp index bea82c38e..924beab5f 100644 --- a/implementation/tracing/src/header.cpp +++ b/implementation/tracing/src/header.cpp @@ -8,7 +8,7 @@ #include "../include/header.hpp" #include "../../endpoints/include/endpoint.hpp" #include "../../endpoints/include/client_endpoint.hpp" -#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/bithelper.hpp" namespace vsomeip_v3 { namespace trace { @@ -54,17 +54,12 @@ bool header::prepare(const endpoint *_endpoint, bool _is_sending, void header::prepare(const boost::asio::ip::address_v4 &_address, std::uint16_t _port, protocol_e _protocol, bool _is_sending, instance_t _instance) { - unsigned long its_address_as_long = _address.to_ulong(); - data_[0] = VSOMEIP_LONG_BYTE3(its_address_as_long); - data_[1] = VSOMEIP_LONG_BYTE2(its_address_as_long); - data_[2] = VSOMEIP_LONG_BYTE1(its_address_as_long); - data_[3] = VSOMEIP_LONG_BYTE0(its_address_as_long); - data_[4] = VSOMEIP_WORD_BYTE1(_port); - data_[5] = VSOMEIP_WORD_BYTE0(_port); - data_[6] = static_cast(_protocol); - data_[7] = static_cast(_is_sending); - data_[8] = VSOMEIP_WORD_BYTE1(_instance); - data_[9] = VSOMEIP_WORD_BYTE0(_instance); + + bithelper::write_uint32_be((uint32_t)_address.to_ulong(), data_); // [0-3] Address + bithelper::write_uint16_be(_port, &data_[4]); // [4-5] Port + data_[6] = static_cast(_protocol); // [6] Protocol + data_[7] = static_cast(_is_sending); // [7] is_sending + bithelper::write_uint16_be(_instance, &data_[8]); // [8-9] Instance } } // namespace trace diff --git a/implementation/utility/include/bithelper.hpp b/implementation/utility/include/bithelper.hpp new file mode 100644 index 000000000..eae200d3b --- /dev/null +++ b/implementation/utility/include/bithelper.hpp @@ -0,0 +1,134 @@ +// Copyright (C) 2014-2024 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_BITHELPER_HPP +#define VSOMEIP_V3_BITHELPER_HPP + +#include +#include +#include +#include +#include + +namespace vsomeip_v3 { + +class bithelper { +public: + bithelper() = delete; + + //Write Methods + inline static void write_uint16_be(uint16_t _value, uint8_t* _buffer) { + if (get_endianness() != endianess_e::be) { + _value = swap_endianness(_value); + } + std::memcpy(_buffer, reinterpret_cast(&_value), sizeof(_value)); + } + + inline static void write_uint16_le(uint16_t _value, uint8_t* _buffer) { + if (get_endianness() != endianess_e::le) { + _value = swap_endianness(_value); + } + std::memcpy(_buffer, reinterpret_cast(&_value), sizeof(_value)); + } + + inline static void write_uint32_be(uint32_t _value, uint8_t* _buffer) { + if (get_endianness() != endianess_e::be) { + _value = swap_endianness(_value); + } + std::memcpy(_buffer, reinterpret_cast(&_value), sizeof(_value)); + } + + inline static void write_uint32_le(uint32_t _value, uint8_t* _buffer) { + if (get_endianness() != endianess_e::le) { + _value = swap_endianness(_value); + } + std::memcpy(_buffer, reinterpret_cast(&_value), sizeof(_value)); + } + + inline static void write_uint64_be(uint64_t _value, uint8_t* _buffer) { + if (get_endianness() != endianess_e::be) { + _value = swap_endianness(_value); + } + std::memcpy(_buffer, reinterpret_cast(&_value), sizeof(_value)); + } + + inline static void write_uint64_le(uint64_t _value, uint8_t* _buffer) { + if (get_endianness() != endianess_e::le) { + _value = swap_endianness(_value); + } + std::memcpy(_buffer, reinterpret_cast(&_value), sizeof(_value)); + } + + //Read Methods + inline static uint16_t read_uint16_be(const uint8_t* _buffer) { + uint16_t value = 0; + std::memcpy(&value, _buffer, sizeof(value)); + return get_endianness() == endianess_e::be ? value : swap_endianness(value); + } + + inline static uint16_t read_uint16_le(const uint8_t* _buffer) { + uint16_t value = 0; + std::memcpy(&value, _buffer, sizeof(value)); + return get_endianness() == endianess_e::le ? value : swap_endianness(value); + } + + inline static uint32_t read_uint32_be(const uint8_t* _buffer) { + uint32_t value = 0; + std::memcpy(&value, _buffer, sizeof(value)); + return get_endianness() == endianess_e::be ? value : swap_endianness(value); + } + + inline static uint32_t read_uint32_le(const uint8_t* _buffer) { + uint32_t value = 0; + std::memcpy(&value, _buffer, sizeof(value)); + return get_endianness() == endianess_e::le ? value : swap_endianness(value); + } + + inline static uint64_t read_uint64_be(const uint8_t* _buffer) { + uint64_t value = 0; + std::memcpy(&value, _buffer, sizeof(value)); + return get_endianness() == endianess_e::be ? value : swap_endianness(value); + } + + inline static uint64_t read_uint64_le(const uint8_t* _buffer) { + uint64_t value = 0; + std::memcpy(&value, _buffer, sizeof(value)); + return get_endianness() == endianess_e::le ? value : swap_endianness(value); + } + + inline static uint16_t read_high_word(uint32_t input) { + return uint16_t((input >> 16) & 0xFFFF); + } + + inline static uint16_t read_low_word(uint32_t input) { + return uint16_t((input) & 0xFFFF); + } + + template + static T swap_endianness(T _value) { + static_assert(std::is_integral::value, "Only integral types can be swapped"); + T swapped{}; + const auto src = reinterpret_cast(&_value); + auto dst = reinterpret_cast(&swapped); + std::reverse_copy(src, src + sizeof(T), dst); + return swapped; + } + +#if defined(COMPILE_TIME_ENDIAN) && (COMPILE_TIME_ENDIAN == BYTEORDER_LITTLE_ENDIAN) + static constexpr endianess_e get_endianness() { return endianess_e::le; } +#elif defined(COMPILE_TIME_ENDIAN) && (COMPILE_TIME_ENDIAN == BYTEORDER_BIG_ENDIAN) + static constexpr Endianness get_endianness() { return endianess_e::be; } +#else + // Run-time check + static endianess_e get_endianness() { + uint16_t test{0x0102}; + return (*reinterpret_cast(&test) == 1) ? endianess_e::be : endianess_e::le; + } +#endif +}; + +} + +#endif // VSOMEIP_V3_BITHELPER_HPP diff --git a/implementation/utility/include/byteorder.hpp b/implementation/utility/include/byteorder.hpp index f5ad3f024..929033fd6 100644 --- a/implementation/utility/include/byteorder.hpp +++ b/implementation/utility/include/byteorder.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2024 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,73 +6,44 @@ #ifndef VSOMEIP_V3_BYTEORDER_HPP #define VSOMEIP_V3_BYTEORDER_HPP -#if defined(__linux__) -#include -#elif defined(__freebsd__) -#include -#else -// TEST IF THERE COULD BE AN ERROR! -//#error "Undefined OS (only Linux/FreeBSD are currently supported)" -#endif - -#if __BYTE_ORDER == __LITTLE_ENDIAN - -#define VSOMEIP_BYTES_TO_WORD(x0, x1) (uint16_t((x0) << 8 | (x1))) -#define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) (uint32_t((x0) << 24 | (x1) << 16 | (x2) << 8 | (x3))) -#define VSOMEIP_BYTES_TO_LONG_LONG(x0, x1, x2, x3, x4, x5, x6, x7) (uint64_t (x0) << 56 | uint64_t (x1) << 48 | uint64_t (x2) << 40 | uint64_t (x3) << 32 | uint64_t (x4) << 24 | uint64_t (x5) << 16 | uint64_t (x6) << 8 | uint64_t (x7)) - -#define VSOMEIP_WORDS_TO_LONG(x0, x1) (uint32_t((x0) << 16 | (x1))) - -#define VSOMEIP_WORD_BYTE0(x) (uint8_t((x) & 0xFF)) -#define VSOMEIP_WORD_BYTE1(x) (uint8_t((x) >> 8)) - -#define VSOMEIP_LONG_BYTE0(x) (uint8_t((x) & 0xFF)) -#define VSOMEIP_LONG_BYTE1(x) (uint8_t(((x) >> 8) & 0xFF)) -#define VSOMEIP_LONG_BYTE2(x) (uint8_t(((x) >> 16) & 0xFF)) -#define VSOMEIP_LONG_BYTE3(x) (uint8_t(((x) >> 24) & 0xFF)) - -#define VSOMEIP_LONG_LONG_BYTE0(x) (uint8_t((x) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE1(x) (uint8_t(((x) >> 8) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE2(x) (uint8_t(((x) >> 16) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE3(x) (uint8_t(((x) >> 24) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE4(x) (uint8_t(((x) >> 32) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE5(x) (uint8_t(((x) >> 40) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE6(x) (uint8_t(((x) >> 48) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE7(x) (uint8_t(((x) >> 56) & 0xFF)) - -#define VSOMEIP_LONG_WORD0(x) (uint16_t((x) & 0xFFFF)) -#define VSOMEIP_LONG_WORD1(x) (uint16_t(((x) >> 16) & 0xFFFF)) - -#elif __BYTE_ORDER == __BIG_ENDIAN - -#define VSOMEIP_BYTES_TO_WORD(x0, x1) (uint16_t((x1) << 8 | (x0))) -#define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) (uint32_t((x3) << 24 | (x2) << 16 | (x1) << 8 | (x0))) -#define VSOMEIP_BYTES_TO_LONG_LONG(x0, x1, x2, x3, x4, x5, x6, x7) (uint64_t((x7) << 56 | (x6) << 48 | (x5) << 40 | (x4) << 32 | (x3) << 24 | (x2) << 16 | (x1) << 8 | (x0))) - -#define VSOMEIP_WORD_BYTE0(x) (uint8_t((x) >> 8)) -#define VSOMEIP_WORD_BYTE1(x) (uint8_t((x) & 0xFF)) - -#define VSOMEIP_LONG_BYTE0(x) (uint8_t(((x) >> 24) & 0xFF)) -#define VSOMEIP_LONG_BYTE1(x) (uint8_t(((x) >> 16) & 0xFF)) -#define VSOMEIP_LONG_BYTE2(x) (uint8_t(((x) >> 8) & 0xFF)) -#define VSOMEIP_LONG_BYTE3(x) (uint8_t((x) & 0xFF)) - -#define VSOMEIP_LONG_LONG_BYTE0(x) (uint8_t(((x) >> 56) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE1(x) (uint8_t(((x) >> 48) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE2(x) (uint8_t(((x) >> 40) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE3(x) (uint8_t(((x) >> 32) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE4(x) (uint8_t(((x) >> 24) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE5(x) (uint8_t(((x) >> 16) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE6(x) (uint8_t(((x) >> 8) & 0xFF)) -#define VSOMEIP_LONG_LONG_BYTE7(x) (uint8_t((x) & 0xFF)) - -#define VSOMEIP_LONG_WORD0(x) (uint16_t((((x) >> 16) & 0xFFFF)) -#define VSOMEIP_LONG_WORD1(x) (uint16_t(((x) & 0xFFFF)) - -#else - -#error "__BYTE_ORDER is not defined!" - -#endif - -#endif // VSOMEIP_V3_BYTEORDER_HPP_ +#define BYTEORDER_UNKNOWN 0 +#define BYTEORDER_LITTLE_ENDIAN 1 +#define BYTEORDER_BIG_ENDIAN 2 + +// Detect with GCC 4.6's macro +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define COMPILE_TIME_ENDIAN BYTEORDER_LITTLE_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define COMPILE_TIME_ENDIAN BYTEORDER_BIG_ENDIAN +# else +# define COMPILE_TIME_ENDIAN BYTEORDER_UNKNOWN +# endif // __BYTE_ORDER__ +// Detect with GLIBC's endian.h +# elif defined(__GLIBC__) +# include +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define COMPILE_TIME_ENDIAN BYTEORDER_LITTLE_ENDIAN +# elif (__BYTE_ORDER == __BIG_ENDIAN) +# define COMPILE_TIME_ENDIAN BYTEORDER_BIG_ENDIAN +# else +# define COMPILE_TIME_ENDIAN BYTEORDER_UNKNOWN +# endif // __GLIBC__ +// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro +# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) +# define COMPILE_TIME_ENDIAN BYTEORDER_LITTLE_ENDIAN +# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) +# define COMPILE_TIME_ENDIAN BYTEORDER_BIG_ENDIAN +// Detect with architecture macros +# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) +# define COMPILE_TIME_ENDIAN BYTEORDER_BIG_ENDIAN +# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) +# define COMPILE_TIME_ENDIAN BYTEORDER_LITTLE_ENDIAN +# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) +# define COMPILE_TIME_ENDIAN BYTEORDER_LITTLE_ENDIAN +# else +# define COMPILE_TIME_ENDIAN BYTEORDER_UNKNOWN +# endif + + +#endif // VSOMEIP_V3_BYTEORDER_HPP diff --git a/implementation/utility/include/qnx_helper.hpp b/implementation/utility/include/qnx_helper.hpp new file mode 100644 index 000000000..2d390b6fc --- /dev/null +++ b/implementation/utility/include/qnx_helper.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2020-2023 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/. + +#ifdef __QNX__ +#ifndef VSOMEIP_V3_QNX_HELPER_HPP_ +#define VSOMEIP_V3_QNX_HELPER_HPP_ +#include +#include + + #define SO_BINDTODEVICE 0x0800 /* restrict traffic to an interface */ + #define IP_PKTINFO 25 /* int; send interface and src addr */ + +/* Structure used for IP_PKTINFO. */ +#ifndef _STRUCT_IN_PKTINFO +struct in_pktinfo + { + int ipi_ifindex; /* Interface index */ + struct in_addr ipi_spec_dst; /* Routing destination address */ + struct in_addr ipi_addr; /* Header destination address */ + }; +#define _STRUCT_IN_PKTINFO +#endif + + #endif // VSOMEIP_V3_QNX_HELPER_HPP_ + +#endif diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp index cb567ae0e..58eda288c 100644 --- a/implementation/utility/include/utility.hpp +++ b/implementation/utility/include/utility.hpp @@ -150,6 +150,8 @@ class utility { return is_equal; } + static void set_thread_niceness(int _nice) noexcept; + private: struct data_t { data_t(); diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp index e7065f0c8..a274a4ce6 100644 --- a/implementation/utility/src/utility.cpp +++ b/implementation/utility/src/utility.cpp @@ -11,6 +11,7 @@ #include #else #include + #include #include #include #include @@ -25,7 +26,7 @@ #include #include -#include "../include/byteorder.hpp" +#include "../include/bithelper.hpp" #include "../include/utility.hpp" #include "../../configuration/include/configuration.hpp" @@ -47,18 +48,24 @@ uint64_t utility::get_message_size(const byte_t *_data, size_t _size) { uint64_t its_size(0); if (VSOMEIP_SOMEIP_HEADER_SIZE <= _size) { its_size = VSOMEIP_SOMEIP_HEADER_SIZE - + VSOMEIP_BYTES_TO_LONG(_data[4], _data[5], _data[6], _data[7]); + + bithelper::read_uint32_be(&_data[4]); } return its_size; } uint32_t utility::get_payload_size(const byte_t *_data, uint32_t _size) { - uint32_t its_size(0); - if (VSOMEIP_SOMEIP_HEADER_SIZE <= _size) { - its_size = VSOMEIP_BYTES_TO_LONG(_data[4], _data[5], _data[6], _data[7]) - - VSOMEIP_SOMEIP_HEADER_SIZE; - } - return its_size; + if(_size <= VSOMEIP_FULL_HEADER_SIZE) + return 0; + + uint32_t length_ = bithelper::read_uint32_be(&_data[4]); + + if(length_ <= VSOMEIP_SOMEIP_HEADER_SIZE) + return 0; + + if (_size != (VSOMEIP_SOMEIP_HEADER_SIZE + length_)) + return 0; + + return length_ - VSOMEIP_SOMEIP_HEADER_SIZE; } bool utility::is_routing_manager(const std::string &_network) { @@ -281,7 +288,17 @@ void utility::reset_client_ids(const std::string &_network) { } } - +void utility::set_thread_niceness(int _nice) noexcept { +#if defined(__linux__) + errno = 0; + if ((nice(_nice) == -1) && (errno < 0)) { + VSOMEIP_WARNING << "failed to set niceness for thread " << std::this_thread::get_id() << " (error: " << strerror(errno) << ')'; + return; + } +#else + (void)_nice; +#endif +} std::uint16_t utility::get_max_client_number( const std::shared_ptr &_config) { diff --git a/interface/vsomeip/application.hpp b/interface/vsomeip/application.hpp index c7340ba1b..b81c90e69 100644 --- a/interface/vsomeip/application.hpp +++ b/interface/vsomeip/application.hpp @@ -27,6 +27,7 @@ class configuration_public; class event; class payload; struct policy; +class policy_manager; /** * \defgroup vsomeip @@ -178,7 +179,7 @@ class application { * The user application must call this method to withdraw a service offer. * * \param _service Service identifier of the offered service interface. - * \param _instance Instance identifer of the offered service instance. + * \param _instance Instance identifier of the offered service instance. * \param _major Major service version (Default: 0). * \param _minor Minor service version (Default: 0). * @@ -1138,6 +1139,20 @@ class application { instance_t _instance, method_t _method, const message_handler_t &_handler, handler_registration_type_e _type) = 0; + + /** + * \brief Get the configuration + * + * \return configuration shared pointer + */ + virtual std::shared_ptr get_configuration() const = 0; + + /** + * \brief Get the policy_manager + * + * \return policy_manager shared pointer + */ + virtual std::shared_ptr get_policy_manager() const = 0; }; /** @} */ diff --git a/interface/vsomeip/enumeration_types.hpp b/interface/vsomeip/enumeration_types.hpp index 09734b83b..b56690de3 100644 --- a/interface/vsomeip/enumeration_types.hpp +++ b/interface/vsomeip/enumeration_types.hpp @@ -102,6 +102,11 @@ enum class handler_registration_type_e : uint8_t { HRT_UNKNOWN = 0xFF }; +enum class endianess_e { + be, // big-endian + le // little-endian +}; + } // namespace vsomeip_v3 #endif // VSOMEIP_V3_ENUMERATION_TYPES_HPP_ diff --git a/implementation/plugin/include/plugin_manager.hpp b/interface/vsomeip/internal/plugin_manager.hpp similarity index 93% rename from implementation/plugin/include/plugin_manager.hpp rename to interface/vsomeip/internal/plugin_manager.hpp index d398e2457..a8b05b227 100644 --- a/implementation/plugin/include/plugin_manager.hpp +++ b/interface/vsomeip/internal/plugin_manager.hpp @@ -23,6 +23,7 @@ class plugin_manager { VSOMEIP_EXPORT virtual void * load_library(const std::string &_path) = 0; VSOMEIP_EXPORT virtual void * load_symbol(void * _handle, const std::string &_symbol) = 0; VSOMEIP_EXPORT virtual void unload_library(void * _handle) = 0; + VSOMEIP_EXPORT virtual bool unload_plugin(plugin_type_e _type) = 0; }; } // namespace vsomeip_v3 diff --git a/interface/vsomeip/internal/policy_manager.hpp b/interface/vsomeip/internal/policy_manager.hpp index 0d610d9ef..5be22f3e1 100644 --- a/interface/vsomeip/internal/policy_manager.hpp +++ b/interface/vsomeip/internal/policy_manager.hpp @@ -19,21 +19,18 @@ struct policy; class VSOMEIP_IMPORT_EXPORT policy_manager { public: - static std::shared_ptr get(); - - virtual ~policy_manager() {}; - + virtual ~policy_manager() {} virtual std::shared_ptr create_policy() const = 0; virtual void print_policy(const std::shared_ptr &_policy) const = 0; virtual bool parse_uid_gid(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid) const = 0; + uid_t &_uid, gid_t &_gid) const = 0; virtual bool parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, + uid_t &_uid, gid_t &_gid, const std::shared_ptr &_policy) const = 0; - virtual bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const = 0; - virtual bool is_policy_removal_allowed(uint32_t _uid) const = 0; + virtual bool is_policy_update_allowed(uid_t _uid, std::shared_ptr &_policy) const = 0; + virtual bool is_policy_removal_allowed(uid_t _uid) const = 0; }; } // namespace vsomeip_v3 diff --git a/interface/vsomeip/primitive_types.hpp b/interface/vsomeip/primitive_types.hpp index 0fbce3c45..a609f33ff 100644 --- a/interface/vsomeip/primitive_types.hpp +++ b/interface/vsomeip/primitive_types.hpp @@ -56,7 +56,7 @@ typedef std::uint32_t pending_remote_offer_id_t; typedef std::uint32_t pending_security_update_id_t; -#if defined(_WIN32) || defined(__QNX__) +#if defined(_WIN32) typedef std::uint32_t uid_t; typedef std::uint32_t gid_t; #else diff --git a/interface/vsomeip/vsomeip_sec.h b/interface/vsomeip/vsomeip_sec.h index 0d269127e..aadcf374d 100644 --- a/interface/vsomeip/vsomeip_sec.h +++ b/interface/vsomeip/vsomeip_sec.h @@ -29,13 +29,9 @@ typedef uint32_t gid_t; #endif typedef struct { -#ifdef __QNX__ - uint32_t user; - uint32_t group; -#else uid_t user; gid_t group; -#endif + vsomeip_sec_ip_addr_t host; vsomeip_sec_network_port_t port; // VSOMEIP_SEC_PORT_UNUSED --> UDS; ]0, VSOMEIP_SEC_PORT_UNSET] --> TCP } vsomeip_sec_client_t; diff --git a/libvsomeip.yaml b/libvsomeip.yaml index 0ad6b7426..eccc62c2a 100644 --- a/libvsomeip.yaml +++ b/libvsomeip.yaml @@ -1,5 +1,5 @@ - name: libvsomeip - version: 3.4.10 + version: 3.5.1 vendor: Lynx Team license: concluded: CLOSED and MPLv2 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f66ac5d33..87a099fd0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -127,13 +127,13 @@ add_dependencies(build_tests build_benchmark_tests) ############################################################################## add_subdirectory(common EXCLUDE_FROM_ALL) -add_subdirectory( network_tests EXCLUDE_FROM_ALL ) +add_subdirectory(network_tests EXCLUDE_FROM_ALL) if (NOT DISABLE_SECURITY) - add_subdirectory( unit_tests EXCLUDE_FROM_ALL ) + add_subdirectory(unit_tests EXCLUDE_FROM_ALL) if(benchmark_FOUND) - add_subdirectory( benchmark_tests EXCLUDE_FROM_ALL ) + add_subdirectory(benchmark_tests EXCLUDE_FROM_ALL) endif() endif() diff --git a/test/bat_tests/excluded_tests.txt b/test/bat_tests/excluded_tests.txt index 17daa05a1..d90fe5681 100644 --- a/test/bat_tests/excluded_tests.txt +++ b/test/bat_tests/excluded_tests.txt @@ -14,7 +14,7 @@ big_payload_test_local_tcp_queue_limited big_payload_test_local_tcp_limited big_payload_test_local_tcp_random big_payload_test_local_tcp -configuration-test +configuration_test client_id_test_diff_client_ids_diff_ports client_id_test_diff_client_ids_same_ports client_id_test_diff_client_ids_partial_same_ports diff --git a/test/benchmark_tests/CMakeLists.txt b/test/benchmark_tests/CMakeLists.txt index ebc51f917..e223c5ec5 100644 --- a/test/benchmark_tests/CMakeLists.txt +++ b/test/benchmark_tests/CMakeLists.txt @@ -9,8 +9,6 @@ file (GLOB SRCS main.cpp **/*.cpp) set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) -find_package(Boost 1.55 COMPONENTS filesystem system REQUIRED) # ---------------------------------------------------------------------------- # Executable and libraries to link diff --git a/test/common/CMakeLists.txt b/test/common/CMakeLists.txt index d4d145347..f74f17f35 100644 --- a/test/common/CMakeLists.txt +++ b/test/common/CMakeLists.txt @@ -38,3 +38,7 @@ target_include_directories ( PUBLIC include PRIVATE src ) + +if (MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) +endif () diff --git a/test/common/include/common/test_timer.hpp b/test/common/include/common/test_timer.hpp new file mode 100644 index 000000000..ffeb89c4a --- /dev/null +++ b/test/common/include/common/test_timer.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2024 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 TEST_TIMER_HPP +#define TEST_TIMER_HPP + +#include + +class test_timer_t { +public: + test_timer_t(std::chrono::milliseconds target_) : + target(target_), start(std::chrono::high_resolution_clock::now()) { } + test_timer_t(std::chrono::seconds target_) : + target(std::chrono::duration_cast(target_)), + start(std::chrono::high_resolution_clock::now()) { } + + bool has_elapsed() { + const auto current = std::chrono::high_resolution_clock::now(); + return target <= std::chrono::duration_cast(current - start); + } + +private: + std::chrono::milliseconds target; + std::chrono::system_clock::time_point start; +}; + +#endif // TEST_TIMER_HPP diff --git a/test/common/include/common/utility.hpp b/test/common/include/common/utility.hpp index 1fe896fe3..35f6e9273 100644 --- a/test/common/include/common/utility.hpp +++ b/test/common/include/common/utility.hpp @@ -4,6 +4,9 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include + +#include "../../../implementation/configuration/include/configuration_impl.hpp" +#include "../../../implementation/routing/include/routing_manager_impl.hpp" #include "../../../implementation/security/include/policy_manager_impl.hpp" #include "../../../implementation/configuration/include/configuration_impl.hpp" #include "../../../implementation/utility/include/utility.hpp" diff --git a/test/internal_routing_disabled_acceptance_test/CMakeLists.txt b/test/internal_routing_disabled_acceptance_test/CMakeLists.txt index 574c6981b..2c2021fb5 100644 --- a/test/internal_routing_disabled_acceptance_test/CMakeLists.txt +++ b/test/internal_routing_disabled_acceptance_test/CMakeLists.txt @@ -13,9 +13,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Threads REQUIRED) -find_package(Boost 1.55 COMPONENTS system REQUIRED) - add_executable(${PROJECT_NAME} applet.cpp client.cpp server.cpp main.cpp) target_include_directories(${PROJECT_NAME} PRIVATE ${gtest_SOURCE_DIR}/include) target_link_libraries(${PROJECT_NAME} PRIVATE gtest Threads::Threads vsomeip3 ${Boost_LIBRARIES}) diff --git a/test/internal_routing_disabled_acceptance_test/client.cpp b/test/internal_routing_disabled_acceptance_test/client.cpp index e0825b379..afe960f57 100644 --- a/test/internal_routing_disabled_acceptance_test/client.cpp +++ b/test/internal_routing_disabled_acceptance_test/client.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "config.hpp" @@ -37,22 +38,22 @@ client::init() { switch(message->get_message_type()) { case vsomeip_v3::message_type_e::MT_RESPONSE: - std::cout - << "received:\n" - << "\tservice: " << std::hex << message->get_service() << '\n' - << "\tinstance: " << std::hex << message->get_instance() << '\n' - << "\tmethod: " << std::hex << message->get_method() << '\n' - << "\tpayload: " << payload->get_data() << '\n'; + VSOMEIP_INFO << "received:\n" + << "\tservice: " << std::hex << message->get_service() << '\n' + << "\tinstance: " << std::hex << message->get_instance() << '\n' + << "\tmethod: " << std::hex << message->get_method() << '\n' + << "\tpayload: " << payload->get_data(); me->counter_method_response++; break; case vsomeip_v3::message_type_e::MT_NOTIFICATION: - std::cout << "GOT NOTIFICATION\n"; + VSOMEIP_INFO << "GOT NOTIFICATION"; me->counter_event_received++; [[fallthrough]]; default: - std::cout << "unhandled message type: " << unsigned(message->get_message_type()) << '\n'; + VSOMEIP_ERROR << "unhandled message type: " + << unsigned(message->get_message_type()); } } } @@ -64,11 +65,8 @@ client::init() { [its_me](vsomeip_v3::service_t service, vsomeip_v3::instance_t instance, bool available){ auto me = its_me.lock(); if (me) { - std::cout - << __func__ << '(' - << std::hex << service << ", " - << std::hex << instance << ", " - << std::boolalpha << available << ")\n"; + VSOMEIP_INFO << __func__ << '('<< std::hex << service << ", " << std::hex + << instance << ", " << std::boolalpha << available << ")"; if(service != config::SERVICE_ID) return; @@ -91,7 +89,7 @@ client::init() { for(int i = 0; i < 10; i++) { - std::cout << "sending: " << str << '\n'; + VSOMEIP_INFO << "sending: " << str; me->application->send(request); me->counter_method_request++; @@ -174,5 +172,5 @@ void client::on_state_registered() void client::on_state_deregistered() { - std::cout << "Client is deregistered!!! Probably could not be registered!!!\n"; + VSOMEIP_WARNING << "Client is deregistered!!! Probably could not be registered!!!"; } diff --git a/test/internal_routing_disabled_acceptance_test/server.cpp b/test/internal_routing_disabled_acceptance_test/server.cpp index 5ba7a18b4..ebc3ec518 100644 --- a/test/internal_routing_disabled_acceptance_test/server.cpp +++ b/test/internal_routing_disabled_acceptance_test/server.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "config.hpp" @@ -35,7 +36,7 @@ server::init() { switch(message->get_message_type()) { case vsomeip_v3::message_type_e::MT_REQUEST: - std::cout << "GOT REQUEST\n"; + VSOMEIP_INFO << "GOT REQUEST"; me->counter_method_request++; { std::shared_ptr response = runtime->create_response(message); @@ -56,7 +57,8 @@ server::init() { break; default: - std::cout << "unhandled message type: " << unsigned(message->get_message_type()) << '\n'; + VSOMEIP_ERROR << "unhandled message type: " + << unsigned(message->get_message_type()); } } } @@ -142,5 +144,5 @@ void server::on_state_registered() void server::on_state_deregistered() { - std::cout << "Server is deregistered!!! Probably could not be registered!!!\n"; + VSOMEIP_WARNING << "Server is deregistered!!! Probably could not be registered!!!"; } diff --git a/test/network_tests/CMakeLists.txt b/test/network_tests/CMakeLists.txt index 883cc5cf8..1481260dc 100644 --- a/test/network_tests/CMakeLists.txt +++ b/test/network_tests/CMakeLists.txt @@ -11,655 +11,52 @@ include_directories( ${gtest_SOURCE_DIR}/include ) - set(TEST_LINK_LIBRARIES gtest) +if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") + set(TEST_LINK_LIBRARIES ${TEST_LINK_LIBRARIES} socket) +endif() set(NETWORK_TEST_BIN_DIR ${PROJECT_BINARY_DIR}/test/network_tests) set(NETWORK_TEST_SRC_DIR ${PROJECT_SOURCE_DIR}/test/network_tests) - -# Function to copy files into the build directory (or anywhere else) -# On unixoid systems this function will create symlinks instead -# SOURCE_PATH: Path to the file which should be copied -# DESTINATION_PATH: destination file -# TARGET_TO_DEPEND: The copying of the file will be added as -# a dependency to this target -function(copy_to_builddir SOURCE_PATH DESTINATION_PATH TARGET_TO_DEPEND) - if(${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR NOT ${TEST_SYMLINK_CONFIG_FILES}) - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - COMMAND ${CMAKE_COMMAND} -E copy "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Copying \"${SOURCE_PATH}\" into build directory" - ) - else() - if(${TEST_SYMLINK_CONFIG_FILES_RELATIVE}) - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - # Create a relative link - COMMAND ln -s -r "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" - ) - else() - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - # Create an absolute link - COMMAND ${CMAKE_COMMAND} -E create_symlink "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" - ) - endif() - endif() - # Add a random number to the end of the string to avoid problems with - # duplicate filenames - set(FILENAME "") - get_filename_component(FILENAME ${SOURCE_PATH} NAME ) - string(RANDOM LENGTH 4 ALPHABET 0123456789 RANDOMNUMBER) - if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - ADD_CUSTOM_TARGET(copy_${FILENAME}_${RANDOMNUMBER} - DEPENDS "${DESTINATION_PATH}" - ) - ADD_DEPENDENCIES(${TARGET_TO_DEPEND} copy_${FILENAME}_${RANDOMNUMBER}) - else() - ADD_CUSTOM_TARGET(symlink_${FILENAME}_${RANDOMNUMBER} - DEPENDS "${DESTINATION_PATH}" +set(HOSTNAME "$ENV{HOSTNAME}") + +# Configures the given files into the build folder. +# +# This function looks for files in the `conf` folder with the same name as the +# given files, and ending in `.in`. It will then copy these files into the build +# folder, and replace variables marked with @VARIABLE@ with their actual value. +# +# # Example +# +# set(configuration_files +# my_test_config.json +# my_test_starter.sh +# ) +# configure_files("${configuration_files}") +function(configure_files files) + foreach(item ${files}) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/conf/${item}.in + ${CMAKE_CURRENT_BINARY_DIR}/${item} + @ONLY ) - ADD_DEPENDENCIES(${TARGET_TO_DEPEND} symlink_${FILENAME}_${RANDOMNUMBER}) - endif() + endforeach() endfunction() -############################################################################## -# configuration-test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_CONFIGURATION configuration-test) - - add_executable(${TEST_CONFIGURATION} - configuration_tests/configuration-test.cpp - ${PROJECT_SOURCE_DIR}/implementation/plugin/src/plugin_manager_impl.cpp - ) - target_link_libraries(${TEST_CONFIGURATION} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # The following will make sure that ${TEST_CONFIGURATION_CONFIG_FILE} is copied - # from the config folder into the test folder in the builddirectory - # This makes it possible to call the configuration test within the build directory - set(TEST_CONFIGURATION_CONFIG_FILE configuration-test.json) - set(TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE configuration-test-deprecated.json) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/configuration_tests/${TEST_CONFIGURATION_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CONFIGURATION_CONFIG_FILE} - ${TEST_CONFIGURATION} - ) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/configuration_tests/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} - ${TEST_CONFIGURATION} - ) -endif() -############################################################################## -# application test -############################################################################## -set(TEST_APPLICATION application_test) - -add_executable(${TEST_APPLICATION} application_tests/${TEST_APPLICATION}.cpp) -target_link_libraries(${TEST_APPLICATION} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) -if(NOT ${TESTS_BAT}) - set(TEST_APPLICATION_SINGLE_PROCESS_NAME ${TEST_APPLICATION}_single_process) - add_executable(${TEST_APPLICATION_SINGLE_PROCESS_NAME} application_tests/${TEST_APPLICATION_SINGLE_PROCESS_NAME}.cpp) - target_link_libraries(${TEST_APPLICATION_SINGLE_PROCESS_NAME} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - if(QNX) - target_compile_definitions(${TEST_APPLICATION_SINGLE_PROCESS_NAME} PRIVATE _QNX_SOURCE) - endif() - - set(TEST_APPLICATION_AVAILABILITY_NAME ${TEST_APPLICATION}_availability) - add_executable(${TEST_APPLICATION_AVAILABILITY_NAME} application_tests/${TEST_APPLICATION_AVAILABILITY_NAME}.cpp) - target_link_libraries(${TEST_APPLICATION_AVAILABILITY_NAME} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE ${TEST_APPLICATION}_single_process.json) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} - ${TEST_APPLICATION}_single_process - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_STARTER ${TEST_APPLICATION}_single_process_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ${TEST_APPLICATION}_single_process - ) - - set(TEST_APPLICATION_AVAILABILITY_STARTER ${TEST_APPLICATION_AVAILABILITY_NAME}_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_AVAILABILITY_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_AVAILABILITY_STARTER} - ${TEST_APPLICATION_SINGLE_PROCESS_NAME} - ) -endif() - -set(TEST_APPLICATION_CONFIGURATION_FILE ${TEST_APPLICATION}.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE}.in - ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} - @ONLY) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_CONFIGURATION_FILE} - ${TEST_APPLICATION} -) - -set(TEST_APPLICATION_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_daemon.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON}.in - ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - @ONLY) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - ${TEST_APPLICATION} -) - -set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE ${TEST_APPLICATION}_no_dispatch_threads.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE}.in - ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - @ONLY) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - ${TEST_APPLICATION} -) - -set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_no_dispatch_threads_daemon.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON}.in - ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - @ONLY) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - ${TEST_APPLICATION} -) - -set(TEST_APPLICATION_STARTER ${TEST_APPLICATION}_starter.sh) - if(${TESTS_BAT}) - configure_file( - ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_STARTER}.bat.in - ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_STARTER} - @ONLY) - endif() - -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_STARTER} -${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_STARTER} -${TEST_APPLICATION} -) - -############################################################################## -# magic-cookies-test-client -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_MAGIC_COOKIES_NAME magic_cookies_test) - - set(TEST_MAGIC_COOKIES_CLIENT ${TEST_MAGIC_COOKIES_NAME}_client) - add_executable(${TEST_MAGIC_COOKIES_CLIENT} magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT}.cpp) - target_link_libraries(${TEST_MAGIC_COOKIES_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_MAGIC_COOKIES_SERVICE ${TEST_MAGIC_COOKIES_NAME}_service) - add_executable(${TEST_MAGIC_COOKIES_SERVICE} magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE}.cpp) - target_link_libraries(${TEST_MAGIC_COOKIES_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${DLT_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE ${TEST_MAGIC_COOKIES_CLIENT}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT ${TEST_MAGIC_COOKIES_CLIENT}_start.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - set(TEST_MAGIC_COOKIES_SERVICE magic_cookies_test_service) - # Copy config file for service into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE ${TEST_MAGIC_COOKIES_SERVICE}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - ${TEST_MAGIC_COOKIES_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT ${TEST_MAGIC_COOKIES_SERVICE}_start.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_MAGIC_COOKIES_STARTER ${TEST_MAGIC_COOKIES_NAME}_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_STARTER} - ${TEST_MAGIC_COOKIES_CLIENT} - ) -endif() -############################################################################## -# someip-header-factory-test -############################################################################## -set(TEST_HEADER_FACTORY_NAME header_factory_test) - -set(TEST_HEADER_FACTORY header_factory_test) -add_executable(${TEST_HEADER_FACTORY} header_factory_tests/header_factory_test.cpp) -target_link_libraries(${TEST_HEADER_FACTORY} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) - -############################################################################## -# Now comes the second part of the header factory test which consists of a client -# and a service both with settings file and bash scripts to start them -set(TEST_HEADER_FACTORY_CLIENT header_factory_test_client) -add_executable(${TEST_HEADER_FACTORY_CLIENT} header_factory_tests/${TEST_HEADER_FACTORY_CLIENT}.cpp) -target_link_libraries(${TEST_HEADER_FACTORY_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) - -# Copy config file for client into $BUILDDIR/test -set(TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE ${TEST_HEADER_FACTORY_CLIENT}.json) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} - ${TEST_HEADER_FACTORY_CLIENT} -) - -# Copy bashscript to start client into $BUILDDIR/test -set(TEST_HEADER_FACTORY_CLIENT_START_SCRIPT ${TEST_HEADER_FACTORY_CLIENT}_start.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} - ${TEST_HEADER_FACTORY_CLIENT} -) - -set(TEST_HEADER_FACTORY_SERVICE header_factory_test_service) -add_executable(${TEST_HEADER_FACTORY_SERVICE} header_factory_tests/${TEST_HEADER_FACTORY_SERVICE}.cpp) -target_link_libraries(${TEST_HEADER_FACTORY_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) - -# Copy config file for service into $BUILDDIR/test -set(TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE ${TEST_HEADER_FACTORY_SERVICE}.json) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} - ${TEST_HEADER_FACTORY_SERVICE} -) - -# Copy bashscript to start service into $BUILDDIR/test -set(TEST_HEADER_FACTORY_SERVICE_START_SCRIPT ${TEST_HEADER_FACTORY_SERVICE}_start.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} - ${TEST_HEADER_FACTORY_SERVICE} -) - -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_HEADER_FACTORY_STARTER header_factory_test_send_receive_starter.sh) - -if(${TESTS_BAT}) - configure_file( - ${NETWORK_TEST_SRC_DIR}/header_factory_tests/conf/${TEST_HEADER_FACTORY_STARTER}.bat.in - ${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_STARTER} - @ONLY) -endif() - -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_STARTER} - ${TEST_HEADER_FACTORY_CLIENT} -) - -############################################################################## -# routing-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_LOCAL_ROUTING_NAME local_routing_test) - - set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) - add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) - add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter_qnx.sh) - else() - set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) - endif() - configure_file( - ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.in - ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - ############################################################################## - set(TEST_EXTERNAL_LOCAL_ROUTING_NAME external_local_routing_test) - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE external_local_routing_test_service) - add_executable(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start external client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT external_local_routing_test_client_external) - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_STARTER external_local_routing_test_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) -else() - set(TEST_LOCAL_ROUTING_NAME local_routing_test) - - set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) - add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) - add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) - configure_file( - ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.bat.in - ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} - ${TEST_LOCAL_ROUTING_CLIENT} - ) -endif() -############################################################################## -# restart_routing-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_RESTART_ROUTING_NAME restart_routing_test) - - set(TEST_RESTART_ROUTING_SERVICE restart_routing_test_service) - add_executable(${TEST_RESTART_ROUTING_SERVICE} restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_RESTART_ROUTING_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE ${TEST_RESTART_ROUTING_SERVICE}.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_RESTART_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_RESTART_ROUTING_SERVICE_START_SCRIPT ${TEST_RESTART_ROUTING_SERVICE}_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} - ${TEST_RESTART_ROUTING_SERVICE} - ) - - set(TEST_RESTART_ROUTING_CLIENT restart_routing_test_client) - add_executable(${TEST_RESTART_ROUTING_CLIENT} - restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT}.cpp - ) - target_link_libraries(${TEST_RESTART_ROUTING_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE ${TEST_RESTART_ROUTING_CLIENT}.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_RESTART_ROUTING_CLIENT_START_SCRIPT ${TEST_RESTART_ROUTING_CLIENT}_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_RESTART_ROUTING_STARTER restart_routing_test_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_STARTER} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy config file for autoconfig into $BUILDDIR/test - set(TEST_RESTART_ROUTING_AUTO_CONFIG_FILE ${TEST_RESTART_ROUTING_NAME}_autoconfig.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} - ${TEST_RESTART_ROUTING_CLIENT} - ) -endif() - -############################################################################## -# security test -############################################################################## - -if (${TEST_SECURITY}) - if(NOT ${TESTS_BAT}) - set(TEST_SECURITY_NAME security_test) - set(TEST_SECURITY_SERVICE security_test_service) - set(TEST_SECURITY_CLIENT security_test_client) - - add_executable(${TEST_SECURITY_SERVICE} security_tests/${TEST_SECURITY_SERVICE}.cpp) - target_link_libraries(${TEST_SECURITY_SERVICE} +# Links the given targets to the default libraries. +# +# These include libraries that are used by nearly every test, such as vsomeip, +# boost, gtest, etc. +# +# # Example +# +# set(executables +# my_test_service +# my_test_client +# ) +# targets_link_default_libraries("${executables}") +function(targets_link_default_libraries targets) + foreach(target ${targets}) + target_link_libraries(${target} ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${DL_LIBRARY} @@ -667,4376 +64,120 @@ if (${TEST_SECURITY}) ${DLT_LIBRARIES} vsomeip_utilities ) + endforeach() +endfunction() - # Copy config file for service into $BUILDDIR/test - set(TEST_SECURITY_LOCAL_CONFIG_FILE ${TEST_SECURITY_NAME}_local_config.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_LOCAL_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_LOCAL_CONFIG_FILE} - ${TEST_SECURITY_SERVICE} - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_service_external_allow.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_SECURITY_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_client_external_allow.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_SECURITY_SERVICE} - ) +# Adds build dependencies to the given targets. +# +# These ensure that the targets will be built alongside `gtest` and +# `build_network_tests` targets. +# +# # Example +# +# set(executables +# my_test_service +# my_test_client +# ) +# targets_add_default_dependencies("${executables}") +function(targets_add_default_dependencies targets) + foreach(target ${targets}) + add_dependencies(${target} gtest) + add_dependencies(build_network_tests ${target}) + endforeach() +endfunction() - # Copy service config file for external deny tests into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_service_external_deny.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY}.in - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - ${TEST_SECURITY_SERVICE} - ) +# Adds a custom command to be called by ctest. +# +# Options include timeouts and environment variables. +# +# Handles the necessary steps to allow calling the test with valgrind, etc. +# +# # Example +# +# add_custom_test( +# NAME my_test_name +# COMMAND ${CMAKE_CURRENT_BINARY_DIR}/my_test_starter.sh ARG1 ARG2... +# TIMEOUT 60 # Optional. Defaults to 120s. +# ENVIRONMENT VSOMEIP_CONFIGURATION=my_test_config.json # Optional. +# ) +function(add_custom_test) + set(options "") + set(oneValueArgs NAME TIMEOUT) + set(multiValueArgs COMMAND ENVIRONMENT) + cmake_parse_arguments(MY_TEST + "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} + ) - # Copy client config file for external deny tests into $BUILDDIR/test - set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_client_external_deny.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY}.in - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - ${TEST_SECURITY_SERVICE} - ) + # Replace "test_name" in TEST_ENTRYPOINT with the actual test name. + string(REPLACE + "test_name" "${MY_TEST_NAME}" custom_test_entrypoint "${TEST_ENTRYPOINT}" + ) - # Copy bashscript to start local test into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT ${TEST_SECURITY_NAME}_local_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) + # Add a custom test command. + add_test( + NAME ${MY_TEST_NAME} + COMMAND ${custom_test_entrypoint} ${MY_TEST_COMMAND} + ) - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT ${TEST_SECURITY_NAME}_external_master_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) + if(NOT MY_TEST_TIMEOUT) + # Set the default timeout to 120 seconds. + set(MY_TEST_TIMEOUT 120) + endif() - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT ${TEST_SECURITY_NAME}_external_slave_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) + # Set a timeout for the test. + set_tests_properties(${MY_TEST_NAME} + PROPERTIES TIMEOUT ${MY_TEST_TIMEOUT} + ) - add_executable(${TEST_SECURITY_CLIENT} - security_tests/${TEST_SECURITY_CLIENT}.cpp - ) - target_link_libraries(${TEST_SECURITY_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities + if(MY_TEST_ENVIRONMENT) + # Set environment variables for the test. + set_property( + TEST ${MY_TEST_NAME} + APPEND PROPERTY ENVIRONMENT + "${MY_TEST_ENVIRONMENT}" ) endif() -endif() - -############################################################################## -# payload-test -############################################################################## - -set(TEST_LOCAL_PAYLOAD_NAME local_payload_test) - -set(TEST_PAYLOAD_SERVICE payload_test_service) -add_executable(${TEST_PAYLOAD_SERVICE} payload_tests/${TEST_PAYLOAD_SERVICE}.cpp) -target_link_libraries(${TEST_PAYLOAD_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) - -# Copy config file for service into $BUILDDIR/test -set(TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE local_${TEST_PAYLOAD_SERVICE}.json) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_PAYLOAD_SERVICE} -) - -# Copy bashscript to start service into $BUILDDIR/test -set(TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT local_${TEST_PAYLOAD_SERVICE}_start.sh) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} -) - -set(TEST_PAYLOAD_CLIENT payload_test_client) -add_executable(${TEST_PAYLOAD_CLIENT} - payload_tests/${TEST_PAYLOAD_CLIENT}.cpp - payload_tests/stopwatch.cpp -) -target_link_libraries(${TEST_PAYLOAD_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) - -# Copy config file for client into $BUILDDIR/test -set(TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE local_${TEST_PAYLOAD_CLIENT}.json) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} -) - -# Copy bashscript to start client into $BUILDDIR/test -set(TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT local_${TEST_PAYLOAD_CLIENT}_start.sh) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} -) - -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_LOCAL_PAYLOAD_STARTER local_payload_test_starter.sh) - -if(${TESTS_BAT}) - configure_file( - ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_LOCAL_PAYLOAD_STARTER}.bat.in - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_STARTER} - @ONLY) -endif() - -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_STARTER} - ${TEST_PAYLOAD_CLIENT} -) - -############################################################################## -set(TEST_EXTERNAL_LOCAL_PAYLOAD_NAME external_local_payload_test) -set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE external_local_payload_test_service) - -# Copy config file for service into $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_PAYLOAD_SERVICE} -) - -# Copy bashscript to start service into $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}_start.sh) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} -) - -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL external_local_payload_test_client_local) - -# Copy config file for client into $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} -) - -# Copy bashscript to start client into $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}_start.sh) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} -) - -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME external_local_payload_test_client_local) -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME}_starter.sh) - -if(${TESTS_BAT}) - configure_file( - ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER}.bat.in - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - @ONLY) -endif() - -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ${TEST_PAYLOAD_CLIENT} -) -############################################################################## -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME external_local_payload_test_client_external) -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL external_local_payload_test_client_external) - -# Copy config file for client into $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} -) - -# Copy bashscript to start client into $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}_start.sh) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} -) - -set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL external_local_payload_test_service_client_external) - -# Copy bashscript to start service into $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL}_start.sh) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} -) - -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME}_starter.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ${TEST_PAYLOAD_CLIENT} -) - -############################################################################## -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME external_local_payload_test_client_local_and_external) -set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME}_starter.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ${TEST_PAYLOAD_CLIENT} -) - -############################################################################## -set(TEST_LOCAL_PAYLOAD_HUGE_NAME local_payload_test_huge_payload) -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_LOCAL_PAYLOAD_HUGE_STARTER ${TEST_LOCAL_PAYLOAD_HUGE_NAME}_starter.sh) - -if(${TESTS_BAT}) - configure_file( - ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_LOCAL_PAYLOAD_HUGE_STARTER}.bat.in - ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - @ONLY) -endif() - -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ${TEST_PAYLOAD_CLIENT} -) - -############################################################################## -# big_payload_test -############################################################################## - -set(TEST_BIG_PAYLOAD_NAME big_payload_test) - -set(TEST_BIG_PAYLOAD_SERVICE big_payload_test_service) -add_executable(${TEST_BIG_PAYLOAD_SERVICE} big_payload_tests/${TEST_BIG_PAYLOAD_SERVICE}.cpp) -target_link_libraries(${TEST_BIG_PAYLOAD_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) - -set(TEST_BIG_PAYLOAD_CLIENT big_payload_test_client) -add_executable(${TEST_BIG_PAYLOAD_CLIENT} big_payload_tests/${TEST_BIG_PAYLOAD_CLIENT}.cpp) -target_link_libraries(${TEST_BIG_PAYLOAD_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local.json) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_queue_limited.json) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_random.json) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_limited.json) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_limited.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_limited.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_queue_limited.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_queue_limited.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} -) +endfunction() -# Copy config file for client and service into $BUILDDIR/test -set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_random.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_random.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_client.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_service.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_client_limited_general.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_service_limited_general.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_client_random.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_service_random.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_general.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_general.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_specific.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -# Copy config file for client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_specific.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${TEST_BIG_PAYLOAD_SERVICE} -) -# Copy config file for UDP client and service into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_service.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} -) -set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_client.json) -configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - @ONLY) -copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -# Copy bashscript to start client local to $BUILDDIR/test -set(TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_local_start.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -# Copy bashscript to start service local to $BUILDDIR/test -set(TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_service_local_start.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_LOCAL_BIG_PAYLOAD_NAME big_payload_test_local) -set(TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_random) -set(TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_limited) -set(TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_queue_limited) -set(TEST_LOCAL_BIG_PAYLOAD_STARTER ${TEST_LOCAL_BIG_PAYLOAD_NAME}_starter.sh) - -if(${TESTS_BAT}) - configure_file( - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_BIG_PAYLOAD_STARTER}.bat.in - ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - @ONLY) -endif() - -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy bashscript to start client and server $BUILDDIR/test -set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME big_payload_test_local_tcp) -set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_tcp_random) -set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_tcp_limited) -set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_tcp_queue_limited) -# Copy starter as well as client/service start scripts for external tests -set(TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME}_starter.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} - ${TEST_BIG_PAYLOAD_SERVICE} -) -set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME}_service_start.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -# Copy bashscript to start client for external test into $BUILDDIR/test -set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external) -set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_external_random) -set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_external_limited) -set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL big_payload_test_external_limited_general) -set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL big_payload_test_external_queue_limited_general) -set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC big_payload_test_external_queue_limited_specific) -set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP big_payload_test_external_udp) - -# Copy starter as well as client/service start scripts for external tests -set(TEST_EXTERNAL_BIG_PAYLOAD_STARTER ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_starter.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ${TEST_BIG_PAYLOAD_SERVICE} -) -set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_service_start.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_BIG_PAYLOAD_SERVICE} -) - -set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_client_start.sh) -copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_BIG_PAYLOAD_CLIENT} -) - -############################################################################## -# client id tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_CLIENT_ID_NAME client_id_test) - set(TEST_CLIENT_ID_SERVICE ${TEST_CLIENT_ID_NAME}_service) - add_executable(${TEST_CLIENT_ID_SERVICE} client_id_tests/${TEST_CLIENT_ID_NAME}_service.cpp) - target_link_libraries(${TEST_CLIENT_ID_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_CLIENT_ID_UTILITY ${TEST_CLIENT_ID_NAME}_utility) - add_executable(${TEST_CLIENT_ID_UTILITY} - client_id_tests/${TEST_CLIENT_ID_UTILITY}.cpp) - #${PROJECT_SOURCE_DIR}/implementation/utility/src/utility.cpp) - target_link_libraries(${TEST_CLIENT_ID_UTILITY} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_UTILITY_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - set(TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_511.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_4095.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_127.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_discontinuous_masked_511.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - # copy starter scripts into builddir - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_CLIENT_ID_MASTER_STARTER ${TEST_CLIENT_ID_NAME}_master_starter_qnx.sh) - else() - set(TEST_CLIENT_ID_MASTER_STARTER ${TEST_CLIENT_ID_NAME}_master_starter.sh) - endif() - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} - ${TEST_CLIENT_ID_SERVICE} - ) - set(TEST_CLIENT_ID_SLAVE_STARTER ${TEST_CLIENT_ID_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SLAVE_STARTER} - ${TEST_CLIENT_ID_SERVICE} - ) -endif() - -############################################################################## -# debounce tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_DEBOUNCE_NAME debounce_test) - set(TEST_DEBOUNCE_CLIENT ${TEST_DEBOUNCE_NAME}_client) - add_executable(${TEST_DEBOUNCE_CLIENT} debounce_tests/${TEST_DEBOUNCE_CLIENT}.cpp) - target_link_libraries(${TEST_DEBOUNCE_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - set(TEST_DEBOUNCE_SERVICE ${TEST_DEBOUNCE_NAME}_service) - add_executable(${TEST_DEBOUNCE_SERVICE} debounce_tests/${TEST_DEBOUNCE_SERVICE}.cpp) - target_link_libraries(${TEST_DEBOUNCE_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # copy starter scripts into builddir - set(TEST_DEBOUNCE_MASTER_STARTER ${TEST_DEBOUNCE_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_STARTER} - ${TEST_DEBOUNCE_SERVICE} - ) - set(TEST_DEBOUNCE_SLAVE_STARTER ${TEST_DEBOUNCE_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_SLAVE_STARTER} - ${TEST_DEBOUNCE_SERVICE} - ) - - # configure configurations and copy them into builddir - set(TEST_DEBOUNCE_MASTER_CONFIG_FILE ${TEST_DEBOUNCE_SERVICE}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_tests/conf/${TEST_DEBOUNCE_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} - ${TEST_DEBOUNCE_SERVICE} - ) - set(TEST_DEBOUNCE_SLAVE_CONFIG_FILE ${TEST_DEBOUNCE_CLIENT}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_tests/conf/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} - ${TEST_DEBOUNCE_SERVICE} - ) -endif() - -############################################################################## -# debounce filter tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_DEBOUNCE_FILTER_NAME debounce_filter_test) - set(TEST_DEBOUNCE_FILTER_CLIENT ${TEST_DEBOUNCE_FILTER_NAME}_client) - add_executable(${TEST_DEBOUNCE_FILTER_CLIENT} debounce_filter_tests/${TEST_DEBOUNCE_FILTER_CLIENT}.cpp) - target_link_libraries(${TEST_DEBOUNCE_FILTER_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - set(TEST_DEBOUNCE_FILTER_SERVICE ${TEST_DEBOUNCE_FILTER_NAME}_service) - add_executable(${TEST_DEBOUNCE_FILTER_SERVICE} debounce_filter_tests/${TEST_DEBOUNCE_FILTER_SERVICE}.cpp) - target_link_libraries(${TEST_DEBOUNCE_FILTER_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # copy starter scripts into builddir - set(TEST_DEBOUNCE_FILTER_MASTER_STARTER ${TEST_DEBOUNCE_FILTER_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/${TEST_DEBOUNCE_FILTER_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FILTER_MASTER_STARTER} - ${TEST_DEBOUNCE_FILTER_SERVICE} - ) - set(TEST_DEBOUNCE_FILTER_SLAVE_STARTER ${TEST_DEBOUNCE_FILTER_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/${TEST_DEBOUNCE_FILTER_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FILTER_SLAVE_STARTER} - ${TEST_DEBOUNCE_FILTER_SERVICE} - ) - - # configure configurations and copy them into builddir - set(TEST_DEBOUNCE_FILTER_MASTER_CONFIG_FILE ${TEST_DEBOUNCE_FILTER_SERVICE}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/conf/${TEST_DEBOUNCE_FILTER_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/${TEST_DEBOUNCE_FILTER_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/${TEST_DEBOUNCE_FILTER_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FILTER_MASTER_CONFIG_FILE} - ${TEST_DEBOUNCE_FILTER_SERVICE} - ) - set(TEST_DEBOUNCE_FILTER_SLAVE_CONFIG_FILE ${TEST_DEBOUNCE_FILTER_CLIENT}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/conf/${TEST_DEBOUNCE_FILTER_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/${TEST_DEBOUNCE_FILTER_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_filter_tests/${TEST_DEBOUNCE_FILTER_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FILTER_SLAVE_CONFIG_FILE} - ${TEST_DEBOUNCE_FILTER_SERVICE} - ) -endif() - -############################################################################## -# debounce frequency tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_DEBOUNCE_FREQUENCY_NAME debounce_frequency_test) - set(TEST_DEBOUNCE_FREQUENCY_CLIENT ${TEST_DEBOUNCE_FREQUENCY_NAME}_client) - add_executable(${TEST_DEBOUNCE_FREQUENCY_CLIENT} debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_CLIENT}.cpp) - target_link_libraries(${TEST_DEBOUNCE_FREQUENCY_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip_utilities - ) - set(TEST_DEBOUNCE_FREQUENCY_SERVICE ${TEST_DEBOUNCE_FREQUENCY_NAME}_service) - add_executable(${TEST_DEBOUNCE_FREQUENCY_SERVICE} debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_SERVICE}.cpp) - target_link_libraries(${TEST_DEBOUNCE_FREQUENCY_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip_utilities - ) - - # copy starter scripts into builddir - set(TEST_DEBOUNCE_FREQUENCY_MASTER_STARTER ${TEST_DEBOUNCE_FREQUENCY_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FREQUENCY_MASTER_STARTER} - ${TEST_DEBOUNCE_FREQUENCY_CLIENT} - ) - set(TEST_DEBOUNCE_FREQUENCY_SLAVE_STARTER ${TEST_DEBOUNCE_FREQUENCY_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FREQUENCY_SLAVE_STARTER} - ${TEST_DEBOUNCE_FREQUENCY_SERVICE} - ) - - # configure configurations and copy them into builddir - set(TEST_DEBOUNCE_FREQUENCY_MASTER_CONFIG_FILE ${TEST_DEBOUNCE_FREQUENCY_CLIENT}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/conf/${TEST_DEBOUNCE_FREQUENCY_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FREQUENCY_MASTER_CONFIG_FILE} - ${TEST_DEBOUNCE_FREQUENCY_CLIENT} - ) - set(TEST_DEBOUNCE_FREQUENCY_SLAVE_CONFIG_FILE ${TEST_DEBOUNCE_FREQUENCY_SERVICE}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/conf/${TEST_DEBOUNCE_FREQUENCY_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_frequency_tests/${TEST_DEBOUNCE_FREQUENCY_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FREQUENCY_SLAVE_CONFIG_FILE} - ${TEST_DEBOUNCE_FREQUENCY_SERVICE} - ) -endif() - -############################################################################## -# debounce callback tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_DEBOUNCE_CALLBACK_NAME debounce_callback_test) - set(TEST_DEBOUNCE_CALLBACK_CLIENT ${TEST_DEBOUNCE_CALLBACK_NAME}_client) - add_executable(${TEST_DEBOUNCE_CALLBACK_CLIENT} debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_CLIENT}.cpp) - target_link_libraries(${TEST_DEBOUNCE_CALLBACK_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - set(TEST_DEBOUNCE_CALLBACK_SERVICE ${TEST_DEBOUNCE_CALLBACK_NAME}_service) - add_executable(${TEST_DEBOUNCE_CALLBACK_SERVICE} debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_SERVICE}.cpp) - target_link_libraries(${TEST_DEBOUNCE_CALLBACK_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # copy starter scripts into builddir - set(TEST_DEBOUNCE_CALLBACK_MASTER_STARTER ${TEST_DEBOUNCE_CALLBACK_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_CALLBACK_MASTER_STARTER} - ${TEST_DEBOUNCE_CALLBACK_SERVICE} - ) - set(TEST_DEBOUNCE_CALLBACK_SLAVE_STARTER ${TEST_DEBOUNCE_CALLBACK_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_CALLBACK_SLAVE_STARTER} - ${TEST_DEBOUNCE_CALLBACK_CLIENT} - ) - - # configure configurations and copy them into builddir - set(TEST_DEBOUNCE_CALLBACK_MASTER_CONFIG_FILE ${TEST_DEBOUNCE_CALLBACK_SERVICE}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/conf/${TEST_DEBOUNCE_CALLBACK_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_CALLBACK_MASTER_CONFIG_FILE} - ${TEST_DEBOUNCE_CALLBACK_SERVICE} - ) - set(TEST_DEBOUNCE_CALLBACK_SLAVE_CONFIG_FILE ${TEST_DEBOUNCE_CALLBACK_CLIENT}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/conf/${TEST_DEBOUNCE_CALLBACK_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/debounce_callback_tests/${TEST_DEBOUNCE_CALLBACK_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_CALLBACK_SLAVE_CONFIG_FILE} - ${TEST_DEBOUNCE_CALLBACK_CLIENT} - ) -endif() - -############################################################################## -# subscribe notify tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_SUBSCRIBE_NOTIFY_NAME subscribe_notify_test) - set(TEST_SUBSCRIBE_NOTIFY_SERVICE ${TEST_SUBSCRIBE_NOTIFY_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_SERVICE} subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_NAME}_service.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config files for test into $BUILDDIR/test (local communication via UDS) - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - # copy starter scripts into builddir - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter_qnx.sh) - else() - set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) - endif() - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - # subscribe_notify_test_one_event_two_eventgroups - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME subscribe_notify_test_one_event_two_eventgroups) - - # service - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - # client - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_client) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - - # Copy config files for test into $BUILDDIR/test (local communication via TCP) - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - # copy starter scripts into builddir - set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave_local_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - -endif() - -############################################################################## -# subscribe notify one tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_SUBSCRIBE_NOTIFY_ONE_NAME subscribe_notify_one_test) - set(TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - # copy starter scripts into builddir - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_master_starter_qnx.sh) - else() - set(TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_master_starter.sh) - endif() - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) -endif() - -############################################################################## -# cpu-load-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_CPU_LOAD_NAME cpu_load_test) - - set(TEST_CPU_LOAD_SERVICE cpu_load_test_service) - add_executable(${TEST_CPU_LOAD_SERVICE} - cpu_load_tests/${TEST_CPU_LOAD_SERVICE}.cpp - cpu_load_tests/cpu_load_measurer.cpp - ) - target_link_libraries(${TEST_CPU_LOAD_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - ${TEST_CPU_LOAD_SERVICE} - ) - set(TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - ${TEST_CPU_LOAD_SERVICE} - ) - - ############################################################################## - set(TEST_CPU_LOAD_CLIENT cpu_load_test_client) - add_executable(${TEST_CPU_LOAD_CLIENT} - cpu_load_tests/${TEST_CPU_LOAD_CLIENT}.cpp - cpu_load_tests/cpu_load_measurer.cpp - ) - target_link_libraries(${TEST_CPU_LOAD_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - ${TEST_CPU_LOAD_CLIENT} - ) - set(TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - ${TEST_CPU_LOAD_CLIENT} - ) - - ############################################################################## - # copy starter scripts into builddir - set(TEST_CPU_LOAD_MASTER_STARTER ${TEST_CPU_LOAD_NAME}_master_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_MASTER_STARTER} - ${TEST_CPU_LOAD_SERVICE} - ) - set(TEST_CPU_LOAD_SLAVE_STARTER ${TEST_CPU_LOAD_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SLAVE_STARTER} - ${TEST_CPU_LOAD_SERVICE} - ) -endif() - -############################################################################## -# initial event tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_INITIAL_EVENT_NAME initial_event_test) - set(TEST_INITIAL_EVENT_SERVICE ${TEST_INITIAL_EVENT_NAME}_service) - add_executable(${TEST_INITIAL_EVENT_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_service.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_INITIAL_EVENT_CLIENT ${TEST_INITIAL_EVENT_NAME}_client) - add_executable(${TEST_INITIAL_EVENT_CLIENT} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_client.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_INITIAL_EVENT_AVAILABILITY_CHECKER ${TEST_INITIAL_EVENT_NAME}_availability_checker) - add_executable(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_availability_checker.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_INITIAL_EVENT_STOP_SERVICE ${TEST_INITIAL_EVENT_NAME}_stop_service) - add_executable(${TEST_INITIAL_EVENT_STOP_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_stop_service.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_STOP_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # copy starter scripts into builddir - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_INITIAL_EVENT_MASTER_STARTER ${TEST_INITIAL_EVENT_NAME}_master_starter_qnx.sh) - else() - set(TEST_INITIAL_EVENT_MASTER_STARTER ${TEST_INITIAL_EVENT_NAME}_master_starter.sh) - endif() - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} - ${TEST_INITIAL_EVENT_SERVICE} - ) - set(TEST_INITIAL_EVENT_SLAVE_STARTER ${TEST_INITIAL_EVENT_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SLAVE_STARTER} - ${TEST_INITIAL_EVENT_SERVICE} - ) -endif() - -############################################################################## -# offer tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_OFFER_NAME offer_test) - set(TEST_OFFER_SERVICE ${TEST_OFFER_NAME}_service) - add_executable(${TEST_OFFER_SERVICE} offer_tests/${TEST_OFFER_NAME}_service.cpp) - target_link_libraries(${TEST_OFFER_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_OFFER_MULTIPLE_OFFERING offer_test_multiple_offerings) - add_executable(${TEST_OFFER_MULTIPLE_OFFERING} offer_tests/${TEST_OFFER_MULTIPLE_OFFERING}.cpp) - target_link_libraries(${TEST_OFFER_MULTIPLE_OFFERING} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # copy starter scripts into builddir - set(TEST_OFFER_MULTIPLE_OFFERING_STARTER ${TEST_OFFER_MULTIPLE_OFFERING}_starter.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MULTIPLE_OFFERING_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_MULTIPLE_OFFERING_STARTER} - ${TEST_OFFER_MULTIPLE_OFFERING} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_OFFER_MULTIPLE_OFFERING_CONFIG ${TEST_OFFER_MULTIPLE_OFFERING}.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MULTIPLE_OFFERING_CONFIG} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_MULTIPLE_OFFERING_CONFIG} - ${TEST_OFFER_MULTIPLE_OFFERING} - ) - - set(TEST_OFFER_CLIENT ${TEST_OFFER_NAME}_client) - add_executable(${TEST_OFFER_CLIENT} offer_tests/${TEST_OFFER_NAME}_client.cpp) - target_link_libraries(${TEST_OFFER_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_OFFER_SERVICE_EXTERNAL ${TEST_OFFER_NAME}_service_external) - add_executable(${TEST_OFFER_SERVICE_EXTERNAL} offer_tests/${TEST_OFFER_NAME}_service_external.cpp) - target_link_libraries(${TEST_OFFER_SERVICE_EXTERNAL} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER ${TEST_OFFER_NAME}_external_sd_msg_sender) - add_executable(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} offer_tests/${TEST_OFFER_NAME}_external_sd_msg_sender.cpp) - target_link_libraries(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # client and service for offer test big sd msg - set(TEST_OFFER_BIG_NAME offer_test_big_sd_msg) - set(TEST_OFFER_BIG_SERVICE ${TEST_OFFER_BIG_NAME}_service) - add_executable(${TEST_OFFER_BIG_SERVICE} offer_tests/${TEST_OFFER_BIG_NAME}_service.cpp) - target_link_libraries(${TEST_OFFER_BIG_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_OFFER_BIG_CLIENT ${TEST_OFFER_BIG_NAME}_client) - add_executable(${TEST_OFFER_BIG_CLIENT} offer_tests/${TEST_OFFER_BIG_NAME}_client.cpp) - target_link_libraries(${TEST_OFFER_BIG_CLIENT} - ${DLT_LIBRARIES} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip_utilities - ) - - # copy starter scripts into builddir - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_OFFER_LOCAL_STARTER ${TEST_OFFER_NAME}_local_starter_qnx.sh) - else() - set(TEST_OFFER_LOCAL_STARTER ${TEST_OFFER_NAME}_local_starter.sh) - endif() - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_LOCAL_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_STARTER} - ${TEST_OFFER_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_OFFER_LOCAL_CONFIG_FILE ${TEST_OFFER_NAME}_local.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_LOCAL_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - # generate and copy json files into builddir for external test - set(TEST_OFFER_SLAVE_CONFIG_FILE ${TEST_OFFER_NAME}_external_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_SLAVE_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - set(TEST_OFFER_MASTER_CONFIG_FILE ${TEST_OFFER_NAME}_external_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_MASTER_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - # generate and copy json files into builddir for big SD message test - set(TEST_OFFER_BIG_SLAVE_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_slave.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - ${TEST_OFFER_BIG_SERVICE} - ) - - set(TEST_OFFER_BIG_MASTER_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - ${TEST_OFFER_BIG_SERVICE} - ) - - # Copy starter scripts for external test to $BUILDDIR/test - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_OFFER_EXTERNAL_MASTER_STARTER ${TEST_OFFER_NAME}_external_master_starter_qnx.sh) - else() - set(TEST_OFFER_EXTERNAL_MASTER_STARTER ${TEST_OFFER_NAME}_external_master_starter.sh) - endif() - configure_file( - ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_EXTERNAL_MASTER_STARTER}.in - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - ${TEST_OFFER_SERVICE} - ) - set(TEST_OFFER_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_NAME}_external_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} - ${TEST_OFFER_SERVICE} - ) - - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_BIG_MASTER_STARTER ${TEST_OFFER_BIG_NAME}_master_starter.sh) - configure_file( - ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_MASTER_STARTER}.in - ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_STARTER} - ${TEST_OFFER_BIG_SERVICE} - ) - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_BIG_NAME}_slave_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} - ${TEST_OFFER_BIG_SERVICE} - ) -endif() - -############################################################################## -# offered services info tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_OFFERED_SERVICES_INFO_NAME offered_services_info_test) - set(TEST_OFFERED_SERVICES_INFO_SERVICE ${TEST_OFFERED_SERVICES_INFO_NAME}_service) - add_executable(${TEST_OFFERED_SERVICES_INFO_SERVICE} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_service.cpp) - target_link_libraries(${TEST_OFFERED_SERVICES_INFO_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_OFFERED_SERVICES_INFO_CLIENT ${TEST_OFFERED_SERVICES_INFO_NAME}_client) - add_executable(${TEST_OFFERED_SERVICES_INFO_CLIENT} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_client.cpp) - target_link_libraries(${TEST_OFFERED_SERVICES_INFO_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # copy starter scripts into builddir - set(TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER ${TEST_OFFERED_SERVICES_INFO_NAME}_local_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} - ${TEST_OFFERED_SERVICES_INFO_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE ${TEST_OFFERED_SERVICES_INFO_NAME}_local.json) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} - ${TEST_OFFERED_SERVICES_INFO_SERVICE} - ) -endif() - -############################################################################## -# pending subscription tests tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_PENDING_SUBSCRIPTION_NAME pending_subscription_test) - set(TEST_PENDING_SUBSCRIPTION_SERVICE ${TEST_PENDING_SUBSCRIPTION_NAME}_service) - add_executable(${TEST_PENDING_SUBSCRIPTION_SERVICE} pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_service.cpp) - target_link_libraries(${TEST_PENDING_SUBSCRIPTION_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - file(GLOB sd_sources - "../../implementation/service_discovery/src/*entry*.cpp" - "../../implementation/service_discovery/src/*option*.cpp" - "../../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_PENDING_SUBSCRIPTION_CLIENT ${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender) - add_executable(${TEST_PENDING_SUBSCRIPTION_CLIENT} - pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_PENDING_SUBSCRIPTION_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-sd - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # copy starter scripts into builddir - set(TEST_PENDING_SUBSCRIPTION_MASTER_STARTER ${TEST_PENDING_SUBSCRIPTION_NAME}_master_starter.sh) - configure_file( - ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER}.in - ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - ${TEST_PENDING_SUBSCRIPTION_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_PENDING_SUBSCRIPTION_CONFIG_FILE ${TEST_PENDING_SUBSCRIPTION_NAME}_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - ${TEST_PENDING_SUBSCRIPTION_SERVICE} - ) -endif() - -############################################################################## -# malicious data tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_MALICIOUS_DATA_NAME malicious_data_test) - set(TEST_MALICIOUS_DATA_SERVICE ${TEST_MALICIOUS_DATA_NAME}_service) - add_executable(${TEST_MALICIOUS_DATA_SERVICE} malicious_data_tests/${TEST_MALICIOUS_DATA_NAME}_service.cpp) - target_link_libraries(${TEST_MALICIOUS_DATA_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - file(GLOB sd_sources - "../../implementation/service_discovery/src/*entry*.cpp" - "../../implementation/service_discovery/src/*option*.cpp" - "../../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_MALICIOUS_DATA_CLIENT ${TEST_MALICIOUS_DATA_NAME}_msg_sender) - add_executable(${TEST_MALICIOUS_DATA_CLIENT} - malicious_data_tests/${TEST_MALICIOUS_DATA_CLIENT}.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_MALICIOUS_DATA_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-sd - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # copy starter scripts into builddir - set(TEST_MALICIOUS_DATA_MASTER_STARTER ${TEST_MALICIOUS_DATA_NAME}_master_starter.sh) - configure_file( - ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_MASTER_STARTER}.in - ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} - ${TEST_MALICIOUS_DATA_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_MALICIOUS_DATA_CONFIG_FILE ${TEST_MALICIOUS_DATA_NAME}_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_CONFIG_FILE} - ${TEST_MALICIOUS_DATA_SERVICE} - ) -endif() - -############################################################################## -# e2e test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_E2E_NAME e2e_test) - set(TEST_E2E_SERVICE e2e_test_service) - set(TEST_E2E_CLIENT e2e_test_client) - - add_executable(${TEST_E2E_SERVICE} e2e_tests/${TEST_E2E_SERVICE}.cpp) - target_link_libraries(${TEST_E2E_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - add_executable(${TEST_E2E_CLIENT} - e2e_tests/${TEST_E2E_CLIENT}.cpp - ) - target_link_libraries(${TEST_E2E_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_service_external.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_client_external.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_E2E_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_NAME}_external_master_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_E2E_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_NAME}_external_slave_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_E2E_SERVICE} - ) -endif() - -############################################################################## -# e2e profile 04 test -############################################################################## - -if(NOT ${TESTS_BAT} AND ${TEST_E2E_PROFILE_04}) - set(TEST_E2E_PROFILE_04_NAME e2e_profile_04_test) - set(TEST_E2E_PROFILE_04_SERVICE e2e_profile_04_test_service) - set(TEST_E2E_PROFILE_04_CLIENT e2e_profile_04_test_client) - - add_executable(${TEST_E2E_PROFILE_04_SERVICE} e2e_tests/${TEST_E2E_PROFILE_04_SERVICE}.cpp) - target_link_libraries(${TEST_E2E_PROFILE_04_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - add_executable(${TEST_E2E_PROFILE_04_CLIENT} - e2e_tests/${TEST_E2E_PROFILE_04_CLIENT}.cpp - ) - target_link_libraries(${TEST_E2E_PROFILE_04_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_service_external.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_client_external.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_master_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_slave_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_E2E_PROFILE_04_SERVICE} - ) -endif() - -############################################################################## -# e2e profile 07 test -############################################################################## - -if(NOT ${TESTS_BAT} AND ${TEST_E2E_PROFILE_07}) - set(TEST_E2E_PROFILE_07_NAME e2e_profile_07_test) - set(TEST_E2E_PROFILE_07_SERVICE e2e_profile_07_test_service) - set(TEST_E2E_PROFILE_07_CLIENT e2e_profile_07_test_client) - - add_executable(${TEST_E2E_PROFILE_07_SERVICE} e2e_tests/${TEST_E2E_PROFILE_07_SERVICE}.cpp) - target_link_libraries(${TEST_E2E_PROFILE_07_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - add_executable(${TEST_E2E_PROFILE_07_CLIENT} - e2e_tests/${TEST_E2E_PROFILE_07_CLIENT}.cpp - ) - target_link_libraries(${TEST_E2E_PROFILE_07_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_07_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_07_NAME}_service_external.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_07_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_07_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_07_SERVICE_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_07_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_07_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_07_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_07_NAME}_client_external.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_07_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_07_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_07_CLIENT_CONFIG_FILE_EXTERNAL} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_07_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_07_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_E2E_PROFILE_07_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_PROFILE_07_NAME}_external_master_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_07_EXTERNAL_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_07_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_E2E_PROFILE_07_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_E2E_PROFILE_07_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_PROFILE_07_NAME}_external_slave_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_07_EXTERNAL_SLAVE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_07_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_E2E_PROFILE_07_SERVICE} - ) -endif() - -############################################################################## -# event tests -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_EVENT_NAME event_test) - set(TEST_EVENT_SERVICE ${TEST_EVENT_NAME}_service) - set(TEST_EVENT_CLIENT ${TEST_EVENT_NAME}_client) - - add_executable(${TEST_EVENT_SERVICE} event_tests/${TEST_EVENT_SERVICE}.cpp) - target_link_libraries(${TEST_EVENT_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - add_executable(${TEST_EVENT_CLIENT} - event_tests/${TEST_EVENT_CLIENT}.cpp - ) - target_link_libraries(${TEST_EVENT_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_EVENT_SLAVE_TCP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_tcp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - ${TEST_EVENT_SERVICE} - ) - - set(TEST_EVENT_SLAVE_UDP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - ${TEST_EVENT_SERVICE} - ) - - set(TEST_EVENT_MASTER_CONFIG_FILE ${TEST_EVENT_NAME}_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_CONFIG_FILE} - ${TEST_EVENT_CLIENT} - ) - - # Copy bashscript to start test (master) into $BUILDDIR/test - set(TEST_EVENT_MASTER_START_SCRIPT ${TEST_EVENT_NAME}_master_starter.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} - ${TEST_EVENT_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_EVENT_SLAVE_START_SCRIPT ${TEST_EVENT_NAME}_slave_starter.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_START_SCRIPT} - ${TEST_EVENT_CLIENT} - ) - -endif() - -############################################################################## -# npdu-test -############################################################################## -if(NOT ${TESTS_BAT} AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "QNX") - set(TEST_NPDU_NAME npdu_test) - - set(TEST_NPDU_DAEMON npdu_test_rmd) - set(TEST_NPDU_DAEMON_CLIENT ${TEST_NPDU_DAEMON}_client_side) - add_executable(${TEST_NPDU_DAEMON_CLIENT} npdu_tests/${TEST_NPDU_DAEMON}.cpp) - set_target_properties(${TEST_NPDU_DAEMON_CLIENT} PROPERTIES COMPILE_FLAGS -DRMD_CLIENT_SIDE) - target_link_libraries(${TEST_NPDU_DAEMON_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_NPDU_DAEMON_SERVICE ${TEST_NPDU_DAEMON}_service_side) - add_executable(${TEST_NPDU_DAEMON_SERVICE} npdu_tests/${TEST_NPDU_DAEMON}.cpp) - set_target_properties(${TEST_NPDU_DAEMON_SERVICE} PROPERTIES COMPILE_FLAGS -DRMD_SERVICE_SIDE) - target_link_libraries(${TEST_NPDU_DAEMON_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - ############################################################################## - - set(TEST_NPDU_SERVICE npdu_test_service) - - set(TEST_NPDU_SERVICE_ONE npdu_test_service_1) - add_executable(${TEST_NPDU_SERVICE_ONE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_ONE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=0) - target_link_libraries(${TEST_NPDU_SERVICE_ONE} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_NPDU_SERVICE_TWO npdu_test_service_2) - add_executable(${TEST_NPDU_SERVICE_TWO} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_TWO} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=1) - target_link_libraries(${TEST_NPDU_SERVICE_TWO} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_NPDU_SERVICE_THREE npdu_test_service_3) - add_executable(${TEST_NPDU_SERVICE_THREE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_THREE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=2) - target_link_libraries(${TEST_NPDU_SERVICE_THREE} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_NPDU_SERVICE_FOUR npdu_test_service_4) - add_executable(${TEST_NPDU_SERVICE_FOUR} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_FOUR} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=3) - target_link_libraries(${TEST_NPDU_SERVICE_FOUR} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config file for service w/o npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_no_npdu.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy bashscript to start service w/o npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_no_npdu_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_START_SCRIPT} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy config file for service with npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_npdu.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy bashscript to start service with npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_npdu_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_START_SCRIPT} - ${TEST_NPDU_SERVICE_ONE} - ) - - ############################################################################## - - set(TEST_NPDU_CLIENT npdu_test_client) - - set(TEST_NPDU_CLIENT_ONE npdu_test_client_1) - add_executable(${TEST_NPDU_CLIENT_ONE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_ONE} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_NPDU_CLIENT_TWO npdu_test_client_2) - add_executable(${TEST_NPDU_CLIENT_TWO} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_TWO} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_NPDU_CLIENT_THREE npdu_test_client_3) - add_executable(${TEST_NPDU_CLIENT_THREE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_THREE} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_NPDU_CLIENT_FOUR npdu_test_client_4) - add_executable(${TEST_NPDU_CLIENT_FOUR} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_FOUR} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - # Copy config files for client w/o npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_no_npdu.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy bashscript to start client w/o npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_no_npdu_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_START_SCRIPT} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy config file for client with npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_npdu.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy bashscript to start client with npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_npdu_start.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_START_SCRIPT} - ${TEST_NPDU_CLIENT_ONE} - ) - - ############################################################################## - - set(TEST_NPDU_STARTER ${TEST_NPDU_NAME}_starter.sh) - copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_STARTER} - ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} - ${TEST_NPDU_DAEMON_CLIENT} - ) -endif() - -############################################################################## -# someip tp tests -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_SOMEIPTP_NAME someip_tp_test) - set(TEST_SOMEIPTP_SERVICE ${TEST_SOMEIPTP_NAME}_service) - - add_executable(${TEST_SOMEIPTP_SERVICE} someip_tp_tests/${TEST_SOMEIPTP_SERVICE}.cpp) - target_link_libraries(${TEST_SOMEIPTP_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - file(GLOB sd_sources - "../../implementation/service_discovery/src/*entry*.cpp" - "../../implementation/service_discovery/src/*option*.cpp" - "../../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_SOMEIPTP_CLIENT ${TEST_SOMEIPTP_NAME}_msg_sender) - add_executable(${TEST_SOMEIPTP_CLIENT} - someip_tp_tests/${TEST_SOMEIPTP_CLIENT}.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_reassembler.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_message.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_SOMEIPTP_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - ${VSOMEIP_NAME} - ${VSOMEIP_NAME}-sd - vsomeip_utilities - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_SOMEIPTP_MASTER_CONFIG_FILE ${TEST_SOMEIPTP_NAME}_master.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - ${TEST_SOMEIPTP_CLIENT} - ) - - # Copy bashscript to start test (master) into $BUILDDIR/test - set(TEST_SOMEIPTP_MASTER_START_SCRIPT ${TEST_SOMEIPTP_NAME}_master_starter.sh) - configure_file( - ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_START_SCRIPT}.in - ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - ${TEST_SOMEIPTP_SERVICE} - ) -endif() - -############################################################################## -# second IP address tests -############################################################################## - -if(NOT ${TESTS_BAT} AND ${TEST_SECOND_ADDRESS}) - set(TEST_SECOND_ADDRESS_NAME second_address_test) - set(TEST_SECOND_ADDRESS_SERVICE ${TEST_SECOND_ADDRESS_NAME}_service) - set(TEST_SECOND_ADDRESS_CLIENT ${TEST_SECOND_ADDRESS_NAME}_client) - - add_executable(${TEST_SECOND_ADDRESS_SERVICE} - second_address_tests/${TEST_SECOND_ADDRESS_SERVICE}.cpp - ) - target_link_libraries(${TEST_SECOND_ADDRESS_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - add_executable(${TEST_SECOND_ADDRESS_CLIENT} - second_address_tests/${TEST_SECOND_ADDRESS_CLIENT}.cpp - ) - target_link_libraries(${TEST_SECOND_ADDRESS_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_service_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_client.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_CLIENT} - ) - - set(TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_client.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_CLIENT} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_service_udp.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_MASTER_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_master_starter.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_slave_starter.sh) - configure_file( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT}.in - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - ${TEST_SECOND_ADDRESS_CLIENT} - ) -endif() - -############################################################################## -# suspend resume tests -############################################################################## -if(NOT ${TESTS_BAT}) - - set(TEST_SUSPEND_RESUME_NAME suspend_resume_test) - set(TEST_SUSPEND_RESUME_SERVICE ${TEST_SUSPEND_RESUME_NAME}_service) - set(TEST_SUSPEND_RESUME_CLIENT ${TEST_SUSPEND_RESUME_NAME}_client) - - add_executable(${TEST_SUSPEND_RESUME_SERVICE} - suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE}.cpp - ) - target_link_libraries(${TEST_SUSPEND_RESUME_SERVICE} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - add_executable(${TEST_SUSPEND_RESUME_CLIENT} - suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT}.cpp - ) - target_link_libraries(${TEST_SUSPEND_RESUME_CLIENT} - ${VSOMEIP_NAME} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ${DLT_LIBRARIES} - vsomeip_utilities - ) - - set(TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE ${TEST_SUSPEND_RESUME_SERVICE}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE ${TEST_SUSPEND_RESUME_CLIENT}.json) - configure_file( - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE}.in - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_MASTER_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_master_starter.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_slave_starter.sh) - copy_to_builddir( - ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} - ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - -endif() - -############################################################################## -# Add for every test a dependency to gtest -############################################################################## - -if(NOT ${TESTS_BAT}) - add_dependencies(${TEST_CONFIGURATION} gtest) - add_dependencies(${TEST_APPLICATION} gtest) - add_dependencies(${TEST_APPLICATION_SINGLE_PROCESS_NAME} gtest) - add_dependencies(${TEST_APPLICATION_AVAILABILITY_NAME} gtest) - add_dependencies(${TEST_MAGIC_COOKIES_CLIENT} gtest) - add_dependencies(${TEST_MAGIC_COOKIES_SERVICE} gtest) - add_dependencies(${TEST_HEADER_FACTORY} gtest) - add_dependencies(${TEST_HEADER_FACTORY_CLIENT} gtest) - add_dependencies(${TEST_HEADER_FACTORY_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) - add_dependencies(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_CLIENT_ID_SERVICE} gtest) - add_dependencies(${TEST_CLIENT_ID_UTILITY} gtest) - add_dependencies(${TEST_DEBOUNCE_CLIENT} gtest) - add_dependencies(${TEST_DEBOUNCE_SERVICE} gtest) - add_dependencies(${TEST_DEBOUNCE_FILTER_CLIENT} gtest) - add_dependencies(${TEST_DEBOUNCE_FILTER_SERVICE} gtest) - add_dependencies(${TEST_DEBOUNCE_CALLBACK_CLIENT} gtest) - add_dependencies(${TEST_DEBOUNCE_CALLBACK_SERVICE} gtest) - add_dependencies(${TEST_DEBOUNCE_FREQUENCY_CLIENT} gtest) - add_dependencies(${TEST_DEBOUNCE_FREQUENCY_SERVICE} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_SERVICE} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} gtest) - add_dependencies(${TEST_CPU_LOAD_SERVICE} gtest) - add_dependencies(${TEST_CPU_LOAD_CLIENT} gtest) - add_dependencies(${TEST_INITIAL_EVENT_SERVICE} gtest) - add_dependencies(${TEST_INITIAL_EVENT_CLIENT} gtest) - add_dependencies(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} gtest) - add_dependencies(${TEST_INITIAL_EVENT_STOP_SERVICE} gtest) - add_dependencies(${TEST_OFFER_SERVICE} gtest) - add_dependencies(${TEST_OFFER_CLIENT} gtest) - add_dependencies(${TEST_OFFER_SERVICE_EXTERNAL} gtest) - add_dependencies(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} gtest) - add_dependencies(${TEST_OFFERED_SERVICES_INFO_CLIENT} gtest) - add_dependencies(${TEST_OFFERED_SERVICES_INFO_SERVICE} gtest) - add_dependencies(${TEST_PENDING_SUBSCRIPTION_SERVICE} gtest) - add_dependencies(${TEST_PENDING_SUBSCRIPTION_CLIENT} gtest) - add_dependencies(${TEST_MALICIOUS_DATA_SERVICE} gtest) - add_dependencies(${TEST_MALICIOUS_DATA_CLIENT} gtest) - if (${TEST_SECURITY}) - add_dependencies(${TEST_SECURITY_SERVICE} gtest) - add_dependencies(${TEST_SECURITY_CLIENT} gtest) - endif() - add_dependencies(${TEST_E2E_SERVICE} gtest) - add_dependencies(${TEST_E2E_CLIENT} gtest) - if (${TEST_E2E_PROFILE_04}) - add_dependencies(${TEST_E2E_PROFILE_04_SERVICE} gtest) - add_dependencies(${TEST_E2E_PROFILE_04_CLIENT} gtest) - endif() - if (${TEST_E2E_PROFILE_07}) - add_dependencies(${TEST_E2E_PROFILE_07_SERVICE} gtest) - add_dependencies(${TEST_E2E_PROFILE_07_CLIENT} gtest) - endif() - add_dependencies(${TEST_EVENT_SERVICE} gtest) - add_dependencies(${TEST_EVENT_CLIENT} gtest) - if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "QNX") - add_dependencies(${TEST_NPDU_SERVICE_ONE} gtest) - add_dependencies(${TEST_NPDU_SERVICE_TWO} gtest) - add_dependencies(${TEST_NPDU_SERVICE_THREE} gtest) - add_dependencies(${TEST_NPDU_SERVICE_FOUR} gtest) - add_dependencies(${TEST_NPDU_CLIENT_ONE} gtest) - add_dependencies(${TEST_NPDU_CLIENT_TWO} gtest) - add_dependencies(${TEST_NPDU_CLIENT_THREE} gtest) - add_dependencies(${TEST_NPDU_CLIENT_FOUR} gtest) - add_dependencies(${TEST_NPDU_DAEMON_CLIENT} gtest) - add_dependencies(${TEST_NPDU_DAEMON_SERVICE} gtest) - endif() - add_dependencies(${TEST_SOMEIPTP_CLIENT} gtest) - add_dependencies(${TEST_SOMEIPTP_SERVICE} gtest) - if(${TEST_SECOND_ADDRESS}) - add_dependencies(${TEST_SECOND_ADDRESS_CLIENT} gtest) - add_dependencies(${TEST_SECOND_ADDRESS_SERVICE} gtest) - endif() - add_dependencies(${TEST_SUSPEND_RESUME_CLIENT} gtest) - add_dependencies(${TEST_SUSPEND_RESUME_SERVICE} gtest) -else() - add_dependencies(${TEST_APPLICATION} gtest) - add_dependencies(${TEST_HEADER_FACTORY} gtest) - add_dependencies(${TEST_HEADER_FACTORY_CLIENT} gtest) - add_dependencies(${TEST_HEADER_FACTORY_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) -endif() - -############################################################################## -# Add tests to the target build_network_tests -############################################################################## - -if(NOT ${TESTS_BAT}) - add_dependencies(build_network_tests ${TEST_CONFIGURATION}) - add_dependencies(build_network_tests ${TEST_APPLICATION}) - add_dependencies(build_network_tests ${TEST_APPLICATION_SINGLE_PROCESS_NAME}) - add_dependencies(build_network_tests ${TEST_APPLICATION_AVAILABILITY_NAME}) - add_dependencies(build_network_tests ${TEST_MAGIC_COOKIES_CLIENT}) - add_dependencies(build_network_tests ${TEST_MAGIC_COOKIES_SERVICE}) - add_dependencies(build_network_tests ${TEST_HEADER_FACTORY}) - add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_CLIENT}) - add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_SERVICE}) - add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_CLIENT}) - add_dependencies(build_network_tests ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_network_tests ${TEST_PAYLOAD_SERVICE}) - add_dependencies(build_network_tests ${TEST_PAYLOAD_CLIENT}) - add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_SERVICE}) - add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_CLIENT}) - add_dependencies(build_network_tests ${TEST_CLIENT_ID_SERVICE}) - add_dependencies(build_network_tests ${TEST_CLIENT_ID_UTILITY}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_CLIENT}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_SERVICE}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_FILTER_CLIENT}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_FILTER_SERVICE}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_CALLBACK_CLIENT}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_CALLBACK_SERVICE}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_FREQUENCY_CLIENT}) - add_dependencies(build_network_tests ${TEST_DEBOUNCE_FREQUENCY_SERVICE}) - add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_SERVICE}) - add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}) - add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}) - add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE}) - add_dependencies(build_network_tests ${TEST_CPU_LOAD_SERVICE}) - add_dependencies(build_network_tests ${TEST_CPU_LOAD_CLIENT}) - add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_SERVICE}) - add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_CLIENT}) - add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER}) - add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_STOP_SERVICE}) - add_dependencies(build_network_tests ${TEST_OFFER_SERVICE}) - add_dependencies(build_network_tests ${TEST_OFFER_CLIENT}) - add_dependencies(build_network_tests ${TEST_OFFER_SERVICE_EXTERNAL}) - add_dependencies(build_network_tests ${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER}) - add_dependencies(build_network_tests ${TEST_OFFER_BIG_SERVICE}) - add_dependencies(build_network_tests ${TEST_OFFER_BIG_CLIENT}) - add_dependencies(build_network_tests ${TEST_OFFER_MULTIPLE_OFFERING}) - add_dependencies(build_network_tests ${TEST_RESTART_ROUTING_SERVICE}) - add_dependencies(build_network_tests ${TEST_RESTART_ROUTING_CLIENT}) - if (${TEST_SECURITY}) - add_dependencies(build_network_tests ${TEST_SECURITY_SERVICE}) - add_dependencies(build_network_tests ${TEST_SECURITY_CLIENT}) - endif() - add_dependencies(build_network_tests ${TEST_OFFERED_SERVICES_INFO_CLIENT}) - add_dependencies(build_network_tests ${TEST_OFFERED_SERVICES_INFO_SERVICE}) - add_dependencies(build_network_tests ${TEST_PENDING_SUBSCRIPTION_SERVICE}) - add_dependencies(build_network_tests ${TEST_PENDING_SUBSCRIPTION_CLIENT}) - add_dependencies(build_network_tests ${TEST_MALICIOUS_DATA_SERVICE}) - add_dependencies(build_network_tests ${TEST_MALICIOUS_DATA_CLIENT}) - add_dependencies(build_network_tests ${TEST_E2E_SERVICE}) - add_dependencies(build_network_tests ${TEST_E2E_CLIENT}) - if (${TEST_E2E_PROFILE_04}) - add_dependencies(build_network_tests ${TEST_E2E_PROFILE_04_SERVICE}) - add_dependencies(build_network_tests ${TEST_E2E_PROFILE_04_CLIENT}) - endif() - if (${TEST_E2E_PROFILE_07}) - add_dependencies(build_network_tests ${TEST_E2E_PROFILE_07_SERVICE}) - add_dependencies(build_network_tests ${TEST_E2E_PROFILE_07_CLIENT}) - endif() - add_dependencies(build_network_tests ${TEST_EVENT_SERVICE}) - add_dependencies(build_network_tests ${TEST_EVENT_CLIENT}) - if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "QNX") - add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_ONE}) - add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_TWO}) - add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_THREE}) - add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_FOUR}) - add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_ONE}) - add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_TWO}) - add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_THREE}) - add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_FOUR}) - add_dependencies(build_network_tests ${TEST_NPDU_DAEMON_CLIENT}) - add_dependencies(build_network_tests ${TEST_NPDU_DAEMON_SERVICE}) - endif() - add_dependencies(build_network_tests ${TEST_SOMEIPTP_CLIENT}) - add_dependencies(build_network_tests ${TEST_SOMEIPTP_SERVICE}) - if(${TEST_SECOND_ADDRESS}) - add_dependencies(build_network_tests ${TEST_SECOND_ADDRESS_CLIENT}) - add_dependencies(build_network_tests ${TEST_SECOND_ADDRESS_SERVICE}) - endif() - add_dependencies(build_network_tests ${TEST_SUSPEND_RESUME_CLIENT}) - add_dependencies(build_network_tests ${TEST_SUSPEND_RESUME_SERVICE}) -else() - add_dependencies(build_network_tests ${TEST_APPLICATION}) - add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_SERVICE}) - add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_CLIENT}) - add_dependencies(build_network_tests ${TEST_PAYLOAD_SERVICE}) - add_dependencies(build_network_tests ${TEST_PAYLOAD_CLIENT}) - add_dependencies(build_network_tests ${TEST_HEADER_FACTORY}) - add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_CLIENT}) - add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_SERVICE}) - add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_CLIENT}) -endif() +### ADD TESTS SUBDIRECTORIES ### +if(NOT ${TESTS_BAT}) + add_subdirectory(client_id_tests) + add_subdirectory(initial_event_tests) + add_subdirectory(subscribe_notify_one_tests) + add_subdirectory(subscribe_notify_tests) + add_subdirectory(restart_routing_tests) + add_subdirectory(configuration_tests) + add_subdirectory(cpu_load_tests) + add_subdirectory(debounce_callback_tests) + add_subdirectory(debounce_filter_tests) + add_subdirectory(debounce_frequency_tests) + add_subdirectory(debounce_tests) + add_subdirectory(e2e_tests) + add_subdirectory(event_tests) + add_subdirectory(lazy_load_tests) + add_subdirectory(magic_cookies_tests) + add_subdirectory(malicious_data_tests) + add_subdirectory(memory_tests) + add_subdirectory(offer_stop_offer_test) + add_subdirectory(offered_services_info_tests) + add_subdirectory(pending_subscription_tests) + add_subdirectory(regression_tests) + add_subdirectory(second_address_tests) + add_subdirectory(security_tests) + add_subdirectory(someip_tp_tests) + add_subdirectory(offer_tests) + add_subdirectory(suspend_resume_tests) +endif() + +add_subdirectory(application_tests) +add_subdirectory(routing_tests) +add_subdirectory(big_payload_tests) +add_subdirectory(header_factory_tests) +add_subdirectory(npdu_tests) +add_subdirectory(payload_tests) +add_subdirectory(cyclic_event_tests) # some tests require the routingmanagerd +if (NOT MSVC) add_dependencies(build_network_tests routingmanagerd) - -############################################################################## -# Add tests -############################################################################## - -if(NOT ${TESTS_BAT}) - add_test(NAME ${TEST_CONFIGURATION} - COMMAND ${TEST_CONFIGURATION} - ) - - # application test - add_test(NAME ${TEST_APPLICATION} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_STARTER} - ) - set_tests_properties(${TEST_APPLICATION} PROPERTIES TIMEOUT 80) - add_test(NAME ${TEST_APPLICATION_SINGLE_PROCESS_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ) - set_tests_properties(${TEST_APPLICATION_SINGLE_PROCESS_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_APPLICATION_AVAILABILITY_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_AVAILABILITY_STARTER} - ) - set_tests_properties(${TEST_APPLICATION_AVAILABILITY_NAME} PROPERTIES TIMEOUT 120) - - # magic cookies test - add_test(NAME ${TEST_MAGIC_COOKIES_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_STARTER} - ) - set_tests_properties(${TEST_MAGIC_COOKIES_NAME} PROPERTIES TIMEOUT 250) - - # Header/Factory tets - add_test(NAME ${TEST_HEADER_FACTORY_NAME} COMMAND ${TEST_HEADER_FACTORY}) - add_test(NAME ${TEST_HEADER_FACTORY_NAME}_send_receive - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_STARTER} - ) - - # Routing tests - add_test(NAME ${TEST_LOCAL_ROUTING_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} - ) - - add_test(NAME ${TEST_EXTERNAL_LOCAL_ROUTING_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_ROUTING_NAME} PROPERTIES TIMEOUT 120) - - # Payload tests - add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_STARTER} - ) - add_test(NAME ${TEST_LOCAL_PAYLOAD_HUGE_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ) - set_tests_properties(${TEST_LOCAL_PAYLOAD_HUGE_NAME} PROPERTIES TIMEOUT 1800) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) - - # big payload tests - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_LOCAL_TCP_TCP_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDSPECIFIC - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} UDP - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} PROPERTIES TIMEOUT 120) - - # client id tests - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY} - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_511 - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_511 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_511 PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_4095 - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_4095 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_4095 PROPERTIES TIMEOUT 600) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_127 - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_127 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_127 PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 PROPERTIES TIMEOUT 120) - - # debounce tests - add_test(NAME ${TEST_DEBOUNCE_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_STARTER}) - set_tests_properties(${TEST_DEBOUNCE_UTILITY} PROPERTIES TIMEOUT 30) - - # debounce filter tests - add_test(NAME ${TEST_DEBOUNCE_FILTER_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FILTER_MASTER_STARTER}) - set_tests_properties(${TEST_DEBOUNCE_FILTER_UTILITY} PROPERTIES TIMEOUT 30) - # debounce callback tests - add_test(NAME ${TEST_DEBOUNCE_CALLBACK_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_CALLBACK_MASTER_STARTER}) - set_tests_properties(${TEST_DEBOUNCE_CALLBACK_NAME} PROPERTIES TIMEOUT 60) - - # debounce frequency tests - add_test(NAME ${TEST_DEBOUNCE_FREQUENCY_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_FREQUENCY_MASTER_STARTER}) - set_tests_properties(${TEST_DEBOUNCE_FREQUENCY_NAME} PROPERTIES TIMEOUT 30) - - # subscribe notify tests (local communication via UDS) - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} SAME_SERVICE_ID) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_local_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_local_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_local_tcp PROPERTIES TIMEOUT 120) - - # subscribe_notify_tests (local communication via TCP) - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp PROPERTIES TIMEOUT 120) - - # subscribe notify one id tests - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 - add_test(NAME ${TEST_CPU_LOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_MASTER_STARTER} - ) - set_tests_properties(${TEST_CPU_LOAD_NAME} PROPERTIES TIMEOUT 3000) - - # initial event tests - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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 ${NETWORK_TEST_BIN_DIR}/${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) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP CLIENT_SUBSCRIBES_TWICE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice PROPERTIES TIMEOUT 120) - - # offer tests - add_test(NAME ${TEST_OFFER_NAME}_local - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_STARTER}) - set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 180) - add_test(NAME ${TEST_OFFER_NAME}_external - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_MASTER_STARTER}) - set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 360) - - add_test(NAME ${TEST_OFFER_BIG_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_STARTER}) - set_tests_properties(${TEST_OFFER_BIG_NAME} PROPERTIES TIMEOUT 360) - - # Multiple Offer tests - add_test(NAME ${TEST_OFFER_MULTIPLE_OFFERING} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_MULTIPLE_OFFERING_STARTER}) - set_tests_properties(${TEST_OFFER_MULTIPLE_OFFERING} PROPERTIES TIMEOUT 1800) - - # offered services info tets - add_test(NAME ${TEST_OFFERED_SERVICES_INFO_NAME}_local - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER}) - set_tests_properties(${TEST_OFFERED_SERVICES_INFO_NAME}_local PROPERTIES TIMEOUT 180) - - # Restart-Routing tests - add_test(NAME ${TEST_RESTART_ROUTING_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_STARTER} - ) - if (${TEST_SECURITY}) - # Security tests - add_test(NAME ${TEST_SECURITY_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ) - add_test(NAME ${TEST_SECURITY_NAME}_external_allow - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_allow.json --allow - ) - add_test(NAME ${TEST_SECURITY_NAME}_external_deny - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_deny.json --deny - ) - endif() - - # pending subscriptions test - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} UNSUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_NACK) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_RESUBSCRIBE_MIXED) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed PROPERTIES TIMEOUT 300) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} REQUEST_TO_SD) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port PROPERTIES TIMEOUT 180) - - # malicious data test - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_events - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} MALICIOUS_EVENTS) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_events PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_protocol_version - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} PROTOCOL_VERSION) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_protocol_version PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_message_type - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} MESSAGE_TYPE) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_message_type PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_return_code - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} RETURN_CODE) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_return_code PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} WRONG_HEADER_FIELDS_UDP) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp PROPERTIES TIMEOUT 180) - - # npdu tests - add_test(NAME ${TEST_NPDU_NAME}_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} UDP sync) - set_tests_properties(${TEST_NPDU_NAME}_udp PROPERTIES TIMEOUT 840) - - add_test(NAME ${TEST_NPDU_NAME}_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} TCP sync) - set_tests_properties(${TEST_NPDU_NAME}_tcp PROPERTIES TIMEOUT 840) - - # e2e tests - add_test(NAME ${TEST_E2E_NAME}_external - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} e2e_test_client_external.json) - set_tests_properties(${TEST_E2E_NAME}_external PROPERTIES TIMEOUT 180) - - if (${TEST_E2E_PROFILE_04}) - add_test(NAME ${TEST_E2E_PROFILE_04_NAME}_external - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} e2e_profile_04_test_client_external.json) - set_tests_properties(${TEST_E2E_PROFILE_04_NAME}_external PROPERTIES TIMEOUT 180) - endif () - - if (${TEST_E2E_PROFILE_07}) - add_test(NAME ${TEST_E2E_PROFILE_07_NAME}_external - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_07_EXTERNAL_MASTER_START_SCRIPT} e2e_profile_07_test_client_external.json) - set_tests_properties(${TEST_E2E_PROFILE_07_NAME}_external PROPERTIES TIMEOUT 180) - endif () - - # event tests - add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED UDP) - set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED TCP) - set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_tcp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC UDP) - set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_tcp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC TCP) - set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_tcp PROPERTIES TIMEOUT 180) - - # SOME/IP-TP tests - add_test(NAME ${TEST_SOMEIPTP_NAME}_in_sequence - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} IN_SEQUENCE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_in_sequence PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_mixed - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} MIXED) - set_tests_properties(${TEST_SOMEIPTP_NAME}_mixed PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_incomplete - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} INCOMPLETE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_incomplete PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_duplicate - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} DUPLICATE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_duplicate PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP) - set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap_front_back - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP_FRONT_BACK) - set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap_front_back PROPERTIES TIMEOUT 180) - - if(${TEST_SECOND_ADDRESS}) - add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} SERVICE UDP - ) - set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} CLIENT UDP - ) - set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp PROPERTIES TIMEOUT 180) - endif() - - # suspend resume test - add_test(NAME ${TEST_SUSPEND_RESUME_NAME}_initial - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} SERVICE - ) - -else() - # Routing tests - add_test(NAME ${TEST_LOCAL_ROUTING_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} - ) - - # application test - add_test(NAME ${TEST_APPLICATION} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_STARTER} - ) - set_tests_properties(${TEST_APPLICATION} PROPERTIES TIMEOUT 80) - - # big payload tests - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_LOCAL_TCP_TCP_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDSPECIFIC - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} UDP - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} PROPERTIES TIMEOUT 120) - - # Header/Factory tests - add_test(NAME ${TEST_HEADER_FACTORY_NAME} COMMAND ${TEST_HEADER_FACTORY}) - add_test(NAME ${TEST_HEADER_FACTORY_NAME}_send_receive - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_STARTER} - ) - - # Payload tests - add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_STARTER} - ) - add_test(NAME ${TEST_LOCAL_PAYLOAD_HUGE_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ) - set_tests_properties(${TEST_LOCAL_PAYLOAD_HUGE_NAME} PROPERTIES TIMEOUT 1800) - - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME} - COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ) -endif() +endif () diff --git a/test/network_tests/application_tests/CMakeLists.txt b/test/network_tests/application_tests/CMakeLists.txt new file mode 100644 index 000000000..65dd6eabe --- /dev/null +++ b/test/network_tests/application_tests/CMakeLists.txt @@ -0,0 +1,122 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(application_tests LANGUAGES CXX) + +# Configure necessary files and copy them to the build folder. +set(configuration_files + application_test.json + application_test_daemon.json + application_test_no_dispatch_threads.json + application_test_no_dispatch_threads_daemon.json + application_test_dispatch_threads.json + application_test_starter.sh + application_test_dispatch_threads_starter.sh + application_test_dispatch_threads_executor_starter.sh +) +configure_files("${configuration_files}") + +# Add the test executable. +add_executable(application_test + application_test.cpp +) + +# Add the test executable for application_test_multiple_init +add_executable(application_test_multiple_init + application_test_multiple_init.cpp +) + +# Add the test executable for application_test_dispatch_threads_executor +add_executable(application_test_dispatch_threads_executor + application_test_dispatch_threads_executor.cpp +) + +# Add the test executable for application_test_dispatch_threads +add_executable(application_test_dispatch_threads + application_test_dispatch_threads.cpp +) + +# Add build dependencies and link libraries to executables. +set(executable_targets + application_test + application_test_multiple_init + application_test_dispatch_threads + application_test_dispatch_threads_executor +) +targets_add_default_dependencies("${executable_targets}") +targets_link_default_libraries("${executable_targets}") + +# Add custom test command. +add_custom_test( + NAME application_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/application_test_starter.sh + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME application_test_multiple_init + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/application_test_multiple_init + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME application_test_dispatch_threads_executor + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/application_test_dispatch_threads_executor_starter.sh + TIMEOUT 180 +) + +if (NOT ${TESTS_BAT}) + + # Configure necessary files and copy them to the build folder. + set(configuration_files + application_test_single_process.json + application_test_single_process_starter.sh + application_test_availability_starter.sh + ) + configure_files("${configuration_files}") + + # Add the test executable. + add_executable(application_test_single_process + application_test_single_process.cpp + ) + + if(QNX) + target_compile_definitions(application_test_single_process + PRIVATE _QNX_SOURCE + ) + endif() + + # Add the test executable. + add_executable(application_test_availability + application_test_availability.cpp + ) + + # Add build dependencies and link libraries to executables. + set(executable_targets + application_test_single_process + application_test_availability + ) + targets_add_default_dependencies("${executable_targets}") + targets_link_default_libraries("${executable_targets}") + + # Add custom test command. + add_custom_test( + NAME application_test_single_process + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/application_test_single_process_starter.sh + TIMEOUT 80 + ) + + # Add custom test command. + add_custom_test( + NAME application_test_availability + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/application_test_availability_starter.sh + TIMEOUT 80 + ) + +endif() diff --git a/test/network_tests/application_tests/application_test_client.cpp b/test/network_tests/application_tests/application_test_client.cpp index 836bdbfca..ba05511a4 100644 --- a/test/network_tests/application_tests/application_test_client.cpp +++ b/test/network_tests/application_tests/application_test_client.cpp @@ -38,7 +38,7 @@ class application_test_client : public vsomeip_utilities::base_logger { stop_thread_(std::bind(&application_test_client::wait_for_stop, this)), send_thread_(std::bind(&application_test_client::send, this)) { if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; + ADD_FAILURE() << "[Client] Couldn't initialize application"; return; } app_->register_state_handler( @@ -74,41 +74,40 @@ class application_test_client : public vsomeip_utilities::base_logger { } void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " + VSOMEIP_INFO << "[Client] Application " << app_->get_name() << " is " << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : "deregistered."); if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); + std::scoped_lock its_lock {mutex_}; wait_until_registered_ = false; condition_.notify_one(); } } - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - std::lock_guard its_lock(mutex_); - if(_is_available) { - wait_until_service_available_ = false; - condition_.notify_one(); - } else { - wait_until_service_available_ = true; - condition_.notify_one(); - } + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available) { + VSOMEIP_INFO << "[Client] Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available" : "not available") << "."; + std::scoped_lock its_lock {mutex_}; + if (_is_available) { + wait_until_service_available_ = false; + condition_.notify_one(); + } else { + wait_until_service_available_ = true; + condition_.notify_one(); + } } - void on_message(const std::shared_ptr &_message) { + void on_message(const std::shared_ptr& _message) { ++received_responses_; EXPECT_EQ(service_info_.service_id, _message->get_service()); EXPECT_EQ(service_info_.method_id, _message->get_method()); EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - VSOMEIP_INFO << "Received a response with Client/Session [" - << std::setfill('0') << std::hex - << std::setw(4) << _message->get_client() << "/" - << std::setw(4) << _message->get_session() << "]"; + VSOMEIP_INFO << "[Client] Received a response with Client/Session [" << std::setfill('0') + << std::hex << std::setw(4) << _message->get_client() << "/" << std::setw(4) + << _message->get_session() << "]"; } void send() { @@ -124,24 +123,22 @@ class application_test_client : public vsomeip_utilities::base_logger { its_lock.release(); for (;;) { - bool send(false); { - std::lock_guard its_lock(mutex_); - send = !wait_until_service_available_; - } - if (send && !stop_called_) { - std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); - its_req->set_service(service_info_.service_id); - its_req->set_instance(service_info_.instance_id); - its_req->set_method(service_info_.method_id); - app_->send(its_req); - ++sent_requests_; - VSOMEIP_INFO << "Sent a request to the service!"; - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); + std::scoped_lock its_lock {mutex_}; + if (!wait_until_service_available_ && !stop_called_) { + std::shared_ptr its_req = + vsomeip::runtime::get()->create_request(); + its_req->set_service(service_info_.service_id); + its_req->set_instance(service_info_.instance_id); + its_req->set_method(service_info_.method_id); + app_->send(its_req); + ++sent_requests_; + VSOMEIP_INFO << "[Client] Sent a request to the service!"; + } } - if(stop_called_) { + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (stop_called_) { break; } } @@ -152,26 +149,25 @@ class application_test_client : public vsomeip_utilities::base_logger { while (wait_for_stop_) { stop_condition_.wait(its_lock); } - VSOMEIP_INFO << "going down"; + VSOMEIP_INFO << "[Client] Going down!"; app_->clear_all_handler(); app_->stop(); } void stop(bool check) { stop_called_ = true; - std::lock_guard its_lock(stop_mutex_); + std::scoped_lock its_lock {stop_mutex_}; wait_for_stop_ = false; - VSOMEIP_INFO << "going down. Sent " << sent_requests_ + VSOMEIP_INFO << "[Client] Going down. Sent " << sent_requests_ << " requests and received " << received_responses_ << " responses. Delta: " << sent_requests_ - received_responses_; - std::uint32_t counter(0); + if (check) { - while(sent_requests_ == 0 || sent_requests_ < received_responses_) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if(++counter > 50) { - break; - } + while (sent_requests_ == 0 || sent_requests_ < received_responses_) { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); } + // time to be sure the sent message is sent by routing manager + std::this_thread::sleep_for(std::chrono::milliseconds(100)); EXPECT_GT(sent_requests_, 0u); EXPECT_GT(received_responses_, 0u); EXPECT_EQ(sent_requests_, received_responses_); diff --git a/test/network_tests/application_tests/application_test_daemon.cpp b/test/network_tests/application_tests/application_test_daemon.cpp index 4f1cb9ff6..d92d020a8 100644 --- a/test/network_tests/application_tests/application_test_daemon.cpp +++ b/test/network_tests/application_tests/application_test_daemon.cpp @@ -18,7 +18,7 @@ class application_test_daemon : public vsomeip_utilities::base_logger { vsomeip_utilities::base_logger("APTD", "APPLICATION TEST DAEMON"), app_(vsomeip::runtime::get()->create_application("daemon")) { if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; + ADD_FAILURE() << "[Daemon] Couldn't initialize application"; return; } std::promise its_promise; @@ -28,7 +28,7 @@ class application_test_daemon : public vsomeip_utilities::base_logger { }); EXPECT_TRUE(its_promise.get_future().get()); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - VSOMEIP_INFO << "Daemon starting"; + VSOMEIP_INFO << "[Daemon] Starting"; } ~application_test_daemon() { @@ -36,7 +36,7 @@ class application_test_daemon : public vsomeip_utilities::base_logger { } void stop() { - VSOMEIP_INFO << "Daemon stopping"; + VSOMEIP_INFO << "[Daemon] Stopping"; app_->stop(); } diff --git a/test/network_tests/application_tests/application_test_dispatch_threads.cpp b/test/network_tests/application_tests/application_test_dispatch_threads.cpp new file mode 100644 index 000000000..33bc35dcc --- /dev/null +++ b/test/network_tests/application_tests/application_test_dispatch_threads.cpp @@ -0,0 +1,307 @@ +// Copyright (C) 2015-2024 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 "application_test_globals.hpp" +#include "someip_test_globals.hpp" + +using namespace vsomeip; + +class someip_application_detach_dispatch { + +public: + bool is_registered_; + bool is_available_; + std::atomic_bool is_forcefully_stopped_; + std::atomic_bool is_finished_; + std::shared_ptr app_; + std::condition_variable cv_; + std::mutex mutex_; + std::thread thread_; + + someip_application_detach_dispatch() { } + ~someip_application_detach_dispatch() { } + + void init() { + is_registered_ = false; + is_available_ = false; + + app_ = runtime::get()->create_application("application_test_dispatch_threads"); + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID, + std::bind(&someip_application_detach_dispatch::on_message, + this, std::placeholders::_1)); + + app_->register_message_handler( + vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_SHORT, + std::bind(&someip_application_detach_dispatch::on_message_loop_short, this, + std::placeholders::_1)); + + app_->register_message_handler( + vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_LONG, + std::bind(&someip_application_detach_dispatch::on_message_loop_long, this, + std::placeholders::_1)); + + app_->register_state_handler(std::bind(&someip_application_detach_dispatch::on_state, this, + std::placeholders::_1)); + app_->register_availability_handler( + vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&someip_application_detach_dispatch::on_availability, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + } + + void cleanup() { + app_->stop(); + app_.reset(); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + void on_state(vsomeip::state_type_e _state) { + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + is_registered_ = true; + cv_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available) { + (void)_service; + (void)_instance; + if (_is_available) { + std::lock_guard its_lock(mutex_); + is_available_ = _is_available; + cv_.notify_one(); + } + } + + void on_message_loop_short(const std::shared_ptr& _request) { + (void)_request; + VSOMEIP_INFO << "Processing something for 5 seconds"; + + pthread_cleanup_push(handler_cbk, nullptr); + + is_finished_ = false; + is_forcefully_stopped_ = false; + + for (int i = 0; i < 6; i++) { + std::unique_lock its_lock(mutex_); + VSOMEIP_INFO << "Elapsed time: " << i << " seconds"; + + // Call stop after 5 seconds + if (i == 5) { + VSOMEIP_INFO << "Sending stop signal after " << i << " seconds"; + app_->stop(); + } + // using a condition variable instead of sleep_for so that ThreadSanitizer does not + // raise any issues + cv_.wait_for(its_lock, std::chrono::seconds(1)); + pthread_testcancel(); + } + + VSOMEIP_INFO << "Finished processing"; + is_finished_ = true; + pthread_cleanup_pop(0); + } + + void on_message_loop_long(const std::shared_ptr& _request) { + (void)_request; + VSOMEIP_INFO << "Processing something for 50 seconds"; + + pthread_cleanup_push(handler_cbk, this); + + is_finished_ = false; + is_forcefully_stopped_ = false; + + for (int i = 0; i < 50; i++) { + std::unique_lock its_lock(mutex_); + VSOMEIP_INFO << "Elapsed time: " << i << " seconds"; + + // Call stop after 5 seconds + if (i == 5) { + VSOMEIP_INFO << "Sending stop signal after " << i << " seconds"; + app_->stop(); + } + // using a condition variable instead of sleep_for so that ThreadSanitizer does not + // raise any issues + cv_.wait_for(its_lock, std::chrono::seconds(1)); + pthread_testcancel(); + } + + VSOMEIP_INFO << "Finished processing"; + is_finished_ = true; + pthread_cleanup_pop(0); + } + + void on_message(const std::shared_ptr& _request) { + (void)_request; + VSOMEIP_INFO << "Processing something"; + + std::unique_lock its_lock(mutex_); + // using a condition variable instead of sleep_for so that ThreadSanitizer does not raise + // any issues + cv_.wait_for(its_lock, std::chrono::milliseconds(100)); + } + + static void handler_cbk(void* arg) { + if (arg != nullptr) { + static_cast(arg)->cleanup_handler(arg); + } + } + + void cleanup_handler(void* arg) { + (void)arg; + VSOMEIP_INFO << "Setting is_forcefully_stopped_ to true"; + is_forcefully_stopped_ = true; + } + + void send_messages(vsomeip_v3::method_t method_id) { + { + std::unique_lock its_lock(mutex_); + while (!is_registered_) { + if (std::cv_status::timeout == cv_.wait_for(its_lock, std::chrono::seconds(10))) { + ADD_FAILURE() << "Application wasn't registered in time!"; + is_registered_ = true; + } + } + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); + while (!is_available_) { + if (std::cv_status::timeout == cv_.wait_for(its_lock, std::chrono::seconds(10))) { + ADD_FAILURE() << "Service didn't become available in time!"; + is_available_ = true; + } + } + } + + create_send_request(method_id); + create_send_request(vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID); + } + + void create_send_request(vsomeip_v3::method_t method_id) { + std::shared_ptr t = runtime::get()->create_request(); + t->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + t->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + t->set_method(method_id); + app_->send(t); + } + + void execute(char** argv) { + // Create a shared memory object. + boost::interprocess::shared_memory_object shm( + boost::interprocess::open_only, // only create + "SharedCV", // name + boost::interprocess::read_write // read-write mode + ); + + try { + // Map the whole shared memory in this process + boost::interprocess::mapped_region region( + shm, // What to map + boost::interprocess::read_write // Map it as read-write + ); + + // Get the address of the mapped region + void* addr = region.get_address(); + + // Obtain a pointer to the shared structure + application_test::dispatch_threads_sync* data = + static_cast(addr); + + init(); + + std::promise its_promise; + std::thread t([&]() { app_->start(); }); + + { + boost::interprocess::scoped_lock lock( + data->mutex); + + // Set initial value of status_ + data->status_ = application_test::dispatch_threads_sync::TEST_FAILURE; + + // Read to argv[2] timeout and convert to tenths of a second + int timeout = std::stoi(argv[2]) * 10; + + // argv[1] should be the type of test to run + if (strcmp(argv[1], "force_abort") == 0) { + VSOMEIP_INFO << "Testing Force Abort"; + send_messages(vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_LONG); + + for (int i = 0; i < timeout; i++) { + + if (is_forcefully_stopped_ == true && is_finished_ == false) { + VSOMEIP_INFO << "Updating CV"; + data->status_ = + application_test::dispatch_threads_sync::SUCCESS_ABORTING; + data->cv.notify_all(); + break; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + } else if (strcmp(argv[1], "wait_finish") == 0) { + VSOMEIP_INFO << "Testing Wait Finish"; + send_messages(vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_SHORT); + + for (int i = 0; i < timeout; i++) { + + if (is_forcefully_stopped_ == false && is_finished_ == true) { + VSOMEIP_INFO << "Updating CV"; + data->status_ = + application_test::dispatch_threads_sync::SUCCESS_WAITING; + data->cv.notify_all(); + break; + } + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + } + + VSOMEIP_INFO << "Finishing execution"; + + t.join(); + + cleanup(); + + } catch (boost::interprocess::interprocess_exception& ex) { + FAIL() << ex.what(); + } + } +}; + +#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) +int main(int argc, char** argv) { + (void)argc; + + someip_application_detach_dispatch exec; + exec.execute(argv); +} +#endif diff --git a/test/network_tests/application_tests/application_test_dispatch_threads_executor.cpp b/test/network_tests/application_tests/application_test_dispatch_threads_executor.cpp new file mode 100644 index 000000000..e354b15ea --- /dev/null +++ b/test/network_tests/application_tests/application_test_dispatch_threads_executor.cpp @@ -0,0 +1,207 @@ +// Copyright (C) 2015-2024 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 + +#include "application_test_globals.hpp" +#include "someip_test_globals.hpp" + +using namespace vsomeip; + +class someip_application_detach_dispatch_executor : public ::testing::Test { + +protected: + void SetUp() { VSOMEIP_INFO << "Setting up test"; } + + void TearDown() { VSOMEIP_INFO << "Tearing down"; } + + int get_process_pid(std::string process_name) { + std::string file_name = "/tmp/" + process_name + ".pid"; + int pid = -1; + FILE* file = fopen(file_name.c_str(), "r"); + + if (file) { + if (fscanf(file, "%d", &pid) != 1) { // Check that fscanf successfully read one integer + std::cerr << "Failed to read PID from file" << std::endl; + pid = -1; // Indicate failure + } + fclose(file); + } else { + std::cerr << "Failed to open PID file" << std::endl; + } + + return pid; + } + + // Erase previous shared memory and schedule erasure on exit + + boost::interprocess::shared_memory_object shm; + + std::condition_variable cv_; + std::mutex mutex_; +}; + +/** + * @test Force detaching of dispatcher threads with long processing times + */ +TEST_F(someip_application_detach_dispatch_executor, dispatch_thread_detached_forcefully_stopped) { + + struct shm_remove { + shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } + ~shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } + } remover; + + // Create a shared memory object. + boost::interprocess::shared_memory_object shm( + boost::interprocess::open_or_create, // only create + "SharedCV", // name + boost::interprocess::read_write // read-write mode + ); + + // Timeout to pass into the test + int seconds_to_timeout = 20; + + // Define how long should the test wait for the condition variable to be set + boost::posix_time::ptime timeout = boost::posix_time::second_clock::local_time() + + boost::posix_time::seconds(seconds_to_timeout); + + try { + // Set size + shm.truncate(sizeof(application_test::dispatch_threads_sync)); + + // Map the whole shared memory in this process + boost::interprocess::mapped_region region( + shm, // What to map + boost::interprocess::read_write // Map it as read-write + ); + + // Get the address of the mapped region + void* addr = region.get_address(); + + // Construct the shared structure in memory + application_test::dispatch_threads_sync* data = + new (addr) application_test::dispatch_threads_sync; + + { + boost::interprocess::scoped_lock lock( + data->mutex); + + std::string exec_cmd = "./application_test_dispatch_threads_starter.sh force_abort " + + std::to_string(seconds_to_timeout); + std::cout << std::flush; + + EXPECT_EQ(system(exec_cmd.c_str()), 0); + + EXPECT_EQ(data->cv.timed_wait(lock, timeout, [&] { return data->status_; }), + application_test::dispatch_threads_sync::SUCCESS_ABORTING); + + // Retrieve the PID + int pid = get_process_pid("application_test_dispatch_threads"); + + std::string check_cmd = "kill -0 " + std::to_string(pid); + + if (system(check_cmd.c_str()) + == 0) { // If the process exists, the command will return 0 + std::string kill_cmd = "kill -9 " + std::to_string(pid); + EXPECT_EQ(system(kill_cmd.c_str()), 0); + } + } + } catch (boost::interprocess::interprocess_exception& ex) { + std::cout << ex.what() << std::endl; + } +} + +/** + * @test Force detaching of dispatcher threads with but dispatcher finishes processing + */ +TEST_F(someip_application_detach_dispatch_executor, dispatch_thread_detached_finishes_execution) { + + struct shm_remove { + shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } + ~shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } + } remover; + + // Create a shared memory object. + boost::interprocess::shared_memory_object shm( + boost::interprocess::open_or_create, // only create + "SharedCV", // name + boost::interprocess::read_write // read-write mode + ); + + VSOMEIP_INFO << "Starting test"; + + // Timeout to pass into the test + int seconds_to_timeout = 8; + + // Define how long should the test wait for the condition variable to be set + boost::posix_time::ptime timeout = boost::posix_time::second_clock::local_time() + + boost::posix_time::seconds(seconds_to_timeout); + + VSOMEIP_INFO << "Timeout set to " << timeout; + + try { + // Set size + shm.truncate(sizeof(application_test::dispatch_threads_sync)); + + // Map the whole shared memory in this process + boost::interprocess::mapped_region region( + shm, // What to map + boost::interprocess::read_write // Map it as read-write + ); + + // Get the address of the mapped region + void* addr = region.get_address(); + + // Construct the shared structure in memory + application_test::dispatch_threads_sync* data = + new (addr) application_test::dispatch_threads_sync; + + { + boost::interprocess::scoped_lock lock( + data->mutex); + + std::string exec_cmd = "./application_test_dispatch_threads_starter.sh wait_finish " + + std::to_string(seconds_to_timeout); + + ASSERT_EQ(system(exec_cmd.c_str()), 0); + + EXPECT_EQ(data->cv.timed_wait(lock, timeout, [&] { return data->status_; }), + application_test::dispatch_threads_sync::SUCCESS_WAITING); + + // Retrieve the PID + int pid = get_process_pid("application_test_dispatch_threads"); + + std::string check_cmd = "kill -0 " + std::to_string(pid); + + if (system(check_cmd.c_str()) + == 0) { // If the process exists, the command will return 0 + std::string kill_cmd = "kill -9 " + std::to_string(pid); + EXPECT_EQ(system(kill_cmd.c_str()), 0); + } + } + } catch (boost::interprocess::interprocess_exception& ex) { + std::cout << ex.what() << std::endl; + } +} + +#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/application_tests/application_test_globals.hpp b/test/network_tests/application_tests/application_test_globals.hpp index 7caa9db2c..7843d7025 100644 --- a/test/network_tests/application_tests/application_test_globals.hpp +++ b/test/network_tests/application_tests/application_test_globals.hpp @@ -6,6 +6,9 @@ #ifndef APPLICATION_TEST_GLOBALS_HPP_ #define APPLICATION_TEST_GLOBALS_HPP_ +#include +#include + namespace application_test { struct service_info { @@ -19,8 +22,16 @@ struct service_info { vsomeip::minor_version_t minor_version; }; +struct service_info service = {0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404, 0x2, 0x4711}; + +struct dispatch_threads_sync { + enum test_status { SUCCESS_ABORTING = 0x00, SUCCESS_WAITING = 0x01, TEST_FAILURE = 0x02 }; -struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404, 0x2, 0x4711 }; + boost::interprocess::interprocess_mutex mutex; + boost::interprocess::interprocess_condition cv; + + test_status status_; +}; static constexpr int number_of_messages_to_send = 150; } diff --git a/test/network_tests/application_tests/application_test_multiple_init.cpp b/test/network_tests/application_tests/application_test_multiple_init.cpp new file mode 100644 index 000000000..1f462d6c5 --- /dev/null +++ b/test/network_tests/application_tests/application_test_multiple_init.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2024 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 + +/// @brief This test validates that no data race occurs when calling vsomeip::application_impl::init +/// on multiple applications, within the same process. +TEST(someip_application_init_test, multithread_init) { + constexpr std::uint32_t thread_count = 128; + std::vector vsomeip_applications; + + std::condition_variable start_cv; + std::mutex start_mutex; + std::atomic_bool start = false; + + // Prepare the init threads + for (std::uint32_t t = 0; t < thread_count; ++t) { + vsomeip_applications.emplace_back([&start_cv, &start_mutex, &start, t] { + { + std::unique_lock lk {start_mutex}; + start_cv.wait(lk, [&start] { return start.load(); }); + } + std::stringstream app_name; + app_name << "vsomeip_app_" << t; + auto vsomeip_app = vsomeip::runtime::get()->create_application(app_name.str()); + + EXPECT_TRUE(vsomeip_app->init()); // EXPECT also no crash + }); + } + + // Start the init threads + { + std::scoped_lock lk {start_mutex}; + start = true; + start_cv.notify_all(); + } + + // After test -> join threads + for (auto& t : vsomeip_applications) { + ASSERT_TRUE(t.joinable()); + t.join(); + } +} + +#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/application_tests/application_test_service.cpp b/test/network_tests/application_tests/application_test_service.cpp index 6e4dbd148..873dc25fd 100644 --- a/test/network_tests/application_tests/application_test_service.cpp +++ b/test/network_tests/application_tests/application_test_service.cpp @@ -36,7 +36,7 @@ class application_test_service : public vsomeip_utilities::base_logger { stop_called_(false), offer_thread_(std::bind(&application_test_service::run, this)) { if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; + ADD_FAILURE() << "[Service] Couldn't initialize application"; return; } app_->register_state_handler( @@ -73,9 +73,9 @@ class application_test_service : public vsomeip_utilities::base_logger { } void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); + VSOMEIP_INFO << "[Service] Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." + : "deregistered."); if (_state == vsomeip::state_type_e::ST_REGISTERED) { std::lock_guard its_lock(mutex_); @@ -86,10 +86,10 @@ class application_test_service : public vsomeip_utilities::base_logger { void on_request(const std::shared_ptr &_message) { app_->send(vsomeip::runtime::get()->create_response(_message)); - VSOMEIP_INFO << "Received a request with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "]"; + VSOMEIP_INFO << "[Service] Received a request with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex << _message->get_session() + << "]"; } void on_shutdown_method_called(const std::shared_ptr &_message) { @@ -106,15 +106,15 @@ class application_test_service : public vsomeip_utilities::base_logger { } void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; + VSOMEIP_DEBUG << "[Service] [" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] is running"; std::unique_lock its_lock(mutex_); while (wait_until_registered_ && !stop_called_) { condition_.wait_for(its_lock, std::chrono::milliseconds(100)); } - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; + VSOMEIP_DEBUG << "[Service] [" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] is offering"; offer(); } diff --git a/test/network_tests/application_tests/application_test_single_process.cpp b/test/network_tests/application_tests/application_test_single_process.cpp index fcd701cb2..4fcf5cfc3 100644 --- a/test/network_tests/application_tests/application_test_single_process.cpp +++ b/test/network_tests/application_tests/application_test_single_process.cpp @@ -24,12 +24,10 @@ TEST(someip_application_test_single_process, notify_increasing_counter) for (int var = 0; var < 10; ++var) { // every time the client is restarted it becomes the rm_stub again application_test_client its_client(application_test::service); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); if(var != 9) { its_client.stop(false); } else { - // for the last iteration we sleep to make sure the communication - // between the client and the service can be established - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); its_client.stop(true); } } diff --git a/test/network_tests/application_tests/conf/application_test.json.in b/test/network_tests/application_tests/conf/application_test.json.in index 910eeeb1b..628283496 100644 --- a/test/network_tests/application_tests/conf/application_test.json.in +++ b/test/network_tests/application_tests/conf/application_test.json.in @@ -2,7 +2,7 @@ "unicast":"@TEST_IP_MASTER@", "logging": { - "level":"warning", + "level":"info", "console":"true", "file": { diff --git a/test/network_tests/application_tests/application_test_availability_starter.sh b/test/network_tests/application_tests/conf/application_test_availability_starter.sh.in similarity index 100% rename from test/network_tests/application_tests/application_test_availability_starter.sh rename to test/network_tests/application_tests/conf/application_test_availability_starter.sh.in diff --git a/test/network_tests/application_tests/conf/application_test_daemon.json.in b/test/network_tests/application_tests/conf/application_test_daemon.json.in index 5fcf8b9e2..cb3179820 100644 --- a/test/network_tests/application_tests/conf/application_test_daemon.json.in +++ b/test/network_tests/application_tests/conf/application_test_daemon.json.in @@ -2,7 +2,7 @@ "unicast":"@TEST_IP_MASTER@", "logging": { - "level":"warning", + "level":"info", "console":"true", "file": { diff --git a/test/network_tests/application_tests/conf/application_test_dispatch_threads.json.in b/test/network_tests/application_tests/conf/application_test_dispatch_threads.json.in new file mode 100644 index 000000000..f65e893ae --- /dev/null +++ b/test/network_tests/application_tests/conf/application_test_dispatch_threads.json.in @@ -0,0 +1,39 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/someip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"application_test_dispatch_threads", + "id":"0x7788", + "num_dispatchers":"5", + "max_detached_thread_wait_time":"5" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678", + "reliable":"30503" + } + ], + "routing":"application_test_dispatch_threads", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/application_tests/conf/application_test_dispatch_threads_executor_starter.sh.in b/test/network_tests/application_tests/conf/application_test_dispatch_threads_executor_starter.sh.in new file mode 100755 index 000000000..b76444c77 --- /dev/null +++ b/test/network_tests/application_tests/conf/application_test_dispatch_threads_executor_starter.sh.in @@ -0,0 +1,8 @@ +#!/bin/bash +# Copyright (C) 2015-2024 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/. + +export VSOMEIP_CONFIGURATION=application_test_dispatch_threads.json +./application_test_dispatch_threads_executor diff --git a/test/network_tests/application_tests/conf/application_test_dispatch_threads_starter.sh.in b/test/network_tests/application_tests/conf/application_test_dispatch_threads_starter.sh.in new file mode 100755 index 000000000..fa294a813 --- /dev/null +++ b/test/network_tests/application_tests/conf/application_test_dispatch_threads_starter.sh.in @@ -0,0 +1,17 @@ +#!/bin/bash +# Copyright (C) 2015-2024 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/. + +export VSOMEIP_CONFIGURATION=application_test_dispatch_threads.json +./application_test_dispatch_threads "$1" "$2" & +PROCESS_PID=$! +echo $PROCESS_PID > /tmp/application_test_dispatch_threads.pid + +if [ $? -ne 0 ] +then + exit 1 +else + exit 0 +fi diff --git a/test/network_tests/application_tests/conf/application_test_no_dispatch_threads.json.in b/test/network_tests/application_tests/conf/application_test_no_dispatch_threads.json.in index 6c7769661..beb4dc536 100644 --- a/test/network_tests/application_tests/conf/application_test_no_dispatch_threads.json.in +++ b/test/network_tests/application_tests/conf/application_test_no_dispatch_threads.json.in @@ -2,7 +2,7 @@ "unicast":"@TEST_IP_MASTER@", "logging": { - "level":"warning", + "level":"info", "console":"true", "file": { diff --git a/test/network_tests/application_tests/conf/application_test_no_dispatch_threads_daemon.json.in b/test/network_tests/application_tests/conf/application_test_no_dispatch_threads_daemon.json.in index 98fd965e3..890d14017 100644 --- a/test/network_tests/application_tests/conf/application_test_no_dispatch_threads_daemon.json.in +++ b/test/network_tests/application_tests/conf/application_test_no_dispatch_threads_daemon.json.in @@ -2,7 +2,7 @@ "unicast":"@TEST_IP_MASTER@", "logging": { - "level":"warning", + "level":"info", "console":"true", "file": { diff --git a/test/network_tests/application_tests/application_test_single_process.json b/test/network_tests/application_tests/conf/application_test_single_process.json.in similarity index 88% rename from test/network_tests/application_tests/application_test_single_process.json rename to test/network_tests/application_tests/conf/application_test_single_process.json.in index 35eda51b2..71c6383ea 100644 --- a/test/network_tests/application_tests/application_test_single_process.json +++ b/test/network_tests/application_tests/conf/application_test_single_process.json.in @@ -2,7 +2,7 @@ "unicast":"127.0.0.1", "logging": { - "level":"warning", + "level":"info", "console":"true", "file": { diff --git a/test/network_tests/application_tests/application_test_single_process_starter.sh b/test/network_tests/application_tests/conf/application_test_single_process_starter.sh.in similarity index 100% rename from test/network_tests/application_tests/application_test_single_process_starter.sh rename to test/network_tests/application_tests/conf/application_test_single_process_starter.sh.in diff --git a/test/network_tests/application_tests/conf/application_test_starter.sh.bat.in b/test/network_tests/application_tests/conf/application_test_starter.sh.bat.in deleted file mode 100755 index de59fa094..000000000 --- a/test/network_tests/application_tests/conf/application_test_starter.sh.bat.in +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# Copyright (C) 2015-2023 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/. - -FAIL=0 - -export VSOMEIP_CONFIGURATION=application_test_no_dispatch_threads.json - -if ! ./application_test -then - FAIL=$((FAIL+1)) -fi - -export VSOMEIP_CONFIGURATION=application_test.json - -if ! ./application_test -then - FAIL=$((FAIL+1)) -fi - - -# Check if both exited successfully -exit $FAIL diff --git a/test/network_tests/application_tests/application_test_starter.sh b/test/network_tests/application_tests/conf/application_test_starter.sh.in similarity index 92% rename from test/network_tests/application_tests/application_test_starter.sh rename to test/network_tests/application_tests/conf/application_test_starter.sh.in index 7e8c022da..00a7d09bc 100755 --- a/test/network_tests/application_tests/application_test_starter.sh +++ b/test/network_tests/application_tests/conf/application_test_starter.sh.in @@ -30,7 +30,7 @@ cat <start(); } void big_payload_test_client::stop() { - VSOMEIP_INFO << "Stopping..."; + VSOMEIP_INFO << "Stopping Client..."; if (test_mode_ == big_payload_test::test_mode::LIMITED || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL @@ -233,19 +233,19 @@ void big_payload_test_client::run() } its_payload->set_data(its_payload_data); request_->set_payload(its_payload); + VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') << std::hex + << request_->get_client() << "/" << std::setw(4) << std::setfill('0') + << std::hex << request_->get_session() + << "] is going to send a request to Service [" << std::setw(4) + << std::setfill('0') << std::hex << request_->get_service() << "." + << std::setw(4) << std::setfill('0') << std::hex << request_->get_instance() + << "] size: " << std::dec << request_->get_payload()->get_length() + << ". Sent Messages: " << number_of_sent_messages_ + 1; app_->send(request_); if (test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); } - VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') - << std::hex << request_->get_client() << "/" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_session() - << "] sent a request to Service [" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_service() - << "." << std::setw(4) << std::setfill('0') << std::hex - << request_->get_instance() << "] size: " << std::dec << - request_->get_payload()->get_length(); number_of_sent_messages_++; } while(!blocked_) { diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_starter.sh b/test/network_tests/big_payload_tests/big_payload_test_local_starter.sh deleted file mode 100755 index 39a307ccf..000000000 --- a/test/network_tests/big_payload_tests/big_payload_test_local_starter.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-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/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit successfully. - -if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "QUEUELIMITEDGENERAL" ]] -then - echo "The only allowed parameter to this script is RANDOM or LIMITED or QUEUELIMITEDGENERAL." - echo "Like $0 RANDOM" - exit 1 -fi - - -FAIL=0 - -# Start the service -if [[ $# -gt 0 && $1 == "RANDOM" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_local_random.json -elif [[ $# -gt 0 && $1 == "LIMITED" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_local_limited.json -elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_local_queue_limited.json -else - export VSOMEIP_CONFIGURATION=big_payload_test_local.json -fi -./big_payload_test_service $1 & - -# Start the client -./big_payload_test_client $1 & - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/big_payload_tests/big_payload_test_service.cpp b/test/network_tests/big_payload_tests/big_payload_test_service.cpp index a6bd4d7eb..31f1a0391 100644 --- a/test/network_tests/big_payload_tests/big_payload_test_service.cpp +++ b/test/network_tests/big_payload_tests/big_payload_test_service.cpp @@ -3,6 +3,8 @@ // 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 "big_payload_test_service.hpp" #include "big_payload_test_globals.hpp" @@ -69,13 +71,13 @@ bool big_payload_test_service::init() void big_payload_test_service::start() { - VSOMEIP_INFO << "Starting..."; + VSOMEIP_INFO << "Starting Service..."; app_->start(); } void big_payload_test_service::stop() { - VSOMEIP_INFO << "Stopping..."; + VSOMEIP_INFO << "Stopping Service..."; stop_offer(); app_->clear_all_handler(); app_->stop(); diff --git a/test/network_tests/big_payload_tests/big_payload_test_client_local_start.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_client_local_start.sh.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_client_local_start.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_client_local_start.sh.in diff --git a/test/network_tests/big_payload_tests/big_payload_test_external_client_start.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_external_client_start.sh.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_external_client_start.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_external_client_start.sh.in diff --git a/test/network_tests/big_payload_tests/big_payload_test_external_service_start.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_external_service_start.sh.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_external_service_start.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_external_service_start.sh.in diff --git a/test/network_tests/big_payload_tests/big_payload_test_external_starter.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_external_starter.sh.in similarity index 94% rename from test/network_tests/big_payload_tests/big_payload_test_external_starter.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_external_starter.sh.in index 58d20d710..f385a223b 100755 --- a/test/network_tests/big_payload_tests/big_payload_test_external_starter.sh +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_external_starter.sh.in @@ -39,9 +39,9 @@ BIG_PAYLOAD_TEST_PID=$! if [ ! -z "$USE_LXC_TEST" ]; then echo "starting big payload test on slave LXC" if [[ $# -gt 0 ]]; then - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_external_service_start.sh $1\"" & + 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/network_tests/big_payload_tests; ./big_payload_test_external_service_start.sh $1\"" & else - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_external_service_start.sh"' & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/big_payload_tests; ./big_payload_test_external_service_start.sh"' & fi elif [ ! -z "$USE_DOCKER" ]; then if [[ $# -gt 0 ]]; then diff --git a/test/network_tests/big_payload_tests/big_payload_test_local.json b/test/network_tests/big_payload_tests/conf/big_payload_test_local.json.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_local.json rename to test/network_tests/big_payload_tests/conf/big_payload_test_local.json.in diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_limited.json b/test/network_tests/big_payload_tests/conf/big_payload_test_local_limited.json.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_local_limited.json rename to test/network_tests/big_payload_tests/conf/big_payload_test_local_limited.json.in diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_queue_limited.json b/test/network_tests/big_payload_tests/conf/big_payload_test_local_queue_limited.json.in similarity index 97% rename from test/network_tests/big_payload_tests/big_payload_test_local_queue_limited.json rename to test/network_tests/big_payload_tests/conf/big_payload_test_local_queue_limited.json.in index 5e1ea9be9..0ae8c13c4 100644 --- a/test/network_tests/big_payload_tests/big_payload_test_local_queue_limited.json +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_queue_limited.json.in @@ -2,7 +2,7 @@ "unicast":"127.0.0.1", "logging": { - "level":"error", + "level":"info", "console":"true", "file": { diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_random.json b/test/network_tests/big_payload_tests/conf/big_payload_test_local_random.json.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_local_random.json rename to test/network_tests/big_payload_tests/conf/big_payload_test_local_random.json.in diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_starter.sh.bat.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_starter.sh.in similarity index 99% rename from test/network_tests/big_payload_tests/conf/big_payload_test_local_starter.sh.bat.in rename to test/network_tests/big_payload_tests/conf/big_payload_test_local_starter.sh.in index b20103737..747cd2e49 100755 --- a/test/network_tests/big_payload_tests/conf/big_payload_test_local_starter.sh.bat.in +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_starter.sh.in @@ -31,6 +31,7 @@ else export VSOMEIP_CONFIGURATION=big_payload_test_local.json fi ./big_payload_test_service $1 & +sleep 1 # Start the client if ! ./big_payload_test_client $1 diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_start.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_start.sh.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_start.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_start.sh.in diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_start.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_start.sh.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_start.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_start.sh.in diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_tcp_starter.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_starter.sh.in similarity index 94% rename from test/network_tests/big_payload_tests/big_payload_test_local_tcp_starter.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_starter.sh.in index 633b8f2c0..6cd4e57ce 100755 --- a/test/network_tests/big_payload_tests/big_payload_test_local_tcp_starter.sh +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_starter.sh.in @@ -36,9 +36,9 @@ BIG_PAYLOAD_TEST_PID=$! if [ ! -z "$USE_LXC_TEST" ]; then echo "starting big payload test on slave LXC" if [[ $# -gt 0 ]]; then - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_local_tcp_service_start.sh $1\"" & + 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/network_tests/big_payload_tests; ./big_payload_test_local_tcp_service_start.sh $1\"" & else - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_local_tcp_service_start.sh"' & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/big_payload_tests; ./big_payload_test_local_tcp_service_start.sh"' & fi elif [ ! -z "$USE_DOCKER" ]; then if [[ $# -gt 0 ]]; then diff --git a/test/network_tests/big_payload_tests/big_payload_test_service_local_start.sh b/test/network_tests/big_payload_tests/conf/big_payload_test_service_local_start.sh.in similarity index 100% rename from test/network_tests/big_payload_tests/big_payload_test_service_local_start.sh rename to test/network_tests/big_payload_tests/conf/big_payload_test_service_local_start.sh.in diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in index 5a7ee365b..d28e5952a 100644 --- a/test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in @@ -25,7 +25,6 @@ { "service":"0x1240", "instance":"0x01", - "unicast":"@TEST_IP_SLAVE@", "unreliable": "30509", "someip-tp" : { "client-to-service" : [ "0x8421" ] diff --git a/test/network_tests/client_id_tests/CMakeLists.txt b/test/network_tests/client_id_tests/CMakeLists.txt new file mode 100644 index 000000000..9e5ff1375 --- /dev/null +++ b/test/network_tests/client_id_tests/CMakeLists.txt @@ -0,0 +1,101 @@ +# Copyright (C) 2023 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(client_id_tests LANGUAGES CXX) + +# Configure the necessary files into the build folder. +set(configuration_files + client_id_test_diff_client_ids_diff_ports_master.json + client_id_test_diff_client_ids_diff_ports_slave.json + client_id_test_diff_client_ids_partial_same_ports_master.json + client_id_test_diff_client_ids_partial_same_ports_slave.json + client_id_test_diff_client_ids_same_ports_master.json + client_id_test_diff_client_ids_same_ports_slave.json + client_id_test_master_starter.sh + client_id_test_same_client_ids_diff_ports_master.json + client_id_test_same_client_ids_diff_ports_slave.json + client_id_test_same_client_ids_same_ports_master.json + client_id_test_same_client_ids_same_ports_slave.json + client_id_test_slave_starter.sh + client_id_test_utility.json + client_id_test_utility_discontinuous_masked_511.json + client_id_test_utility_masked_127.json + client_id_test_utility_masked_511.json + client_id_test_utility_masked_4095.json +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(client_id_test_service + client_id_test_service.cpp +) + +# Add test executable. +add_executable(client_id_test_utility + client_id_test_utility.cpp +) + +# Link vsomeip configuration libraries. +target_link_libraries(client_id_test_utility + ${VSOMEIP_NAME}-cfg +) + +# Add build dependencies and link libraries to executables. +set(test_executables + client_id_test_service + client_id_test_utility +) +targets_link_default_libraries("${test_executables}") +targets_add_default_dependencies("${test_executables}") + +# Add custom test commands. + +add_custom_test( + NAME client_id_test_diff_client_ids_diff_ports + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_master_starter.sh client_id_test_diff_client_ids_diff_ports_master.json +) + +add_custom_test( + NAME client_id_test_diff_client_ids_same_ports + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_master_starter.sh client_id_test_diff_client_ids_same_ports_master.json +) + +add_custom_test( + NAME client_id_test_diff_client_ids_partial_same_ports + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_master_starter.sh client_id_test_diff_client_ids_partial_same_ports_master.json +) + +add_custom_test( + NAME client_id_test_utility + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility + ENVIRONMENT "VSOMEIP_CONFIGURATION=${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility.json" +) + +add_custom_test( + NAME client_id_test_utility_masked_511 + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility + ENVIRONMENT "VSOMEIP_CONFIGURATION=${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility_masked_511.json" +) + +add_custom_test( + NAME client_id_test_utility_masked_4095 + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility + ENVIRONMENT "VSOMEIP_CONFIGURATION=${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility_masked_4095.json" + TIMEOUT 600 +) + +add_custom_test( + NAME client_id_test_utility_masked_127 + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility + ENVIRONMENT "VSOMEIP_CONFIGURATION=${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility_masked_127.json" +) + +add_custom_test( + NAME client_id_test_utility_discontinuous_masked_511 + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility + ENVIRONMENT "VSOMEIP_CONFIGURATION=${CMAKE_CURRENT_BINARY_DIR}/client_id_test_utility_discontinuous_masked_511.json" +) diff --git a/test/network_tests/client_id_tests/client_id_test_master_starter_qnx.sh b/test/network_tests/client_id_tests/client_id_test_master_starter_qnx.sh deleted file mode 100755 index de2f59e0b..000000000 --- a/test/network_tests/client_id_tests/client_id_test_master_starter_qnx.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -# Copyright (C) 2015-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# 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 client_id_test_diff_client_ids_diff_ports_master.json" - exit 1 -fi - -MASTER_JSON_FILE=$1 -CLIENT_JSON_FILE="" - -FAIL=0 - -# Start the services -export VSOMEIP_APPLICATION_NAME=client_id_test_service_one -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 1 & -CLIENT_ID_PIDS[1]=$! - -export VSOMEIP_APPLICATION_NAME=client_id_test_service_two -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 2 & -CLIENT_ID_PIDS[2]=$! - -export VSOMEIP_APPLICATION_NAME=client_id_test_service_three -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 3 & -CLIENT_ID_PIDS[3]=$! - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting client id test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE" & -else -cat < app_; std::promise registered_; std::thread app_thread_; - vsomeip::client_t client_; + std::atomic client_; }; TEST_F(client_id_utility_test, request_release_client_id) { diff --git a/test/network_tests/client_id_tests/client_id_test_master_starter.sh b/test/network_tests/client_id_tests/conf/client_id_test_master_starter.sh.in similarity index 96% rename from test/network_tests/client_id_tests/client_id_test_master_starter.sh rename to test/network_tests/client_id_tests/conf/client_id_test_master_starter.sh.in index 5495c44bf..25b66229a 100755 --- a/test/network_tests/client_id_tests/client_id_test_master_starter.sh +++ b/test/network_tests/client_id_tests/conf/client_id_test_master_starter.sh.in @@ -42,7 +42,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting client id test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./client_id_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/network_tests/client_id_tests; ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE" & else diff --git a/test/network_tests/client_id_tests/client_id_test_slave_starter.sh b/test/network_tests/client_id_tests/conf/client_id_test_slave_starter.sh.in similarity index 100% rename from test/network_tests/client_id_tests/client_id_test_slave_starter.sh rename to test/network_tests/client_id_tests/conf/client_id_test_slave_starter.sh.in diff --git a/test/network_tests/client_id_tests/client_id_test_utility.json b/test/network_tests/client_id_tests/conf/client_id_test_utility.json.in similarity index 97% rename from test/network_tests/client_id_tests/client_id_test_utility.json rename to test/network_tests/client_id_tests/conf/client_id_test_utility.json.in index a911b654b..e07eb9afc 100644 --- a/test/network_tests/client_id_tests/client_id_test_utility.json +++ b/test/network_tests/client_id_tests/conf/client_id_test_utility.json.in @@ -9,7 +9,7 @@ "enable":"false", "path":"/tmp/vsomeip.log" }, - "dlt":"true" + "dlt":"false" }, "diagnosis":"0x63", "applications": diff --git a/test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json b/test/network_tests/client_id_tests/conf/client_id_test_utility_discontinuous_masked_511.json.in similarity index 97% rename from test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json rename to test/network_tests/client_id_tests/conf/client_id_test_utility_discontinuous_masked_511.json.in index dcaaded73..af3dfd6c5 100644 --- a/test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json +++ b/test/network_tests/client_id_tests/conf/client_id_test_utility_discontinuous_masked_511.json.in @@ -9,7 +9,7 @@ "enable":"false", "path":"/tmp/vsomeip.log" }, - "dlt":"true" + "dlt":"false" }, "diagnosis":"0x63", "diagnosis_mask":"0xFB00", diff --git a/test/network_tests/client_id_tests/client_id_test_utility_masked_127.json b/test/network_tests/client_id_tests/conf/client_id_test_utility_masked_127.json.in similarity index 97% rename from test/network_tests/client_id_tests/client_id_test_utility_masked_127.json rename to test/network_tests/client_id_tests/conf/client_id_test_utility_masked_127.json.in index 7b9067854..8aa51353b 100644 --- a/test/network_tests/client_id_tests/client_id_test_utility_masked_127.json +++ b/test/network_tests/client_id_tests/conf/client_id_test_utility_masked_127.json.in @@ -9,7 +9,7 @@ "enable":"false", "path":"/tmp/vsomeip.log" }, - "dlt":"true" + "dlt":"false" }, "diagnosis":"0x63", "diagnosis_mask":"0xFF80", diff --git a/test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json b/test/network_tests/client_id_tests/conf/client_id_test_utility_masked_4095.json.in similarity index 97% rename from test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json rename to test/network_tests/client_id_tests/conf/client_id_test_utility_masked_4095.json.in index 6cef0ebc7..86044350b 100644 --- a/test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json +++ b/test/network_tests/client_id_tests/conf/client_id_test_utility_masked_4095.json.in @@ -9,7 +9,7 @@ "enable":"false", "path":"/tmp/vsomeip.log" }, - "dlt":"true" + "dlt":"false" }, "diagnosis":"0x60", "diagnosis_mask":"0xF000", diff --git a/test/network_tests/client_id_tests/client_id_test_utility_masked_511.json b/test/network_tests/client_id_tests/conf/client_id_test_utility_masked_511.json.in similarity index 97% rename from test/network_tests/client_id_tests/client_id_test_utility_masked_511.json rename to test/network_tests/client_id_tests/conf/client_id_test_utility_masked_511.json.in index 2edcc7554..a57d382a4 100644 --- a/test/network_tests/client_id_tests/client_id_test_utility_masked_511.json +++ b/test/network_tests/client_id_tests/conf/client_id_test_utility_masked_511.json.in @@ -9,7 +9,7 @@ "enable":"false", "path":"/tmp/vsomeip.log" }, - "dlt":"true" + "dlt":"false" }, "diagnosis":"0x62", "diagnosis_mask":"0xFE00", diff --git a/test/network_tests/configuration_tests/CMakeLists.txt b/test/network_tests/configuration_tests/CMakeLists.txt new file mode 100644 index 000000000..c570f3177 --- /dev/null +++ b/test/network_tests/configuration_tests/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(configuration_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + configuration_test_deprecated.json + configuration_test.json +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(configuration_test + configuration_test.cpp +) + +# Link vsomeip configuration libraries. +target_link_libraries(configuration_test + ${VSOMEIP_NAME}-cfg +) + +# Add build dependencies and link libraries to executable. +targets_link_default_libraries(configuration_test) +targets_add_default_dependencies(configuration_test) + +# Add custom test command. +add_custom_test( + NAME configuration_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/configuration_test +) diff --git a/test/network_tests/configuration_tests/configuration-test.json b/test/network_tests/configuration_tests/conf/configuration_test.json.in similarity index 99% rename from test/network_tests/configuration_tests/configuration-test.json rename to test/network_tests/configuration_tests/conf/configuration_test.json.in index 3e24819fa..6ee9168b8 100644 --- a/test/network_tests/configuration_tests/configuration-test.json +++ b/test/network_tests/configuration_tests/conf/configuration_test.json.in @@ -95,6 +95,7 @@ "id" : "0x7788", "max_dispatchers" : "25", "max_dispatch_time" : "1234", + "max_detached_thread_wait_time":"3", "threads" : "12", "request_debounce_time" : "5000", "plugins" : diff --git a/test/network_tests/configuration_tests/configuration-test-deprecated.json b/test/network_tests/configuration_tests/conf/configuration_test_deprecated.json.in similarity index 99% rename from test/network_tests/configuration_tests/configuration-test-deprecated.json rename to test/network_tests/configuration_tests/conf/configuration_test_deprecated.json.in index 3e4c118d6..a6cc993c8 100644 --- a/test/network_tests/configuration_tests/configuration-test-deprecated.json +++ b/test/network_tests/configuration_tests/conf/configuration_test_deprecated.json.in @@ -71,6 +71,7 @@ "id" : "0x7788", "max_dispatchers" : "25", "max_dispatch_time" : "1234", + "max_detached_thread_wait_time":"3", "threads" : "12", "request_debounce_time" : "5000", "plugins" : diff --git a/test/network_tests/configuration_tests/configuration-test.cpp b/test/network_tests/configuration_tests/configuration_test.cpp similarity index 97% rename from test/network_tests/configuration_tests/configuration-test.cpp rename to test/network_tests/configuration_tests/configuration_test.cpp index f2c8f8647..68e017e37 100644 --- a/test/network_tests/configuration_tests/configuration-test.cpp +++ b/test/network_tests/configuration_tests/configuration_test.cpp @@ -13,9 +13,9 @@ #include #include #include +#include #include "../implementation/configuration/include/configuration.hpp" -#include "../../implementation/plugin/include/plugin_manager_impl.hpp" #include "../../implementation/configuration/include/configuration_impl.hpp" #include "../../implementation/configuration/include/configuration_plugin.hpp" #include "../../implementation/protocol/include/protocol.hpp" @@ -23,8 +23,8 @@ namespace vsomeip = vsomeip_v3; -#define CONFIGURATION_FILE "configuration-test.json" -#define DEPRECATED_CONFIGURATION_FILE "configuration-test-deprecated.json" +#define CONFIGURATION_FILE "configuration_test.json" +#define DEPRECATED_CONFIGURATION_FILE "configuration_test_deprecated.json" #define EXPECTED_UNICAST_ADDRESS "10.0.2.15" @@ -43,6 +43,7 @@ namespace vsomeip = vsomeip_v3; // Application #define EXPECTED_APPLICATION_MAX_DISPATCHERS 25 #define EXPECTED_APPLICATION_MAX_DISPATCH_TIME 1234 +#define EXPECTED_APPLICATION_MAX_DETACHED_THREAD_WAIT_TIME 3 #define EXPECTED_APPLICATION_THREADS 12 #define EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME 5000 @@ -126,6 +127,7 @@ void check_file(const std::string &_config_file, uint32_t _expected_version_logging_interval, uint32_t _expected_application_max_dispatcher, uint32_t _expected_application_max_dispatch_time, + uint32_t _expected_application_max_detached_thread_wait_time, uint32_t _expected_application_threads, uint32_t _expected_application_request_debounce_time, const std::string &_expected_logfile, @@ -167,7 +169,7 @@ void check_file(const std::string &_config_file, // 1. Create configuration object std::shared_ptr its_configuration; - auto its_plugin = vsomeip::plugin_manager_impl::get()->get_plugin( + auto its_plugin = vsomeip::plugin_manager::get()->get_plugin( vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); if (its_plugin) { auto its_configuration_plugin @@ -332,6 +334,8 @@ void check_file(const std::string &_config_file, EXPECTED_ROUTING_MANAGER_HOST); std::size_t max_dispatch_time = its_configuration->get_max_dispatch_time( EXPECTED_ROUTING_MANAGER_HOST); + std::size_t max_detached_thread_wait_time = its_configuration->get_max_detached_thread_wait_time( + EXPECTED_ROUTING_MANAGER_HOST); std::size_t io_threads = its_configuration->get_io_thread_count( EXPECTED_ROUTING_MANAGER_HOST); std::size_t request_time = its_configuration->get_request_debouncing( @@ -341,6 +345,8 @@ void check_file(const std::string &_config_file, _expected_application_max_dispatcher, "MAX DISPATCHERS")); EXPECT_TRUE(check(max_dispatch_time, _expected_application_max_dispatch_time, "MAX DISPATCH TIME")); + EXPECT_TRUE(check(max_detached_thread_wait_time, + _expected_application_max_detached_thread_wait_time, "MAX DETACHED THREADS WAIT TIME")); EXPECT_TRUE(check(io_threads, _expected_application_threads, "IO THREADS")); EXPECT_TRUE(check(request_time, @@ -572,7 +578,7 @@ void check_file(const std::string &_config_file, vsomeip_sec_client_t its_8000_8000 = utility::create_uds_client(8000, 8000, 0); vsomeip_sec_client_t its_9000_9000 = utility::create_uds_client(9000, 9000, 0); - auto its_security = vsomeip::policy_manager_impl::get(); + auto its_security = its_configuration->get_policy_manager(); EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1234, 0x5678)); EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1235, 0x5678)); EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1236, 0x5678)); @@ -753,7 +759,7 @@ void check_file(const std::string &_config_file, EXPECT_TRUE(check(request_response_delay, static_cast(_expected_request_response_delay), "SD RESPONSE REQUEST DELAY")); EXPECT_EQ(1000u, its_configuration->get_sd_offer_debounce_time()); - ASSERT_TRUE(vsomeip::plugin_manager_impl::get()->unload_plugin(vsomeip::plugin_type_e::CONFIGURATION_PLUGIN)); + ASSERT_TRUE(vsomeip::plugin_manager::get()->unload_plugin(vsomeip::plugin_type_e::CONFIGURATION_PLUGIN)); } TEST(configuration_test, check_config_file) { @@ -767,6 +773,7 @@ TEST(configuration_test, check_config_file) { EXPECTED_VERSION_LOGGING_INTERVAL, EXPECTED_APPLICATION_MAX_DISPATCHERS, EXPECTED_APPLICATION_MAX_DISPATCH_TIME, + EXPECTED_APPLICATION_MAX_DETACHED_THREAD_WAIT_TIME, EXPECTED_APPLICATION_THREADS, EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, EXPECTED_LOGFILE, @@ -810,6 +817,7 @@ TEST(configuration_test, check_deprecated_config_file) { EXPECTED_VERSION_LOGGING_INTERVAL, EXPECTED_APPLICATION_MAX_DISPATCHERS, EXPECTED_APPLICATION_MAX_DISPATCH_TIME, + EXPECTED_APPLICATION_MAX_DETACHED_THREAD_WAIT_TIME, EXPECTED_APPLICATION_THREADS, EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, EXPECTED_LOGFILE, diff --git a/test/network_tests/cpu_load_tests/CMakeLists.txt b/test/network_tests/cpu_load_tests/CMakeLists.txt new file mode 100644 index 000000000..843edf129 --- /dev/null +++ b/test/network_tests/cpu_load_tests/CMakeLists.txt @@ -0,0 +1,44 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +# Configure necessary files into the build folder. +set(configuration_files + cpu_load_test_client_master.json + cpu_load_test_client_slave.json + cpu_load_test_master_starter.sh + cpu_load_test_service_master.json + cpu_load_test_service_slave.json + cpu_load_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(cpu_load_test_service + cpu_load_test_service.cpp + cpu_load_measurer.cpp +) + +# Add test executable. +add_executable(cpu_load_test_client + cpu_load_test_client.cpp + cpu_load_measurer.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + cpu_load_test_client + cpu_load_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME cpu_load_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/cpu_load_test_master_starter.sh + TIMEOUT 3000 +) diff --git a/test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh b/test/network_tests/cpu_load_tests/conf/cpu_load_test_master_starter.sh.in similarity index 97% rename from test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh rename to test/network_tests/cpu_load_tests/conf/cpu_load_test_master_starter.sh.in index 30010c2ee..f1950bf2b 100755 --- a/test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh +++ b/test/network_tests/cpu_load_tests/conf/cpu_load_test_master_starter.sh.in @@ -19,7 +19,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting cpu load test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./cpu_load_test_slave_starter.sh"' & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/cpu_load_tests; ./cpu_load_test_slave_starter.sh"' & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./cpu_load_test_slave_starter.sh" & else diff --git a/test/network_tests/cpu_load_tests/cpu_load_test_slave_starter.sh b/test/network_tests/cpu_load_tests/conf/cpu_load_test_slave_starter.sh.in similarity index 100% rename from test/network_tests/cpu_load_tests/cpu_load_test_slave_starter.sh rename to test/network_tests/cpu_load_tests/conf/cpu_load_test_slave_starter.sh.in diff --git a/test/network_tests/cpu_load_tests/cpu_load_test_service.cpp b/test/network_tests/cpu_load_tests/cpu_load_test_service.cpp index 3d935e395..8bf00cf2f 100644 --- a/test/network_tests/cpu_load_tests/cpu_load_test_service.cpp +++ b/test/network_tests/cpu_load_tests/cpu_load_test_service.cpp @@ -7,12 +7,13 @@ #include -#include -#include +#include // for isfinite #include #include +#include +#include #include -#include // for isfinite +#include #include "cpu_load_test_globals.hpp" #include diff --git a/test/network_tests/cyclic_event_tests/CMakeLists.txt b/test/network_tests/cyclic_event_tests/CMakeLists.txt new file mode 100644 index 000000000..761fb125a --- /dev/null +++ b/test/network_tests/cyclic_event_tests/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (C) 2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +# Configure necessary files into the build folder. +set(configuration_files + service/vsomeip_events.json + service/vsomeip_gen.json + service/vsomeip_std.json + cyclic_event_test_client.json + cyclic_event_test_master_starter.sh + cyclic_event_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(cyclic_event_test_service + cyclic_event_test_service.cpp +) + +# Add test executable. +add_executable(cyclic_event_test_client + cyclic_event_test_client.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + cyclic_event_test_client + cyclic_event_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME cyclic_event_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/cyclic_event_test_master_starter.sh + TIMEOUT 15 +) diff --git a/test/network_tests/cyclic_event_tests/conf/cyclic_event_test_client.json.in b/test/network_tests/cyclic_event_tests/conf/cyclic_event_test_client.json.in new file mode 100644 index 000000000..5adaea3aa --- /dev/null +++ b/test/network_tests/cyclic_event_tests/conf/cyclic_event_test_client.json.in @@ -0,0 +1,35 @@ +{ + "unicast": "@TEST_IP_SLAVE@", + "logging": { + "level": "debug", + "console": "true", + "file": { + "enable": "false", + "path": "/tmp/vsomeip.log" + }, + "dlt": "true" + }, + "applications": [ + { + "name": "client-sample", + "id": "0xbbbb" + } + ], + "clients": [ + { + "service": "0x1111", + "instance": "0x0001", + "unreliable": [ + 40000, + 40002 + ] + } + ], + "routing": "routingmanagerd", + "service-discovery": { + "enable": "true", + "multicast": "224.0.0.1", + "port": "30490", + "protocol": "udp" + } +} diff --git a/test/network_tests/cyclic_event_tests/conf/cyclic_event_test_master_starter.sh.in b/test/network_tests/cyclic_event_tests/conf/cyclic_event_test_master_starter.sh.in new file mode 100755 index 000000000..e2799e2c6 --- /dev/null +++ b/test/network_tests/cyclic_event_tests/conf/cyclic_event_test_master_starter.sh.in @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# Copyright (C) 2024 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/. + +# Configuration to be used by daemon and service. +export VSOMEIP_CONFIGURATION=service + +# Start the routing manager. +export VSOMEIP_APPLICATION_NAME="service-daemon" +../../../examples/routingmanagerd/routingmanagerd & +DAEMON_PID=$! + +# Start the test service. +export VSOMEIP_APPLICATION_NAME="service-sample" +./cyclic_event_test_service & +SERVICE_PID=$! + +# Start the test client. +if [ -n "$USE_LXC_TEST" ]; then + echo "starting cyclic_event_test_slave_starter.sh on slave LXC" + ssh -tt -i "$SANDBOX_ROOT_DIR"/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@"$LXC_TEST_SLAVE_IP" "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/cyclic_event_tests; ./cyclic_event_test_slave_starter.sh\"" & + echo "remote ssh job id: $!" +elif [ -n "$USE_DOCKER" ]; then + docker exec "$DOCKER_IMAGE" sh -c "cd $DOCKER_TESTS && ./cyclic_event_test_slave_starter.sh" & +else + cat <create_application("client-sample"); + ASSERT_TRUE(application) << "Should create a vsomeip application."; + ASSERT_TRUE(application->init()) << "Should initialize application."; + + // Create a promise to shutdown the service. + std::promise shutdown_promise; + auto shutdown_future = shutdown_promise.get_future(); + + // Track amount of notifications that were received. + std::atomic_uint8_t notification_count {0}; + + // Handle an event notification. + application->register_message_handler( + SERVICE_ID, INSTANCE_ID, EVENT_ID, + [runtime, application, + ¬ification_count](const std::shared_ptr /* message */) { + VSOMEIP_INFO << "Received event notification."; + + constexpr std::uint8_t MIN_NOTIFICATION_COUNT = 3; + if ((notification_count += 1) != MIN_NOTIFICATION_COUNT) { + return; + } + + auto shutdown_request = runtime->create_request(false); + shutdown_request->set_service(SERVICE_ID); + shutdown_request->set_instance(INSTANCE_ID); + shutdown_request->set_method(METHOD_ID); + shutdown_request->set_interface_version(MAJOR_VERSION); + application->send(shutdown_request); + }); + + // Handle shutdown response. + application->register_message_handler( + SERVICE_ID, INSTANCE_ID, METHOD_ID, + [&shutdown_promise](const std::shared_ptr /* message */) { + VSOMEIP_INFO << "Received shutdown response."; + shutdown_promise.set_value(true); + }); + + // Request the test service. + application->request_service(SERVICE_ID, INSTANCE_ID, MAJOR_VERSION, MINOR_VERSION); + application->request_event(SERVICE_ID, INSTANCE_ID, EVENT_ID, {EVENTGROUP_ID}); + + // Subscribe to the test service when it becomes available. + application->register_availability_handler( + SERVICE_ID, INSTANCE_ID, + [application](vsomeip::service_t /* service */, vsomeip::instance_t /* instance */, + bool is_available) { + if (is_available) { + application->subscribe(SERVICE_ID, INSTANCE_ID, EVENTGROUP_ID, MAJOR_VERSION); + } + }, + MAJOR_VERSION, MINOR_VERSION); + + // Start the vsomeip application. + std::thread worker_thread([application] { application->start(); }); + + // Wait for the shutdown call. + shutdown_future.wait(); + application->stop(); + + // Clean up worker thread. + if (worker_thread.joinable()) { + worker_thread.join(); + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/cyclic_event_tests/cyclic_event_test_globals.hpp b/test/network_tests/cyclic_event_tests/cyclic_event_test_globals.hpp new file mode 100644 index 000000000..3184037b5 --- /dev/null +++ b/test/network_tests/cyclic_event_tests/cyclic_event_test_globals.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2024 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/. + +#pragma once + +#include +#include +#include +#include +#include + +namespace cyclic_event_test { + +// Unique identifier of the test service. +constexpr vsomeip::service_t SERVICE_ID = 0x1111; + +// Unique identifier of the test service instance. +constexpr vsomeip::instance_t INSTANCE_ID = 0x0001; + +// Major version of the test service interface. +constexpr vsomeip::major_version_t MAJOR_VERSION = 0x1; + +// Minor version of the test service interface. +constexpr vsomeip::minor_version_t MINOR_VERSION = 0x0; + +// Unique identifier of the method that triggers the shutdown of the service. +constexpr vsomeip::method_t METHOD_ID = 0x0001; + +// Unique identifier of the event offered by the service. +constexpr vsomeip::event_t EVENT_ID = 0x0002; + +// Unique identifier of the event group to which the event belongs. +constexpr vsomeip::eventgroup_t EVENTGROUP_ID = 0x0001; + +} diff --git a/test/network_tests/cyclic_event_tests/cyclic_event_test_service.cpp b/test/network_tests/cyclic_event_tests/cyclic_event_test_service.cpp new file mode 100644 index 000000000..5ccb77733 --- /dev/null +++ b/test/network_tests/cyclic_event_tests/cyclic_event_test_service.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2024 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 "cyclic_event_test_globals.hpp" + +using namespace cyclic_event_test; + +TEST(CyclicEventTest, ServiceNotifiesClient) { + // Initialize the runtime. + auto runtime = vsomeip::runtime::get(); + ASSERT_TRUE(runtime) << "Should create a vsomeip runtime."; + + // Initialize the application. + auto application = runtime->create_application("service-sample"); + ASSERT_TRUE(application) << "Should create a vsomeip application."; + ASSERT_TRUE(application->init()) << "Should initialize application."; + + // Create a promise to shutdown the service. + std::promise shutdown_promise; + auto shutdown_future = shutdown_promise.get_future(); + + // Handle a shutdown method call. + application->register_message_handler(SERVICE_ID, INSTANCE_ID, METHOD_ID, + [runtime, application, &shutdown_promise]( + const std::shared_ptr message) { + VSOMEIP_INFO << "Received shutdown request."; + + auto response = runtime->create_response(message); + application->send(response); + + shutdown_promise.set_value(true); + }); + + // Offer the test service. + application->offer_service(SERVICE_ID, INSTANCE_ID, MAJOR_VERSION, MINOR_VERSION); + application->offer_event(SERVICE_ID, INSTANCE_ID, EVENT_ID, {EVENTGROUP_ID}, + vsomeip_v3::event_type_e::ET_FIELD); + + // Start the vsomeip application. + std::thread worker_thread([application] { application->start(); }); + + // Set the value of the event field. + auto payload = runtime->create_payload({0x01}); + application->notify(SERVICE_ID, INSTANCE_ID, EVENT_ID, payload); + + // Wait for the shutdown call. + shutdown_future.wait(); + + // Give the client a chance to exit cleanly. + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + application->stop(); + + // Clean up worker thread. + if (worker_thread.joinable()) { + worker_thread.join(); + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/debounce_callback_tests/CMakeLists.txt b/test/network_tests/debounce_callback_tests/CMakeLists.txt new file mode 100644 index 000000000..dca6ddadc --- /dev/null +++ b/test/network_tests/debounce_callback_tests/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(debounce_callback_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + debounce_callback_test_client.json + debounce_callback_test_master_starter.sh + debounce_callback_test_service.json + debounce_callback_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(debounce_callback_test_client + debounce_callback_test_client.cpp +) + +# Add test executable. +add_executable(debounce_callback_test_service + debounce_callback_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + debounce_callback_test_client + debounce_callback_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME debounce_callback_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/debounce_callback_test_master_starter.sh + TIMEOUT 60 +) diff --git a/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_client.json.in b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_client.json.in index c0e2b2613..8cc0e690b 100644 --- a/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_client.json.in +++ b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_client.json.in @@ -1,5 +1,14 @@ { "unicast" : "@TEST_IP_MASTER@", + "logging": { + "level": "info", + "console": "true", + "file": { + "enable": "false", + "path": "/tmp/foo.log" + }, + "dlt": "true" + }, "debounce" : [ { diff --git a/test/network_tests/debounce_callback_tests/debounce_callback_test_master_starter.sh b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_master_starter.sh.in similarity index 92% rename from test/network_tests/debounce_callback_tests/debounce_callback_test_master_starter.sh rename to test/network_tests/debounce_callback_tests/conf/debounce_callback_test_master_starter.sh.in index 87ebb2dd2..914b6ac26 100755 --- a/test/network_tests/debounce_callback_tests/debounce_callback_test_master_starter.sh +++ b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_master_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_callback_test_client.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 @@ -19,7 +19,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting debounce test on slave LXC debounce_callback_test_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./debounce_callback_test_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/debounce_callback_tests; ./debounce_callback_test_slave_starter.sh\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./debounce_callback_test_slave_starter.sh" & else diff --git a/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_service.json.in b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_service.json.in index 29efa708c..78b939cf7 100644 --- a/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_service.json.in +++ b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_service.json.in @@ -1,5 +1,14 @@ { "unicast" : "@TEST_IP_SLAVE@", + "logging": { + "level": "info", + "console": "true", + "file": { + "enable": "false", + "path": "/tmp/foo.log" + }, + "dlt": "true" + }, "services" : [ { diff --git a/test/network_tests/debounce_callback_tests/debounce_callback_test_slave_starter.sh b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_slave_starter.sh.in similarity index 91% rename from test/network_tests/debounce_callback_tests/debounce_callback_test_slave_starter.sh rename to test/network_tests/debounce_callback_tests/conf/debounce_callback_test_slave_starter.sh.in index 6b4fe8738..8bf91b5a7 100755 --- a/test/network_tests/debounce_callback_tests/debounce_callback_test_slave_starter.sh +++ b/test/network_tests/debounce_callback_tests/conf/debounce_callback_test_slave_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_callback_test_service.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 diff --git a/test/network_tests/debounce_callback_tests/debounce_callback_test_client.cpp b/test/network_tests/debounce_callback_tests/debounce_callback_test_client.cpp index f7a6c2a37..8ba0df5df 100644 --- a/test/network_tests/debounce_callback_tests/debounce_callback_test_client.cpp +++ b/test/network_tests/debounce_callback_tests/debounce_callback_test_client.cpp @@ -10,73 +10,62 @@ #include "debounce_callback_test_client.hpp" -static std::vector > payloads__; - -debounce_test_client::debounce_test_client(int64_t _interval) - : interval(_interval), - index_(0), - is_available_(false), - runner_(std::bind(&debounce_test_client::run, this)), - app_(vsomeip::runtime::get()->create_application("debounce_timeout_test_client")) { -} +static std::vector> payloads__; + +debounce_test_client::debounce_test_client(int64_t _interval) : + interval(_interval), index_(0), is_available_(false), + runner_(std::bind(&debounce_test_client::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_timeout_test_client")) { } -bool -debounce_test_client::init() { +bool debounce_test_client::init() { bool its_result = app_->init(); if (its_result) { - app_->register_availability_handler( - DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - std::bind(&debounce_test_client::on_availability, this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3), - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->register_availability_handler(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + std::bind(&debounce_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); app_->register_message_handler( DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, - std::bind(&debounce_test_client::on_message, this, - std::placeholders::_1)); - app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); - app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT); - app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT_2); + std::bind(&debounce_test_client::on_message, this, std::placeholders::_1)); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, + DEBOUNCE_EVENT); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, + DEBOUNCE_EVENT_2); } return its_result; } -void -debounce_test_client::start() { +void debounce_test_client::start() { + VSOMEIP_INFO << "Starting Client..."; app_->start(); } -void -debounce_test_client::stop() { +void debounce_test_client::stop() { + VSOMEIP_INFO << "Stopping Client..."; app_->stop(); } -void -debounce_test_client::run() { +void debounce_test_client::run() { { std::unique_lock its_lock(run_mutex_); while (!is_available_) { - auto its_status - = run_condition_.wait_for(its_lock, std::chrono::milliseconds(15000)); + auto its_status = run_condition_.wait_for(its_lock, std::chrono::milliseconds(15000)); EXPECT_EQ(its_status, std::cv_status::no_timeout); if (its_status == std::cv_status::timeout) { - VSOMEIP_ERROR << __func__ << ": Debounce service did not become available after 15s."; + VSOMEIP_ERROR << __func__ + << ": Debounce service did not become available after 15s."; stop(); return; } @@ -96,20 +85,16 @@ debounce_test_client::run() { stop(); } -void -debounce_test_client::wait() { +void debounce_test_client::wait() { if (runner_.joinable()) runner_.join(); } -void -debounce_test_client::on_availability( - vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available) { +void debounce_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { - if (_service == DEBOUNCE_SERVICE - && _instance == DEBOUNCE_INSTANCE) { + if (_service == DEBOUNCE_SERVICE && _instance == DEBOUNCE_INSTANCE) { if (_is_available) { VSOMEIP_ERROR << __func__ << ": Debounce service becomes available."; @@ -127,36 +112,33 @@ debounce_test_client::on_availability( } } -void -debounce_test_client::on_message( - const std::shared_ptr &_message) { +void debounce_test_client::on_message(const std::shared_ptr& _message) { std::stringstream s; s << "RECV: "; - for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) + for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) { s << std::hex << std::setw(2) << std::setfill('0') - << (int)_message->get_payload()->get_data()[i] << ' '; - VSOMEIP_INFO << s.str(); + << static_cast(_message->get_payload()->get_data()[i]) << ' '; + } + VSOMEIP_DEBUG << s.str(); // Check if message received is equal to the one it was expecting if (DEBOUNCE_SERVICE == _message->get_service() - && (DEBOUNCE_EVENT == _message->get_method() || DEBOUNCE_EVENT_2 == _message->get_method())) { + && (DEBOUNCE_EVENT == _message->get_method() + || DEBOUNCE_EVENT_2 == _message->get_method())) { bool is_equal = compare_payload(_message->get_payload(), index_++); EXPECT_EQ(is_equal, true); } } -bool -debounce_test_client::compare_payload( - const std::shared_ptr &_payload, - std::size_t _index) const { +bool debounce_test_client::compare_payload(const std::shared_ptr& _payload, + std::size_t _index) const { auto its_expected_payload = payloads__[_index]; return (*_payload == *its_expected_payload); } -void -debounce_test_client::run_test() { +void debounce_test_client::run_test() { // Trigger the test auto its_runtime = vsomeip::runtime::get(); @@ -173,15 +155,12 @@ debounce_test_client::run_test() { std::this_thread::sleep_for(std::chrono::seconds(23)); } -void -debounce_test_client::unsubscribe_all() { +void debounce_test_client::unsubscribe_all() { - app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP); + app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP); } -void -debounce_test_client::stop_service() { +void debounce_test_client::stop_service() { auto its_runtime = vsomeip::runtime::get(); auto its_payload = its_runtime->create_payload(); @@ -195,82 +174,79 @@ debounce_test_client::stop_service() { app_->send(its_message); } -size_t -debounce_test_client::getIndex() { +size_t debounce_test_client::getIndex() { return index_; } TEST(debounce_timeout_test, callback) { // Interval time of 2 seconds debounce_test_client its_client(2000); - if (its_client.init()) { - VSOMEIP_ERROR << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - // Check it got all messages - EXPECT_EQ(its_client.getIndex(), payloads__.size()); - } else { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + ASSERT_TRUE(its_client.init()); + VSOMEIP_ERROR << "Debounce Client successfully initialized!"; + its_client.start(); + its_client.wait(); + + // Check it got all messages + EXPECT_EQ(its_client.getIndex(), payloads__.size()); } int main(int argc, char** argv) { std::shared_ptr its_payload; its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); payloads__.push_back(its_payload); - + its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00}); payloads__.push_back(its_payload); - + its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00}); payloads__.push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0D }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0D}); payloads__.push_back(its_payload); - + its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0D }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0D}); payloads__.push_back(its_payload); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/network_tests/debounce_callback_tests/debounce_callback_test_client.hpp b/test/network_tests/debounce_callback_tests/debounce_callback_test_client.hpp index 2b6da025c..52c810a32 100644 --- a/test/network_tests/debounce_callback_tests/debounce_callback_test_client.hpp +++ b/test/network_tests/debounce_callback_tests/debounce_callback_test_client.hpp @@ -30,17 +30,16 @@ class debounce_test_client { size_t getIndex(); private: - void on_availability( - vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available); - void on_message(const std::shared_ptr &_message); + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available); + void on_message(const std::shared_ptr& _message); void run_test(); void unsubscribe_all(); void stop_service(); - bool compare_payload(const std::shared_ptr &_payload, - std::size_t _index) const; + bool compare_payload(const std::shared_ptr& _payload, + std::size_t _index) const; private: int64_t interval; diff --git a/test/network_tests/debounce_callback_tests/debounce_callback_test_service.cpp b/test/network_tests/debounce_callback_tests/debounce_callback_test_service.cpp index 35ac2088d..f67366f5e 100644 --- a/test/network_tests/debounce_callback_tests/debounce_callback_test_service.cpp +++ b/test/network_tests/debounce_callback_tests/debounce_callback_test_service.cpp @@ -7,62 +7,50 @@ #include "debounce_callback_test_service.hpp" -debounce_test_service::debounce_test_service() - : runner_(std::bind(&debounce_test_service::run, this)), - app_(vsomeip::runtime::get()->create_application("debounce_timeout_test_service")) { +debounce_test_service::debounce_test_service() : + runner_(std::bind(&debounce_test_service::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_timeout_test_service")) { } -} - -bool -debounce_test_service::init() { +bool debounce_test_service::init() { bool is_initialized = app_->init(); if (is_initialized) { app_->register_message_handler( DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_START_METHOD, - std::bind(&debounce_test_service::on_start, this, - std::placeholders::_1)); + std::bind(&debounce_test_service::on_start, this, std::placeholders::_1)); app_->register_message_handler( DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, - std::bind(&debounce_test_service::on_stop, this, - std::placeholders::_1)); - app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + std::bind(&debounce_test_service::on_stop, this, std::placeholders::_1)); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); } return is_initialized; } -void -debounce_test_service::start() { +void debounce_test_service::start() { + VSOMEIP_INFO << "Starting Service..."; app_->start(); } -void -debounce_test_service::stop() { +void debounce_test_service::stop() { + VSOMEIP_INFO << "Stopping Service..."; app_->stop(); } -void -debounce_test_service::run() { +void debounce_test_service::run() { { std::unique_lock its_lock(run_mutex_); - auto its_result = run_condition_.wait_for( - its_lock, std::chrono::milliseconds(5000)); + auto its_result = run_condition_.wait_for(its_lock, std::chrono::milliseconds(5000)); if (its_result == std::cv_status::timeout) return; } @@ -70,16 +58,13 @@ debounce_test_service::run() { start_test(); } -void -debounce_test_service::wait() { +void debounce_test_service::wait() { if (runner_.joinable()) runner_.join(); } -void -debounce_test_service::on_start( - const std::shared_ptr &_message) { +void debounce_test_service::on_start(const std::shared_ptr& _message) { (void)_message; @@ -87,10 +72,7 @@ debounce_test_service::on_start( run_condition_.notify_one(); } - -void -debounce_test_service::on_stop( - const std::shared_ptr &_message) { +void debounce_test_service::on_stop(const std::shared_ptr& _message) { (void)_message; @@ -98,62 +80,61 @@ debounce_test_service::on_stop( stop(); } -void -debounce_test_service::start_test() { +void debounce_test_service::start_test() { auto its_payload = vsomeip::runtime::get()->create_payload(); // To check if debouncer send the last message after timeout - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent first message!"; std::this_thread::sleep_for(std::chrono::seconds(1)); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent second message!"; std::this_thread::sleep_for(std::chrono::seconds(3)); // To check normal function of the debouncer - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent third message!"; std::this_thread::sleep_for(std::chrono::seconds(3)); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent fourth message!"; std::this_thread::sleep_for(std::chrono::seconds(3)); // To check only one message is forwarded after timeout - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent fifth message!"; std::this_thread::sleep_for(std::chrono::milliseconds(500)); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent sixth message!"; std::this_thread::sleep_for(std::chrono::milliseconds(500)); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent seventh message!"; std::this_thread::sleep_for(std::chrono::seconds(3)); // To check the interaction when two events use the debounce - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent eight message!"; app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); VSOMEIP_INFO << "Sent first event 2 message!"; std::this_thread::sleep_for(std::chrono::milliseconds(500)); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent ninth message!"; app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); VSOMEIP_INFO << "Sent second event 2 message!"; std::this_thread::sleep_for(std::chrono::milliseconds(500)); - its_payload->set_data({ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 }); + its_payload->set_data({0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); VSOMEIP_INFO << "Sent tenth message!"; app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); @@ -164,28 +145,24 @@ debounce_test_service::start_test() { // Testing with lots of messages VSOMEIP_INFO << "Sending lot of messages!"; - for (int i = 0; i < 30; i++) - { - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, (unsigned char)(i%16) }); + for (int i = 0; i < 30; i++) { + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, (unsigned char)(i % 16)}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } - - } TEST(debounce_timeout_test, callback) { debounce_test_service its_service; - if (its_service.init()) { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/test/network_tests/debounce_callback_tests/debounce_callback_test_service.hpp b/test/network_tests/debounce_callback_tests/debounce_callback_test_service.hpp index 0a9ed3fbc..ba418c16d 100644 --- a/test/network_tests/debounce_callback_tests/debounce_callback_test_service.hpp +++ b/test/network_tests/debounce_callback_tests/debounce_callback_test_service.hpp @@ -29,8 +29,8 @@ class debounce_test_service { void wait(); private: - void on_start(const std::shared_ptr &_message); - void on_stop(const std::shared_ptr &_message); + void on_start(const std::shared_ptr& _message); + void on_stop(const std::shared_ptr& _message); void start_test(); @@ -41,5 +41,4 @@ class debounce_test_service { std::shared_ptr app_; }; - #endif // DEBOUNCE_CALLBACK_TEST_SERVICE_HPP_ diff --git a/test/network_tests/debounce_filter_tests/CMakeLists.txt b/test/network_tests/debounce_filter_tests/CMakeLists.txt new file mode 100644 index 000000000..af116fc4e --- /dev/null +++ b/test/network_tests/debounce_filter_tests/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(debounce_filter_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + debounce_filter_test_client.json + debounce_filter_test_master_starter.sh + debounce_filter_test_service.json + debounce_filter_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(debounce_filter_test_client + debounce_filter_test_client.cpp +) + +# Add test executable. +add_executable(debounce_filter_test_service + debounce_filter_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + debounce_filter_test_client + debounce_filter_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME debounce_filter_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/debounce_filter_test_master_starter.sh +) diff --git a/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_client.json.in b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_client.json.in index 8792425e5..aa781685b 100644 --- a/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_client.json.in +++ b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_client.json.in @@ -1,10 +1,10 @@ { "unicast" : "@TEST_IP_MASTER@", "logging": { - "level": "verbose", + "level": "info", "console": "true", "file": { - "enable": "true", + "enable": "false", "path": "/tmp/foo.log" }, "dlt": "true" diff --git a/test/network_tests/debounce_filter_tests/debounce_filter_test_master_starter.sh b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_master_starter.sh.in similarity index 92% rename from test/network_tests/debounce_filter_tests/debounce_filter_test_master_starter.sh rename to test/network_tests/debounce_filter_tests/conf/debounce_filter_test_master_starter.sh.in index a80a54ff9..e85e01008 100755 --- a/test/network_tests/debounce_filter_tests/debounce_filter_test_master_starter.sh +++ b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_master_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_filter_test_client.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 @@ -19,7 +19,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting debounce_filter test on slave LXC debounce_filter_test_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./debounce_filter_test_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/debounce_filter_tests; ./debounce_filter_test_slave_starter.sh\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./debounce_filter_test_slave_starter.sh" & else diff --git a/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_service.json.in b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_service.json.in index d5b34e5e4..caacc1f8e 100644 --- a/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_service.json.in +++ b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_service.json.in @@ -1,10 +1,10 @@ { "unicast" : "@TEST_IP_SLAVE@", "logging": { - "level": "verbose", + "level": "info", "console": "true", "file": { - "enable": "true", + "enable": "false", "path": "/tmp/foo.log" }, "dlt": "true" diff --git a/test/network_tests/debounce_filter_tests/debounce_filter_test_slave_starter.sh b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_slave_starter.sh.in similarity index 93% rename from test/network_tests/debounce_filter_tests/debounce_filter_test_slave_starter.sh rename to test/network_tests/debounce_filter_tests/conf/debounce_filter_test_slave_starter.sh.in index ef0fea1fd..a462ba268 100755 --- a/test/network_tests/debounce_filter_tests/debounce_filter_test_slave_starter.sh +++ b/test/network_tests/debounce_filter_tests/conf/debounce_filter_test_slave_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_filter_test_service.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 diff --git a/test/network_tests/debounce_filter_tests/debounce_filter_test_client.cpp b/test/network_tests/debounce_filter_tests/debounce_filter_test_client.cpp index 0bd89131f..4cc33a412 100644 --- a/test/network_tests/debounce_filter_tests/debounce_filter_test_client.cpp +++ b/test/network_tests/debounce_filter_tests/debounce_filter_test_client.cpp @@ -12,66 +12,53 @@ static std::vector>> payloads__; -debounce_test_client::debounce_test_client(int64_t _interval) - : interval(_interval), - index_(0), - is_available_(false), - runner_(std::bind(&debounce_test_client::run, this)), - app_(vsomeip::runtime::get()->create_application("debounce_test_client")) -{ -} +debounce_test_client::debounce_test_client(int64_t _interval) : + interval(_interval), index_(0), is_available_(false), + runner_(std::bind(&debounce_test_client::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_client")), sum_time(0) { } -bool debounce_test_client::init() -{ +bool debounce_test_client::init() { dBFilter.interval_ = interval; bool its_result = app_->init(); - if (its_result) - { - app_->register_availability_handler( - DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - std::bind(&debounce_test_client::on_availability, this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3), - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + if (its_result) { + app_->register_availability_handler(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + std::bind(&debounce_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); app_->register_message_handler( - DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, - std::bind(&debounce_test_client::on_message, this, - std::placeholders::_1)); - app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT, {DEBOUNCE_EVENTGROUP}, - vsomeip::event_type_e::ET_FIELD, + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, + std::bind(&debounce_test_client::on_message, this, std::placeholders::_1)); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); - app_->subscribe_with_debounce(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT, dBFilter); + app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->subscribe_with_debounce(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, + DEBOUNCE_MAJOR, DEBOUNCE_EVENT, dBFilter); } return its_result; } -void debounce_test_client::start() -{ +void debounce_test_client::start() { + VSOMEIP_INFO << "Starting Client..."; app_->start(); } -void debounce_test_client::stop() -{ +void debounce_test_client::stop() { + VSOMEIP_INFO << "Stopping Client..."; app_->stop(); } -void debounce_test_client::run() -{ +void debounce_test_client::run() { { std::unique_lock its_lock(run_mutex_); - while (!is_available_) - { + while (!is_available_) { auto its_status = run_condition_.wait_for(its_lock, std::chrono::milliseconds(15000)); EXPECT_EQ(its_status, std::cv_status::no_timeout); - if (its_status == std::cv_status::timeout) - { - VSOMEIP_ERROR << __func__ << ": Debounce service did not become available after 15s."; + if (its_status == std::cv_status::timeout) { + VSOMEIP_ERROR << __func__ + << ": Debounce service did not become available after 15s."; stop(); return; } @@ -91,30 +78,23 @@ void debounce_test_client::run() stop(); } -void debounce_test_client::wait() -{ +void debounce_test_client::wait() { if (runner_.joinable()) runner_.join(); } -void debounce_test_client::on_availability( - vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available) -{ - if (_service == DEBOUNCE_SERVICE && _instance == DEBOUNCE_INSTANCE) - { +void debounce_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + if (_service == DEBOUNCE_SERVICE && _instance == DEBOUNCE_INSTANCE) { - if (_is_available) - { + if (_is_available) { VSOMEIP_INFO << __func__ << ": Debounce service becomes available."; { std::lock_guard its_lock(run_mutex_); is_available_ = true; } run_condition_.notify_one(); - } - else - { + } else { VSOMEIP_INFO << __func__ << ": Debounce service becomes unavailable."; std::lock_guard its_lock(run_mutex_); @@ -123,18 +103,37 @@ void debounce_test_client::on_availability( } } -void debounce_test_client::on_message( - const std::shared_ptr &_message) -{ - if (DEBOUNCE_SERVICE == _message->get_service() && DEBOUNCE_EVENT == _message->get_method()) - { - // VSOMEIP_INFO << "Got new message: " << nb_msgs_rcvd << std::endl; +void debounce_test_client::on_message(const std::shared_ptr& _message) { + if (!nb_msgs_rcvd) { + time_start = std::chrono::high_resolution_clock::now(); + time_last = time_start; + } else { + time_last = std::chrono::high_resolution_clock::now(); + } + + std::stringstream s; + s << "RECV: "; + for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) { + s << std::hex << std::setw(3) << std::setfill('0') + << static_cast(_message->get_payload()->get_data()[i]) << " "; + } + + if (DEBOUNCE_SERVICE == _message->get_service() && DEBOUNCE_EVENT == _message->get_method()) { nb_msgs_rcvd++; + s << "\t- Message: " << std::dec << std::setw(2) << nb_msgs_rcvd; + + if (nb_msgs_rcvd >= 2) { + std::chrono::duration elapsed_time_ms = (time_last - time_start); + sum_time += std::chrono::duration_cast(elapsed_time_ms); + s << " Average interval is " << get_avgtime().count() << " ms"; + } + VSOMEIP_DEBUG << s.str(); + s.clear(); } + time_start = time_last; } -void debounce_test_client::run_test() -{ +void debounce_test_client::run_test() { // Trigger the test auto its_runtime = vsomeip::runtime::get(); auto its_payload = its_runtime->create_payload(); @@ -150,14 +149,11 @@ void debounce_test_client::run_test() std::this_thread::sleep_for(std::chrono::seconds(15)); } -void debounce_test_client::unsubscribe_all() -{ - app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP); +void debounce_test_client::unsubscribe_all() { + app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP); } -void debounce_test_client::stop_service() -{ +void debounce_test_client::stop_service() { auto its_runtime = vsomeip::runtime::get(); auto its_payload = its_runtime->create_payload(); auto its_message = its_runtime->create_request(false); @@ -174,64 +170,46 @@ int64_t debounce_test_client::getNbMsgsRcvd() { return nb_msgs_rcvd; } -TEST(debounce_test, normal_interval) -{ +std::chrono::milliseconds debounce_test_client::get_avgtime() { + return (sum_time / (getNbMsgsRcvd() - 1)); +} + +TEST(debounce_test, normal_interval) { debounce_test_client its_client(DEBOUNCE_INTERVAL_1); - if (its_client.init()) - { - VSOMEIP_INFO << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - // With a debounce interval of 100 miliseconds, the client is expected to receive a total of about 100-101 messages - // Using limits instead of comparing to one number because CI doesn't always behave as expected - EXPECT_GE(its_client.getNbMsgsRcvd(), 90); - EXPECT_LE(its_client.getNbMsgsRcvd(), 110); + ASSERT_TRUE(its_client.init()); + VSOMEIP_INFO << "Debounce client successfully initialized!"; + its_client.start(); + its_client.wait(); - } - else - { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + // Average Interval should be between 95ms and 105ms + EXPECT_GE(its_client.get_avgtime().count(), (double)DEBOUNCE_INTERVAL_1 - 5); + EXPECT_LE(its_client.get_avgtime().count(), (double)DEBOUNCE_INTERVAL_1 + 5); } -TEST(debounce_test, large_interval) -{ +TEST(debounce_test, large_interval) { debounce_test_client its_client(DEBOUNCE_INTERVAL_2); - if (its_client.init()) - { - VSOMEIP_INFO << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - // With a debounce interval of 100 miliseconds, the client is expected to receive a total of about 10-11 messages - // Using limits instead of comparing to one number because CI doesn't always behave as expected - EXPECT_GE(its_client.getNbMsgsRcvd(), 8); - EXPECT_LE(its_client.getNbMsgsRcvd(), 16); - } - else - { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + ASSERT_TRUE(its_client.init()); + VSOMEIP_INFO << "Debounce client successfully initialized!"; + its_client.start(); + its_client.wait(); + + // Average Interval should be between 995ms and 1005ms + EXPECT_GE(its_client.get_avgtime().count(), (double)DEBOUNCE_INTERVAL_2 - 5); + EXPECT_LE(its_client.get_avgtime().count(), (double)DEBOUNCE_INTERVAL_2 + 5); } -TEST(debounce_test, disable) -{ +TEST(debounce_test, disable) { debounce_test_client its_client(DEBOUNCE_INTERVAL_3); - if (its_client.init()) - { - VSOMEIP_INFO << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - // With a debounce interval disabled (-1), the client is expected to not receive any message - EXPECT_EQ(its_client.getNbMsgsRcvd(), 0); - } - else - { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + ASSERT_TRUE(its_client.init()); + VSOMEIP_INFO << "Debounce Client successfully initialized!"; + its_client.start(); + its_client.wait(); + + // With a debounce interval disabled (-1), the client is expected to not receive any message + EXPECT_EQ(its_client.getNbMsgsRcvd(), 0); } -int main(int argc, char **argv) -{ +int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/network_tests/debounce_filter_tests/debounce_filter_test_client.hpp b/test/network_tests/debounce_filter_tests/debounce_filter_test_client.hpp index 59bf22c49..ba58b14c1 100644 --- a/test/network_tests/debounce_filter_tests/debounce_filter_test_client.hpp +++ b/test/network_tests/debounce_filter_tests/debounce_filter_test_client.hpp @@ -28,12 +28,12 @@ class debounce_test_client { void wait(); int64_t getNbMsgsRcvd(); + std::chrono::milliseconds get_avgtime(); private: - void on_availability( - vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available); - void on_message(const std::shared_ptr &_message); + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available); + void on_message(const std::shared_ptr& _message); void run_test(); void unsubscribe_all(); @@ -54,6 +54,9 @@ class debounce_test_client { vsomeip::debounce_filter_t dBFilter; int64_t nb_msgs_rcvd = 0; + std::chrono::milliseconds sum_time; + std::chrono::time_point time_start; + std::chrono::time_point time_last; }; #endif // DEBOUNCE_TEST_CLIENT_HPP_ diff --git a/test/network_tests/debounce_filter_tests/debounce_filter_test_service.cpp b/test/network_tests/debounce_filter_tests/debounce_filter_test_service.cpp index 621a0a727..8993af5ab 100644 --- a/test/network_tests/debounce_filter_tests/debounce_filter_test_service.cpp +++ b/test/network_tests/debounce_filter_tests/debounce_filter_test_service.cpp @@ -7,54 +7,42 @@ #include "debounce_filter_test_service.hpp" -debounce_test_service::debounce_test_service() - : is_running_(true), - runner_(std::bind(&debounce_test_service::run, this)), - app_(vsomeip::runtime::get()->create_application("debounce_test_service")) -{ -} +debounce_test_service::debounce_test_service() : + is_running_(true), runner_(std::bind(&debounce_test_service::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_service")) { } -bool debounce_test_service::init() -{ +bool debounce_test_service::init() { bool is_initialized = app_->init(); - if (is_initialized) - { + if (is_initialized) { app_->register_message_handler( - DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_START_METHOD, - std::bind(&debounce_test_service::on_start, this, - std::placeholders::_1)); + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_START_METHOD, + std::bind(&debounce_test_service::on_start, this, std::placeholders::_1)); app_->register_message_handler( - DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, - std::bind(&debounce_test_service::on_stop, this, - std::placeholders::_1)); - app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT, {DEBOUNCE_EVENTGROUP}, - vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, + std::bind(&debounce_test_service::on_stop, this, std::placeholders::_1)); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); } return is_initialized; } -void debounce_test_service::start() -{ +void debounce_test_service::start() { + VSOMEIP_INFO << "Starting Service..."; app_->start(); } -void debounce_test_service::stop() -{ +void debounce_test_service::stop() { + VSOMEIP_INFO << "Stopping Service..."; app_->stop(); } -void debounce_test_service::run() -{ +void debounce_test_service::run() { { std::unique_lock its_lock(run_mutex_); - auto its_result = run_condition_.wait_for( - its_lock, std::chrono::milliseconds(5000)); + auto its_result = run_condition_.wait_for(its_lock, std::chrono::milliseconds(5000)); if (its_result == std::cv_status::timeout) return; } @@ -62,74 +50,57 @@ void debounce_test_service::run() start_test(); } -void debounce_test_service::wait() -{ +void debounce_test_service::wait() { if (runner_.joinable()) runner_.join(); } -void debounce_test_service::on_start( - const std::shared_ptr &) -{ +void debounce_test_service::on_start(const std::shared_ptr&) { VSOMEIP_INFO << __func__ << ": Starting test"; run_condition_.notify_one(); } -void debounce_test_service::on_stop( - const std::shared_ptr &) -{ +void debounce_test_service::on_stop(const std::shared_ptr&) { VSOMEIP_INFO << __func__ << ": Received a STOP command."; is_running_ = false; stop(); } -void debounce_test_service::start_test() -{ +void debounce_test_service::start_test() { auto its_payload = vsomeip::runtime::get()->create_payload(); - for (int i = 0; i <= 1000; i++) - { + for (int i = 0; i <= 1000; i++) { its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); std::this_thread::sleep_for(std::chrono::milliseconds(5)); - its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); std::this_thread::sleep_for(std::chrono::milliseconds(5)); } } -TEST(debounce_test, normal_interval) -{ +TEST(debounce_test, normal_interval) { debounce_test_service its_service; - if (its_service.init()) - { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } -TEST(debounce_test, large_interval) -{ +TEST(debounce_test, large_interval) { debounce_test_service its_service; - if (its_service.init()) - { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } -TEST(debounce_test, disable) -{ +TEST(debounce_test, disable) { debounce_test_service its_service; - if (its_service.init()) - { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } -int main(int argc, char **argv) -{ +int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/network_tests/debounce_filter_tests/debounce_filter_test_service.hpp b/test/network_tests/debounce_filter_tests/debounce_filter_test_service.hpp index 5275a8395..0b4dde643 100644 --- a/test/network_tests/debounce_filter_tests/debounce_filter_test_service.hpp +++ b/test/network_tests/debounce_filter_tests/debounce_filter_test_service.hpp @@ -29,8 +29,8 @@ class debounce_test_service { void wait(); private: - void on_start(const std::shared_ptr &); - void on_stop(const std::shared_ptr &); + void on_start(const std::shared_ptr&); + void on_stop(const std::shared_ptr&); void start_test(); diff --git a/test/network_tests/debounce_frequency_tests/CMakeLists.txt b/test/network_tests/debounce_frequency_tests/CMakeLists.txt new file mode 100644 index 000000000..28206ac88 --- /dev/null +++ b/test/network_tests/debounce_frequency_tests/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(debounce_frequency_test LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + debounce_frequency_test_client.json + debounce_frequency_test_master_starter.sh + debounce_frequency_test_service.json + debounce_frequency_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(debounce_frequency_test_client + debounce_frequency_test_client.cpp +) + +# Add test executable. +add_executable(debounce_frequency_test_service + debounce_frequency_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + debounce_frequency_test_client + debounce_frequency_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME debounce_frequency_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/debounce_frequency_test_master_starter.sh + TIMEOUT 60 +) diff --git a/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_client.json.in b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_client.json.in index ff0969870..3281c47c4 100644 --- a/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_client.json.in +++ b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_client.json.in @@ -1,5 +1,14 @@ { "unicast": "@TEST_IP_MASTER@", + "logging": { + "level": "info", + "console": "true", + "file": { + "enable": "false", + "path": "/tmp/foo.log" + }, + "dlt": "true" + }, "debounce": [ { "service": "0xb657", diff --git a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_master_starter.sh b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_master_starter.sh.in similarity index 92% rename from test/network_tests/debounce_frequency_tests/debounce_frequency_test_master_starter.sh rename to test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_master_starter.sh.in index 92dd8cd94..e372519cd 100755 --- a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_master_starter.sh +++ b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_master_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_frequency_test_client.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 @@ -19,7 +19,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting debounce test on slave LXC debounce_frequency_test_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./debounce_frequency_test_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/debounce_frequency_tests; ./debounce_frequency_test_slave_starter.sh\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./debounce_frequency_test_slave_starter.sh" & else diff --git a/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_service.json.in b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_service.json.in index 29efa708c..78b939cf7 100644 --- a/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_service.json.in +++ b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_service.json.in @@ -1,5 +1,14 @@ { "unicast" : "@TEST_IP_SLAVE@", + "logging": { + "level": "info", + "console": "true", + "file": { + "enable": "false", + "path": "/tmp/foo.log" + }, + "dlt": "true" + }, "services" : [ { diff --git a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_slave_starter.sh b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_slave_starter.sh.in similarity index 92% rename from test/network_tests/debounce_frequency_tests/debounce_frequency_test_slave_starter.sh rename to test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_slave_starter.sh.in index ae3343328..2bd5a89c8 100755 --- a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_slave_starter.sh +++ b/test/network_tests/debounce_frequency_tests/conf/debounce_frequency_test_slave_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_frequency_test_service.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 diff --git a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.cpp b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.cpp index 2baa1ec3f..4467b10fe 100644 --- a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.cpp +++ b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.cpp @@ -10,11 +10,9 @@ #include "debounce_frequency_test_client.hpp" - // Flag the desired event availability void test_client::on_availability(vsomeip::service_t service_, vsomeip::instance_t instance_, - bool _is_available) -{ + bool _is_available) { if (_is_available && service_ == DEBOUNCE_SERVICE && instance_ == DEBOUNCE_INSTANCE) { std::unique_lock lk(mutex); availability = true; @@ -23,8 +21,15 @@ void test_client::on_availability(vsomeip::service_t service_, vsomeip::instance } // When a message is received, verify if it is one of the required events -void test_client::on_message(const std::shared_ptr &_message) -{ +void test_client::on_message(const std::shared_ptr& _message) { + std::stringstream s; + s << "RECV: "; + for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) { + s << std::hex << std::setw(2) << std::setfill('0') + << static_cast(_message->get_payload()->get_data()[i]) << " "; + } + VSOMEIP_DEBUG << s.str(); + if (DEBOUNCE_SERVICE == _message->get_service() && DEBOUNCE_EVENT == _message->get_method()) { std::unique_lock lk(event_counter_mutex); event_1_recv_messages++; @@ -37,43 +42,42 @@ void test_client::on_message(const std::shared_ptr &_message) } } -test_client::test_client(const char *app_name_, const char *app_id_) : vsomeip_utilities::base_vsip_app(app_name_, app_id_) -{ +test_client::test_client(const char* app_name_, const char* app_id_) : + vsomeip_utilities::base_vsip_app(app_name_, app_id_) { _app->register_availability_handler(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - std::bind(&test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3), - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); - _app->register_message_handler(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, - std::bind(&test_client::on_message, this, std::placeholders::_1)); - _app->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, vsomeip::reliability_type_e::RT_UNRELIABLE); + std::bind(&test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + _app->register_message_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, + std::bind(&test_client::on_message, this, std::placeholders::_1)); + _app->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, {DEBOUNCE_EVENTGROUP}, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); _app->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, - { DEBOUNCE_EVENTGROUP }, vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); _app->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); _app->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, - DEBOUNCE_EVENT); + DEBOUNCE_EVENT); _app->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, - DEBOUNCE_EVENT_2); + DEBOUNCE_EVENT_2); } -int test_client::was_event1_recv() -{ +int test_client::was_event1_recv() { std::unique_lock lk(event_counter_mutex); return event_1_recv_messages; } -int test_client::was_event2_recv() -{ +int test_client::was_event2_recv() { std::unique_lock lk(event_counter_mutex); return event_2_recv_messages; } -void test_client::send_request() -{ +void test_client::send_request() { std::unique_lock lk(mutex); // Only send the requests when the service availability is secured if (condition_availability.wait_for(lk, std::chrono::milliseconds(15000), @@ -86,35 +90,30 @@ void test_client::send_request() _app->send(its_message); } - EXPECT_TRUE(availability) - << "Events expected by the client were not available for 15 seconds "; + EXPECT_TRUE(availability) << "Events expected by the client were not available for 15 seconds "; // Wait for Server to send all the messages std::this_thread::sleep_for(std::chrono::seconds(10)); } -void test_client::unsubscribe_all() -{ +void test_client::unsubscribe_all() { _app->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP); } -void test_client::stop_service() -{ - auto its_message = vsomeip_utilities::create_standard_vsip_request(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_STOP_METHOD, DEBOUNCE_MAJOR, - vsomeip::message_type_e::MT_REQUEST_NO_RETURN); +void test_client::stop_service() { + auto its_message = vsomeip_utilities::create_standard_vsip_request( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, DEBOUNCE_MAJOR, + vsomeip::message_type_e::MT_REQUEST_NO_RETURN); _app->send(its_message); } -test_client::~test_client() -{ +test_client::~test_client() { unsubscribe_all(); stop_service(); } -TEST(debounce_frequency_test, client) -{ - test_client debounce_client("debounce_frequency_test_client","DFTC"); +TEST(debounce_frequency_test, client) { + test_client debounce_client("debounce_frequency_test_client", "DFTC"); // Request the server to send the test messages debounce_client.send_request(); @@ -126,8 +125,7 @@ TEST(debounce_frequency_test, client) << debounce_client.was_event2_recv() << " times."; } -int main(int argc, char **argv) -{ +int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.hpp b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.hpp index 9911c9178..4b0c12c0c 100644 --- a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.hpp +++ b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_client.hpp @@ -17,26 +17,25 @@ #include "debounce_frequency_test_common.hpp" #include -class test_client : public vsomeip_utilities::base_vsip_app -{ +class test_client : public vsomeip_utilities::base_vsip_app { private: std::condition_variable condition_availability; std::mutex mutex; std::mutex event_counter_mutex; - bool availability { false }; + bool availability {false}; - int event_1_recv_messages { 0 }; - int event_2_recv_messages { 0 }; + int event_1_recv_messages {0}; + int event_2_recv_messages {0}; void on_availability(vsomeip::service_t service_, vsomeip::instance_t instance_, bool _is_available); - void on_message(const std::shared_ptr &_message); + void on_message(const std::shared_ptr& _message); void stop_service(); void unsubscribe_all(); public: - test_client(const char *app_name_, const char *app_id_); + test_client(const char* app_name_, const char* app_id_); int was_event1_recv(); int was_event2_recv(); diff --git a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.cpp b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.cpp index 202901390..587778b77 100644 --- a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.cpp +++ b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.cpp @@ -6,42 +6,40 @@ #include #include "debounce_frequency_test_service.hpp" -uint64_t elapsedMilliseconds(const std::chrono::time_point &_start_time) -{ +uint64_t +elapsedMilliseconds(const std::chrono::time_point& _start_time) { return std::chrono::duration_cast(std::chrono::system_clock::now() - - _start_time).count(); + - _start_time) + .count(); } -void test_service::on_start(const std::shared_ptr /*&_message*/) -{ +void test_service::on_start(const std::shared_ptr /*&_message*/) { std::unique_lock lk(mutex); received_message = true; condition_wait_start.notify_one(); } -void test_service::on_stop(const std::shared_ptr /*&_message*/) -{ +void test_service::on_stop(const std::shared_ptr /*&_message*/) { VSOMEIP_INFO << "service: " << __func__ << ": Received a STOP command."; } -test_service::test_service(const char *app_name_, const char *app_id_) : vsomeip_utilities::base_vsip_app(app_name_,app_id_) -{ +test_service::test_service(const char* app_name_, const char* app_id_) : + vsomeip_utilities::base_vsip_app(app_name_, app_id_) { _app->register_message_handler(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_START_METHOD, - std::bind(&test_service::on_start, this, std::placeholders::_1)); + std::bind(&test_service::on_start, this, std::placeholders::_1)); _app->register_message_handler(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, - std::bind(&test_service::on_stop, this, std::placeholders::_1)); - _app->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), false, - true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - _app->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), false, - true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + std::bind(&test_service::on_stop, this, std::placeholders::_1)); + _app->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, {DEBOUNCE_EVENTGROUP}, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), false, + true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + _app->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, {DEBOUNCE_EVENTGROUP}, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), false, + true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); _app->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); } // Send the debounce events with different frequencies, but configured with the same debounce time -void test_service::send_messages() -{ +void test_service::send_messages() { std::unique_lock lk(mutex); if (condition_wait_start.wait_for(lk, std::chrono::milliseconds(2000), [=] { return received_message; })) { @@ -53,7 +51,7 @@ void test_service::send_messages() if (elapsedMilliseconds(start_time) % 30 == 0) { auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, i++ }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, i++}); _app->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); event_1_sent_messages = true; @@ -61,7 +59,7 @@ void test_service::send_messages() if (elapsedMilliseconds(start_time) % 2 == 0) { auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, i++ }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, i++}); _app->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); event_2_sent_messages = true; } @@ -71,18 +69,15 @@ void test_service::send_messages() } } -bool test_service::was_event_1_sent() -{ +bool test_service::was_event_1_sent() { return event_1_sent_messages; } -bool test_service::was_event_2_sent() -{ +bool test_service::was_event_2_sent() { return event_2_sent_messages; } -TEST(debounce_frequency_test, server) -{ +TEST(debounce_frequency_test, server) { test_service debounce_server("debounce_frequency_test_service", "DFTS"); debounce_server.send_messages(); @@ -90,8 +85,7 @@ TEST(debounce_frequency_test, server) EXPECT_TRUE(debounce_server.was_event_2_sent()) << "Event 2 was not sent by the service"; } -int main(int argc, char **argv) -{ +int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.hpp b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.hpp index 78939f341..6efc44b69 100644 --- a/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.hpp +++ b/test/network_tests/debounce_frequency_tests/debounce_frequency_test_service.hpp @@ -18,21 +18,20 @@ #include "debounce_frequency_test_common.hpp" #include -class test_service : public vsomeip_utilities::base_vsip_app -{ +class test_service : public vsomeip_utilities::base_vsip_app { private: std::condition_variable condition_wait_start; std::mutex mutex; - bool received_message { false }; + bool received_message {false}; std::chrono::time_point start_time; - bool event_1_sent_messages { false }; - bool event_2_sent_messages { false }; + bool event_1_sent_messages {false}; + bool event_2_sent_messages {false}; void on_start(const std::shared_ptr /*&_message*/); void on_stop(const std::shared_ptr /*&_message*/); public: - test_service(const char *app_name_, const char *app_id_); + test_service(const char* app_name_, const char* app_id_); void send_messages(); bool was_event_1_sent(); diff --git a/test/network_tests/debounce_tests/CMakeLists.txt b/test/network_tests/debounce_tests/CMakeLists.txt new file mode 100644 index 000000000..1e314352e --- /dev/null +++ b/test/network_tests/debounce_tests/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(debounce_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + debounce_test_client.json + debounce_test_master_starter.sh + debounce_test_service.json + debounce_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(debounce_test_client + debounce_test_client.cpp +) + +# Add test executable. +add_executable(debounce_test_service + debounce_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + debounce_test_client + debounce_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME debounce_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/debounce_test_master_starter.sh + TIMEOUT 60 +) diff --git a/test/network_tests/debounce_tests/conf/debounce_test_client.json.in b/test/network_tests/debounce_tests/conf/debounce_test_client.json.in index e81836e7a..77884e07c 100644 --- a/test/network_tests/debounce_tests/conf/debounce_test_client.json.in +++ b/test/network_tests/debounce_tests/conf/debounce_test_client.json.in @@ -1,5 +1,14 @@ { "unicast" : "@TEST_IP_MASTER@", + "logging": { + "level": "info", + "console": "true", + "file": { + "enable": "false", + "path": "/tmp/foo.log" + }, + "dlt": "true" + }, "debounce" : [ { diff --git a/test/network_tests/debounce_tests/debounce_test_master_starter.sh b/test/network_tests/debounce_tests/conf/debounce_test_master_starter.sh.in similarity index 92% rename from test/network_tests/debounce_tests/debounce_test_master_starter.sh rename to test/network_tests/debounce_tests/conf/debounce_test_master_starter.sh.in index 534c2ff06..749e131c6 100755 --- a/test/network_tests/debounce_tests/debounce_test_master_starter.sh +++ b/test/network_tests/debounce_tests/conf/debounce_test_master_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_test_client.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 @@ -19,7 +19,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting debounce test on slave LXC debounce_test_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./debounce_test_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/debounce_tests; ./debounce_test_slave_starter.sh\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./debounce_test_slave_starter.sh" & else diff --git a/test/network_tests/debounce_tests/conf/debounce_test_service.json.in b/test/network_tests/debounce_tests/conf/debounce_test_service.json.in index 29efa708c..78b939cf7 100644 --- a/test/network_tests/debounce_tests/conf/debounce_test_service.json.in +++ b/test/network_tests/debounce_tests/conf/debounce_test_service.json.in @@ -1,5 +1,14 @@ { "unicast" : "@TEST_IP_SLAVE@", + "logging": { + "level": "info", + "console": "true", + "file": { + "enable": "false", + "path": "/tmp/foo.log" + }, + "dlt": "true" + }, "services" : [ { diff --git a/test/network_tests/debounce_tests/debounce_test_slave_starter.sh b/test/network_tests/debounce_tests/conf/debounce_test_slave_starter.sh.in similarity index 93% rename from test/network_tests/debounce_tests/debounce_test_slave_starter.sh rename to test/network_tests/debounce_tests/conf/debounce_test_slave_starter.sh.in index ce5b230f6..89b598243 100755 --- a/test/network_tests/debounce_tests/debounce_test_slave_starter.sh +++ b/test/network_tests/debounce_tests/conf/debounce_test_slave_starter.sh.in @@ -7,7 +7,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=debounce_test_service.json -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 diff --git a/test/network_tests/debounce_tests/debounce_test_client.cpp b/test/network_tests/debounce_tests/debounce_test_client.cpp index 5927300c4..7ad2b6067 100644 --- a/test/network_tests/debounce_tests/debounce_test_client.cpp +++ b/test/network_tests/debounce_tests/debounce_test_client.cpp @@ -10,80 +10,67 @@ #include "debounce_test_client.hpp" -static std::vector > > payloads__; +static std::vector>> payloads__; +debounce_test_client::debounce_test_client(debounce_test_id_e _test_id) : + test_id_(_test_id), index_(0), is_available_(false), + runner_(std::bind(&debounce_test_client::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_client")) { } -debounce_test_client::debounce_test_client(debounce_test_id_e _test_id) - : test_id_(_test_id), - index_(0), - is_available_(false), - runner_(std::bind(&debounce_test_client::run, this)), - app_(vsomeip::runtime::get()->create_application("debounce_test_client")) { -} - -bool -debounce_test_client::init() { +bool debounce_test_client::init() { bool its_result = app_->init(); if (its_result) { - app_->register_availability_handler( - DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - std::bind(&debounce_test_client::on_availability, this, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3), - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->register_availability_handler(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + std::bind(&debounce_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); app_->register_message_handler( DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, - std::bind(&debounce_test_client::on_message, this, - std::placeholders::_1)); - app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT_4, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); - app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT); - app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT_2); - app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT_4); + std::bind(&debounce_test_client::on_message, this, std::placeholders::_1)); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, + DEBOUNCE_EVENT); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, + DEBOUNCE_EVENT_2); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, + DEBOUNCE_EVENT_4); } return its_result; } -void -debounce_test_client::start() { +void debounce_test_client::start() { + VSOMEIP_INFO << "Starting Client..."; app_->start(); } -void -debounce_test_client::stop() { +void debounce_test_client::stop() { + VSOMEIP_INFO << "Stopping Client..."; app_->stop(); } -void -debounce_test_client::run() { +void debounce_test_client::run() { { std::unique_lock its_lock(run_mutex_); while (!is_available_) { - auto its_status - = run_condition_.wait_for(its_lock, std::chrono::milliseconds(15000)); + auto its_status = run_condition_.wait_for(its_lock, std::chrono::milliseconds(15000)); EXPECT_EQ(its_status, std::cv_status::no_timeout); if (its_status == std::cv_status::timeout) { - VSOMEIP_ERROR << __func__ << ": Debounce service did not become available after 15s."; + VSOMEIP_ERROR << __func__ + << ": Debounce service did not become available after 15s."; stop(); return; } @@ -103,20 +90,16 @@ debounce_test_client::run() { stop(); } -void -debounce_test_client::wait() { +void debounce_test_client::wait() { if (runner_.joinable()) runner_.join(); } -void -debounce_test_client::on_availability( - vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available) { +void debounce_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { - if (_service == DEBOUNCE_SERVICE - && _instance == DEBOUNCE_INSTANCE) { + if (_service == DEBOUNCE_SERVICE && _instance == DEBOUNCE_INSTANCE) { if (_is_available) { VSOMEIP_ERROR << __func__ << ": Debounce service becomes available."; @@ -134,19 +117,17 @@ debounce_test_client::on_availability( } } -void -debounce_test_client::on_message( - const std::shared_ptr &_message) { +void debounce_test_client::on_message(const std::shared_ptr& _message) { std::stringstream s; s << "RECV: "; - for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) + for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) { s << std::hex << std::setw(2) << std::setfill('0') - << (int)_message->get_payload()->get_data()[i] << " "; + << static_cast(_message->get_payload()->get_data()[i]) << " "; + } VSOMEIP_DEBUG << s.str(); - if (DEBOUNCE_SERVICE == _message->get_service() - && DEBOUNCE_EVENT == _message->get_method()) { + if (DEBOUNCE_SERVICE == _message->get_service() && DEBOUNCE_EVENT == _message->get_method()) { if (test_id_ == debounce_test_id_e::DTI_FLAT) { bool is_equal = compare_payload(_message->get_payload(), index_++); @@ -158,11 +139,10 @@ debounce_test_client::on_message( return; } - if (DEBOUNCE_SERVICE == _message->get_service() - && DEBOUNCE_EVENT_2 == _message->get_method()) { + if (DEBOUNCE_SERVICE == _message->get_service() && DEBOUNCE_EVENT_2 == _message->get_method()) { if (test_id_ == debounce_test_id_e::DTI_INCREASE - || test_id_ == debounce_test_id_e::DTI_DECREASE) { + || test_id_ == debounce_test_id_e::DTI_DECREASE) { bool is_equal = compare_payload(_message->get_payload(), index_++); EXPECT_EQ(is_equal, true); @@ -173,8 +153,7 @@ debounce_test_client::on_message( return; } - if (DEBOUNCE_SERVICE == _message->get_service() - && DEBOUNCE_EVENT_4 == _message->get_method()) { + if (DEBOUNCE_SERVICE == _message->get_service() && DEBOUNCE_EVENT_4 == _message->get_method()) { if (test_id_ == debounce_test_id_e::DTI_MASK) { bool is_equal = compare_payload(_message->get_payload(), index_++); @@ -188,17 +167,14 @@ debounce_test_client::on_message( } } -bool -debounce_test_client::compare_payload( - const std::shared_ptr &_payload, - std::size_t _index) const { +bool debounce_test_client::compare_payload(const std::shared_ptr& _payload, + std::size_t _index) const { auto its_expected_payload = payloads__[test_id_][_index]; return (*_payload == *its_expected_payload); } -void -debounce_test_client::run_test() { +void debounce_test_client::run_test() { // Trigger the test auto its_runtime = vsomeip::runtime::get(); @@ -215,8 +191,7 @@ debounce_test_client::run_test() { // Wait for the result std::unique_lock its_lock(run_mutex_); if (!is_available_) { - auto its_result = run_condition_.wait_for( - its_lock, std::chrono::milliseconds(5000)); + auto its_result = run_condition_.wait_for(its_lock, std::chrono::milliseconds(5000)); EXPECT_EQ(its_result, std::cv_status::no_timeout); } @@ -224,15 +199,12 @@ debounce_test_client::run_test() { std::this_thread::sleep_for(std::chrono::seconds(2)); } -void -debounce_test_client::unsubscribe_all() { +void debounce_test_client::unsubscribe_all() { - app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENTGROUP); + app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENTGROUP); } -void -debounce_test_client::stop_service() { +void debounce_test_client::stop_service() { auto its_runtime = vsomeip::runtime::get(); auto its_payload = its_runtime->create_payload(); @@ -246,49 +218,36 @@ debounce_test_client::stop_service() { app_->send(its_message); } - TEST(debounce_test, flat) { debounce_test_client its_client(debounce_test_id_e::DTI_FLAT); - if (its_client.init()) { - VSOMEIP_ERROR << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - } else { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + ASSERT_TRUE(its_client.init()); + VSOMEIP_ERROR << "Debounce Client successfully initialized!"; + its_client.start(); + its_client.wait(); } TEST(debounce_test, increase) { debounce_test_client its_client(debounce_test_id_e::DTI_INCREASE); - if (its_client.init()) { - VSOMEIP_ERROR << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - } else { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + ASSERT_TRUE(its_client.init()); + VSOMEIP_ERROR << "Debounce Client successfully initialized!"; + its_client.start(); + its_client.wait(); } TEST(debounce_test, decrease) { debounce_test_client its_client(debounce_test_id_e::DTI_DECREASE); - if (its_client.init()) { - VSOMEIP_ERROR << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - } else { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + ASSERT_TRUE(its_client.init()); + VSOMEIP_ERROR << "Debounce Client successfully initialized!"; + its_client.start(); + its_client.wait(); } TEST(debounce_test, mask) { debounce_test_client its_client(debounce_test_id_e::DTI_MASK); - if (its_client.init()) { - VSOMEIP_ERROR << "debounce_client successfully initialized!"; - its_client.start(); - its_client.wait(); - } else { - VSOMEIP_ERROR << "debounce_client could not be initialized!"; - } + ASSERT_TRUE(its_client.init()); + VSOMEIP_ERROR << "Debounce Client successfully initialized!"; + its_client.start(); + its_client.wait(); } int main(int argc, char** argv) { @@ -296,107 +255,107 @@ int main(int argc, char** argv) { std::shared_ptr its_payload; // Flat test - payloads__.push_back(std::vector >()); + payloads__.push_back(std::vector>()); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07 }); + its_payload->set_data({0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07 }); + its_payload->set_data({0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07 }); + its_payload->set_data({0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07 }); + its_payload->set_data({0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); // Increase test - payloads__.push_back(std::vector >()); + payloads__.push_back(std::vector>()); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08 }); + its_payload->set_data({0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08}); payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09 }); + its_payload->set_data({0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09}); payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A }); + its_payload->set_data({0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A}); payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + its_payload->set_data({0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}); payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + its_payload->set_data({0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}); payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); // Decrease test - payloads__.push_back(std::vector >()); + payloads__.push_back(std::vector>()); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}); payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + its_payload->set_data({0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B}); payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + its_payload->set_data({0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}); payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A }); + its_payload->set_data({0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A}); payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09 }); + its_payload->set_data({0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09}); payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08 }); + its_payload->set_data({0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08}); payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); - // Mask test - payloads__.push_back(std::vector >()); + // Mask test + payloads__.push_back(std::vector>()); - its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); - payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + its_payload->set_data({0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07}); payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + its_payload->set_data({0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07}); payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/network_tests/debounce_tests/debounce_test_client.hpp b/test/network_tests/debounce_tests/debounce_test_client.hpp index 0480ea3ca..14d127588 100644 --- a/test/network_tests/debounce_tests/debounce_test_client.hpp +++ b/test/network_tests/debounce_tests/debounce_test_client.hpp @@ -28,17 +28,16 @@ class debounce_test_client { void wait(); private: - void on_availability( - vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available); - void on_message(const std::shared_ptr &_message); + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available); + void on_message(const std::shared_ptr& _message); void run_test(); void unsubscribe_all(); void stop_service(); - bool compare_payload(const std::shared_ptr &_payload, - std::size_t _index) const; + bool compare_payload(const std::shared_ptr& _payload, + std::size_t _index) const; private: debounce_test_id_e test_id_; diff --git a/test/network_tests/debounce_tests/debounce_test_service.cpp b/test/network_tests/debounce_tests/debounce_test_service.cpp index 58f68d370..f9c2f4a3c 100644 --- a/test/network_tests/debounce_tests/debounce_test_service.cpp +++ b/test/network_tests/debounce_tests/debounce_test_service.cpp @@ -7,87 +7,69 @@ #include "debounce_test_service.hpp" -debounce_test_service::debounce_test_service(debounce_test_id_e _test_id) - : test_id_(_test_id), - is_running_(true), - runner_(std::bind(&debounce_test_service::run, this)), - app_(vsomeip::runtime::get()->create_application("debounce_test_service")) { +debounce_test_service::debounce_test_service(debounce_test_id_e _test_id) : + test_id_(_test_id), is_running_(true), runner_(std::bind(&debounce_test_service::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_service")) { } -} - -bool -debounce_test_service::init() { +bool debounce_test_service::init() { bool is_initialized = app_->init(); if (is_initialized) { app_->register_message_handler( DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_START_METHOD, - std::bind(&debounce_test_service::on_start, this, - std::placeholders::_1)); + std::bind(&debounce_test_service::on_start, this, std::placeholders::_1)); app_->register_message_handler( DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, - std::bind(&debounce_test_service::on_stop, this, - std::placeholders::_1)); - app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_EVENT_4, { DEBOUNCE_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, - DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + std::bind(&debounce_test_service::on_stop, this, std::placeholders::_1)); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, + {DEBOUNCE_EVENTGROUP}, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_MAJOR, DEBOUNCE_MINOR); } return is_initialized; } -void -debounce_test_service::start() { +void debounce_test_service::start() { + VSOMEIP_INFO << "Starting Service..."; app_->start(); } -void -debounce_test_service::stop() { +void debounce_test_service::stop() { + VSOMEIP_INFO << "Stopping Service..."; app_->stop(); } -void -debounce_test_service::run() { +void debounce_test_service::run() { { std::unique_lock its_lock(run_mutex_); - auto its_result = run_condition_.wait_for( - its_lock, std::chrono::milliseconds(5000)); + auto its_result = run_condition_.wait_for(its_lock, std::chrono::milliseconds(5000)); if (its_result == std::cv_status::timeout) return; } + std::this_thread::sleep_for(std::chrono::milliseconds(500)); start_test(); } -void -debounce_test_service::wait() { +void debounce_test_service::wait() { if (runner_.joinable()) runner_.join(); } -void -debounce_test_service::on_start( - const std::shared_ptr &_message) { +void debounce_test_service::on_start(const std::shared_ptr& _message) { (void)_message; @@ -95,10 +77,7 @@ debounce_test_service::on_start( run_condition_.notify_one(); } - -void -debounce_test_service::on_stop( - const std::shared_ptr &_message) { +void debounce_test_service::on_stop(const std::shared_ptr& _message) { (void)_message; @@ -107,180 +86,177 @@ debounce_test_service::on_stop( stop(); } -void -debounce_test_service::start_test() { +void debounce_test_service::start_test() { if (test_id_ == debounce_test_id_e::DTI_FLAT) { auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + its_payload->set_data({0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07 }); + its_payload->set_data({0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07 }); + its_payload->set_data({0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07 }); + its_payload->set_data({0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07 }); + its_payload->set_data({0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07 }); + its_payload->set_data({0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07 }); + its_payload->set_data({0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07 }); + its_payload->set_data({0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); - its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07 }); + its_payload->set_data({0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); } if (test_id_ == debounce_test_id_e::DTI_INCREASE) { auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08 }); + its_payload->set_data({0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08 }); + its_payload->set_data({0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09 }); + its_payload->set_data({0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09 }); + its_payload->set_data({0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09, 0x0A }); + its_payload->set_data({0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09, 0x0A}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A }); + its_payload->set_data({0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + its_payload->set_data({0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + its_payload->set_data({0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + its_payload->set_data( + {0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); } if (test_id_ == debounce_test_id_e::DTI_DECREASE) { auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + its_payload->set_data( + {0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + its_payload->set_data({0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + its_payload->set_data({0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09, 0x0A }); + its_payload->set_data({0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09, 0x0A}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A }); + its_payload->set_data({0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09 }); + its_payload->set_data({0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09 }); + its_payload->set_data({0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08 }); + its_payload->set_data({0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08 }); + its_payload->set_data({0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); - its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07 }); + its_payload->set_data({0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); } if (test_id_ == debounce_test_id_e::DTI_MASK) { auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x12, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x12, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x21, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x21, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + its_payload->set_data({0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + its_payload->set_data({0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + its_payload->set_data({0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); - its_payload->set_data({ 0x25, 0x02, 0x03, 0x04, 0x05, 0x17, 0x07 }); + its_payload->set_data({0x25, 0x02, 0x03, 0x04, 0x05, 0x17, 0x07}); app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); } } TEST(debounce_test, flat) { debounce_test_service its_service(debounce_test_id_e::DTI_FLAT); - if (its_service.init()) { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } TEST(debounce_test, increase) { debounce_test_service its_service(debounce_test_id_e::DTI_INCREASE); - if (its_service.init()) { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } TEST(debounce_test, decrease) { debounce_test_service its_service(debounce_test_id_e::DTI_DECREASE); - if (its_service.init()) { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } TEST(debounce_test, mask) { debounce_test_service its_service(debounce_test_id_e::DTI_MASK); - if (its_service.init()) { - its_service.start(); - its_service.wait(); - } + ASSERT_TRUE(its_service.init()); + its_service.start(); + its_service.wait(); } int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/test/network_tests/debounce_tests/debounce_test_service.hpp b/test/network_tests/debounce_tests/debounce_test_service.hpp index 0271ae18c..570e403bf 100644 --- a/test/network_tests/debounce_tests/debounce_test_service.hpp +++ b/test/network_tests/debounce_tests/debounce_test_service.hpp @@ -29,8 +29,8 @@ class debounce_test_service { void wait(); private: - void on_start(const std::shared_ptr &_message); - void on_stop(const std::shared_ptr &_message); + void on_start(const std::shared_ptr& _message); + void on_stop(const std::shared_ptr& _message); void start_test(); @@ -44,5 +44,4 @@ class debounce_test_service { std::shared_ptr app_; }; - #endif // DEBOUNCE_TEST_SERVICE_HPP_ diff --git a/test/network_tests/e2e_tests/CMakeLists.txt b/test/network_tests/e2e_tests/CMakeLists.txt new file mode 100644 index 000000000..56fdc23bf --- /dev/null +++ b/test/network_tests/e2e_tests/CMakeLists.txt @@ -0,0 +1,118 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(e2e_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + e2e_test_client_external.json + e2e_test_external_master_start.sh + e2e_test_external_slave_start.sh + e2e_test_service_external.json +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(e2e_test_client + e2e_test_client.cpp +) + +# Add test executable. +add_executable(e2e_test_service + e2e_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + e2e_test_client + e2e_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME e2e_test_external + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/e2e_test_external_master_start.sh e2e_test_client_external.json + TIMEOUT 180 +) + +if(TEST_E2E_PROFILE_04) + + # Configure necessary files into the build directory. + set(configuration_files + e2e_profile_04_test_client_external.json + e2e_profile_04_test_external_master_start.sh + e2e_profile_04_test_external_slave_start.sh + e2e_profile_04_test_service_external.json + ) + configure_files("${configuration_files}") + + # Add test executable. + add_executable(e2e_profile_04_test_client + e2e_profile_04_test_client.cpp + ) + + # Add test executable. + add_executable(e2e_profile_04_test_service + e2e_profile_04_test_service.cpp + ) + + # Add build dependencies and link libraries to executables. + set(executables + e2e_profile_04_test_client + e2e_profile_04_test_service + ) + targets_link_default_libraries("${executables}") + targets_add_default_dependencies("${executables}") + + # Add custom test command. + add_custom_test( + NAME e2e_profile_04_test_external + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/e2e_profile_04_test_external_master_start.sh e2e_profile_04_test_client_external.json + TIMEOUT 180 + ) + +endif() + +if(TEST_E2E_PROFILE_07) + + # Configure necessary files into the build directory. + set(configuration_files + e2e_profile_07_test_client_external.json + e2e_profile_07_test_external_master_start.sh + e2e_profile_07_test_external_slave_start.sh + e2e_profile_07_test_service_external.json + ) + configure_files("${configuration_files}") + + # Add test executable. + add_executable(e2e_profile_07_test_client + e2e_profile_07_test_client.cpp + ) + + # Add test executable. + add_executable(e2e_profile_07_test_service + e2e_profile_07_test_service.cpp + ) + + # Add build dependencies and link libraries to executables. + set(executables + e2e_profile_07_test_client + e2e_profile_07_test_service + ) + targets_link_default_libraries("${executables}") + targets_add_default_dependencies("${executables}") + + # Add custom test command. + add_custom_test( + NAME e2e_profile_07_test_external + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/e2e_profile_07_test_external_master_start.sh e2e_profile_07_test_client_external.json + TIMEOUT 180 + ) + +endif() diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_external_master_start.sh.in similarity index 95% rename from test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh rename to test/network_tests/e2e_tests/conf/e2e_profile_04_test_external_master_start.sh.in index df2095b9b..fcbfab104 100755 --- a/test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh +++ b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_external_master_start.sh.in @@ -31,7 +31,7 @@ PID_CLIENT=$! if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external e2e profile 04 test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_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/network_tests/e2e_tests; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE" & else diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_external_slave_start.sh b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_external_slave_start.sh.in similarity index 100% rename from test/network_tests/e2e_tests/e2e_profile_04_test_external_slave_start.sh rename to test/network_tests/e2e_tests/conf/e2e_profile_04_test_external_slave_start.sh.in diff --git a/test/network_tests/e2e_tests/e2e_profile_07_test_external_master_start.sh b/test/network_tests/e2e_tests/conf/e2e_profile_07_test_external_master_start.sh.in similarity index 95% rename from test/network_tests/e2e_tests/e2e_profile_07_test_external_master_start.sh rename to test/network_tests/e2e_tests/conf/e2e_profile_07_test_external_master_start.sh.in index 5b07bd0d1..d6455c1ea 100755 --- a/test/network_tests/e2e_tests/e2e_profile_07_test_external_master_start.sh +++ b/test/network_tests/e2e_tests/conf/e2e_profile_07_test_external_master_start.sh.in @@ -31,7 +31,7 @@ PID_CLIENT=$! if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external e2e profile 07 test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./e2e_profile_07_test_external_slave_start.sh $SERVICE_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/network_tests/e2e_tests; ./e2e_profile_07_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_profile_07_test_external_slave_start.sh $SERVICE_JSON_FILE" & else diff --git a/test/network_tests/e2e_tests/e2e_profile_07_test_external_slave_start.sh b/test/network_tests/e2e_tests/conf/e2e_profile_07_test_external_slave_start.sh.in similarity index 100% rename from test/network_tests/e2e_tests/e2e_profile_07_test_external_slave_start.sh rename to test/network_tests/e2e_tests/conf/e2e_profile_07_test_external_slave_start.sh.in diff --git a/test/network_tests/e2e_tests/e2e_test_external_master_start.sh b/test/network_tests/e2e_tests/conf/e2e_test_external_master_start.sh.in similarity index 96% rename from test/network_tests/e2e_tests/e2e_test_external_master_start.sh rename to test/network_tests/e2e_tests/conf/e2e_test_external_master_start.sh.in index 16836c710..5b4863b70 100755 --- a/test/network_tests/e2e_tests/e2e_test_external_master_start.sh +++ b/test/network_tests/e2e_tests/conf/e2e_test_external_master_start.sh.in @@ -31,7 +31,7 @@ PID_CLIENT=$! if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external e2e test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./e2e_test_external_slave_start.sh $SERVICE_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/network_tests/e2e_tests; ./e2e_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_test_external_slave_start.sh $SERVICE_JSON_FILE" & else diff --git a/test/network_tests/e2e_tests/e2e_test_external_slave_start.sh b/test/network_tests/e2e_tests/conf/e2e_test_external_slave_start.sh.in similarity index 100% rename from test/network_tests/e2e_tests/e2e_test_external_slave_start.sh rename to test/network_tests/e2e_tests/conf/e2e_test_external_slave_start.sh.in diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp b/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp index 266865682..f97f038ab 100644 --- a/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp @@ -3,6 +3,8 @@ // 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 "e2e_profile_04_test_common.hpp" #include "e2e_profile_04_test_client.hpp" diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_service.cpp b/test/network_tests/e2e_tests/e2e_profile_04_test_service.cpp index efd48c906..acf34779b 100644 --- a/test/network_tests/e2e_tests/e2e_profile_04_test_service.cpp +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_service.cpp @@ -3,6 +3,8 @@ // 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 "e2e_profile_04_test_common.hpp" #include "e2e_profile_04_test_service.hpp" diff --git a/test/network_tests/e2e_tests/e2e_profile_07_test_client.cpp b/test/network_tests/e2e_tests/e2e_profile_07_test_client.cpp index 606ef9968..58faa3ec6 100644 --- a/test/network_tests/e2e_tests/e2e_profile_07_test_client.cpp +++ b/test/network_tests/e2e_tests/e2e_profile_07_test_client.cpp @@ -3,6 +3,8 @@ // 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 "e2e_profile_07_test_common.hpp" #include "e2e_profile_07_test_client.hpp" diff --git a/test/network_tests/e2e_tests/e2e_profile_07_test_service.cpp b/test/network_tests/e2e_tests/e2e_profile_07_test_service.cpp index 5426209f5..5e2a09293 100644 --- a/test/network_tests/e2e_tests/e2e_profile_07_test_service.cpp +++ b/test/network_tests/e2e_tests/e2e_profile_07_test_service.cpp @@ -3,6 +3,8 @@ // 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 "e2e_profile_07_test_common.hpp" #include "e2e_profile_07_test_service.hpp" diff --git a/test/network_tests/e2e_tests/e2e_test_client.cpp b/test/network_tests/e2e_tests/e2e_test_client.cpp index 260ad7e13..9e270cca2 100644 --- a/test/network_tests/e2e_tests/e2e_test_client.cpp +++ b/test/network_tests/e2e_tests/e2e_test_client.cpp @@ -3,6 +3,8 @@ // 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 "e2e_test_client.hpp" static bool is_remote_test = false; diff --git a/test/network_tests/e2e_tests/e2e_test_service.cpp b/test/network_tests/e2e_tests/e2e_test_service.cpp index 46e57ae4e..164716700 100644 --- a/test/network_tests/e2e_tests/e2e_test_service.cpp +++ b/test/network_tests/e2e_tests/e2e_test_service.cpp @@ -3,6 +3,8 @@ // 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 "e2e_test_service.hpp" static bool is_remote_test = false; diff --git a/test/network_tests/event_tests/CMakeLists.txt b/test/network_tests/event_tests/CMakeLists.txt new file mode 100644 index 000000000..54bde4d61 --- /dev/null +++ b/test/network_tests/event_tests/CMakeLists.txt @@ -0,0 +1,64 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(event_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + event_test_master.json + event_test_master_starter.sh + event_test_slave_starter.sh + event_test_slave_tcp.json + event_test_slave_udp.json +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(event_test_client + event_test_client.cpp +) + +# Add test executable. +add_executable(event_test_service + event_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + event_test_client + event_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME event_test_payload_fixed_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/event_test_master_starter.sh PAYLOAD_FIXED UDP + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME event_test_payload_fixed_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/event_test_master_starter.sh PAYLOAD_FIXED TCP + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME event_test_payload_dynamic_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/event_test_master_starter.sh PAYLOAD_DYNAMIC UDP + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME event_test_payload_dynamic_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/event_test_master_starter.sh PAYLOAD_DYNAMIC TCP + TIMEOUT 180 +) diff --git a/test/network_tests/event_tests/event_test_master_starter.sh b/test/network_tests/event_tests/conf/event_test_master_starter.sh.in similarity index 93% rename from test/network_tests/event_tests/event_test_master_starter.sh rename to test/network_tests/event_tests/conf/event_test_master_starter.sh.in index 61dc9bcc4..74a25ae87 100755 --- a/test/network_tests/event_tests/event_test_master_starter.sh +++ b/test/network_tests/event_tests/conf/event_test_master_starter.sh.in @@ -18,7 +18,7 @@ TESTMODE=$1 COMMUNICATIONMODE=$2 export VSOMEIP_CONFIGURATION=event_test_master.json -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! ./event_test_client $TESTMODE $COMMUNICATIONMODE & @@ -28,7 +28,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./event_test_slave_starter.sh $COMMUNICATIONMODE\"" & + 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/network_tests/event_tests; ./event_test_slave_starter.sh $COMMUNICATIONMODE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./event_test_slave_starter.sh $COMMUNICATIONMODE" & else diff --git a/test/network_tests/event_tests/event_test_slave_starter.sh b/test/network_tests/event_tests/conf/event_test_slave_starter.sh.in similarity index 95% rename from test/network_tests/event_tests/event_test_slave_starter.sh rename to test/network_tests/event_tests/conf/event_test_slave_starter.sh.in index 65e92b3e4..a7871dbda 100755 --- a/test/network_tests/event_tests/event_test_slave_starter.sh +++ b/test/network_tests/event_tests/conf/event_test_slave_starter.sh.in @@ -21,7 +21,7 @@ elif [ "$COMMUNICATIONMODE" = "UDP" ]; then export VSOMEIP_CONFIGURATION=event_test_slave_udp.json fi -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! ./event_test_service $COMMUNICATIONMODE & diff --git a/test/network_tests/event_tests/event_test_service.cpp b/test/network_tests/event_tests/event_test_service.cpp index 3728a8276..5f7099ffb 100644 --- a/test/network_tests/event_tests/event_test_service.cpp +++ b/test/network_tests/event_tests/event_test_service.cpp @@ -3,13 +3,14 @@ // 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 diff --git a/test/network_tests/header_factory_tests/CMakeLists.txt b/test/network_tests/header_factory_tests/CMakeLists.txt new file mode 100644 index 000000000..ac81f1ae9 --- /dev/null +++ b/test/network_tests/header_factory_tests/CMakeLists.txt @@ -0,0 +1,61 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(header_factory_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + header_factory_test_client.json + header_factory_test_client_start.sh + header_factory_test_send_receive_starter.sh + header_factory_test_service.json + header_factory_test_service_start.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(header_factory_test + header_factory_test.cpp +) + +# Add test executable. +add_executable(header_factory_test_client + header_factory_test_client.cpp +) + +# Add test executable. +add_executable(header_factory_test_service + header_factory_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + header_factory_test + header_factory_test_client + header_factory_test_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Link thread libraries to executables. +foreach(target ${executables}) + target_link_libraries(${target} + ${CMAKE_THREAD_LIBS_INIT} + ) +endforeach() + +# Add custom test command. +add_custom_test( + NAME header_factory_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/header_factory_test +) + +# Add custom test command. +add_custom_test( + NAME header_factory_test_send_receive + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/header_factory_test_send_receive_starter.sh +) diff --git a/test/network_tests/header_factory_tests/header_factory_test_client.json b/test/network_tests/header_factory_tests/conf/header_factory_test_client.json.in similarity index 100% rename from test/network_tests/header_factory_tests/header_factory_test_client.json rename to test/network_tests/header_factory_tests/conf/header_factory_test_client.json.in diff --git a/test/network_tests/header_factory_tests/header_factory_test_client_start.sh b/test/network_tests/header_factory_tests/conf/header_factory_test_client_start.sh.in similarity index 100% rename from test/network_tests/header_factory_tests/header_factory_test_client_start.sh rename to test/network_tests/header_factory_tests/conf/header_factory_test_client_start.sh.in diff --git a/test/network_tests/header_factory_tests/conf/header_factory_test_send_receive_starter.sh.bat.in b/test/network_tests/header_factory_tests/conf/header_factory_test_send_receive_starter.sh.in similarity index 100% rename from test/network_tests/header_factory_tests/conf/header_factory_test_send_receive_starter.sh.bat.in rename to test/network_tests/header_factory_tests/conf/header_factory_test_send_receive_starter.sh.in diff --git a/test/network_tests/header_factory_tests/header_factory_test_service.json b/test/network_tests/header_factory_tests/conf/header_factory_test_service.json.in similarity index 100% rename from test/network_tests/header_factory_tests/header_factory_test_service.json rename to test/network_tests/header_factory_tests/conf/header_factory_test_service.json.in diff --git a/test/network_tests/header_factory_tests/header_factory_test_service_start.sh b/test/network_tests/header_factory_tests/conf/header_factory_test_service_start.sh.in similarity index 100% rename from test/network_tests/header_factory_tests/header_factory_test_service_start.sh rename to test/network_tests/header_factory_tests/conf/header_factory_test_service_start.sh.in diff --git a/test/network_tests/header_factory_tests/header_factory_test_client.cpp b/test/network_tests/header_factory_tests/header_factory_test_client.cpp index 13b1111ed..59395ee66 100644 --- a/test/network_tests/header_factory_tests/header_factory_test_client.cpp +++ b/test/network_tests/header_factory_tests/header_factory_test_client.cpp @@ -3,6 +3,8 @@ // 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 "header_factory_test_client.hpp" header_factory_test_client::header_factory_test_client(bool _use_tcp) : diff --git a/test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh b/test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh deleted file mode 100755 index 5d1d780fb..000000000 --- a/test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-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/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -# Start the service -export VSOMEIP_APPLICATION_NAME=header_factory_test_service -export VSOMEIP_CONFIGURATION=header_factory_test_service.json -./header_factory_test_service & -sleep 1; - -# Start the client -export VSOMEIP_APPLICATION_NAME=header_factory_test_client -export VSOMEIP_CONFIGURATION=header_factory_test_client.json -./header_factory_test_client & - -# Wait until client and service are finished -FAIL=0 -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/header_factory_tests/header_factory_test_service.cpp b/test/network_tests/header_factory_tests/header_factory_test_service.cpp index d647fd9b3..8f7255fe8 100644 --- a/test/network_tests/header_factory_tests/header_factory_test_service.cpp +++ b/test/network_tests/header_factory_tests/header_factory_test_service.cpp @@ -3,9 +3,10 @@ // 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 "header_factory_test_service.hpp" - #include +#include + +#include "header_factory_test_service.hpp" header_factory_test_service::header_factory_test_service(bool _use_static_routing) : app_(vsomeip::runtime::get()->create_application()), diff --git a/test/network_tests/initial_event_tests/CMakeLists.txt b/test/network_tests/initial_event_tests/CMakeLists.txt new file mode 100644 index 000000000..3242ec4b5 --- /dev/null +++ b/test/network_tests/initial_event_tests/CMakeLists.txt @@ -0,0 +1,300 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(initial_event_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + initial_event_test_diff_client_ids_diff_ports_master.json + initial_event_test_diff_client_ids_diff_ports_master_tcp.json + initial_event_test_diff_client_ids_diff_ports_master_udp.json + initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json + initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json + initial_event_test_diff_client_ids_diff_ports_slave.json + initial_event_test_diff_client_ids_diff_ports_slave_tcp.json + initial_event_test_diff_client_ids_diff_ports_slave_udp.json + initial_event_test_diff_client_ids_partial_same_ports_master.json + initial_event_test_diff_client_ids_partial_same_ports_slave.json + initial_event_test_diff_client_ids_same_ports_master.json + initial_event_test_diff_client_ids_same_ports_master_tcp.json + initial_event_test_diff_client_ids_same_ports_master_udp.json + initial_event_test_diff_client_ids_same_ports_slave.json + initial_event_test_diff_client_ids_same_ports_slave_tcp.json + initial_event_test_diff_client_ids_same_ports_slave_udp.json + initial_event_test_master_starter.sh + initial_event_test_master_starter_qnx.sh + initial_event_test_same_client_ids_diff_ports_master.json + initial_event_test_same_client_ids_diff_ports_slave.json + initial_event_test_same_client_ids_same_ports_master.json + initial_event_test_same_client_ids_same_ports_slave.json + initial_event_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(initial_event_test_client + initial_event_test_client.cpp +) + +# Add test executable. +add_executable(initial_event_test_service + initial_event_test_service.cpp +) + +# Add test executable. +add_executable(initial_event_test_availability_checker + initial_event_test_availability_checker.cpp +) + +# Add test executable. +add_executable(initial_event_test_stop_service + initial_event_test_stop_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + initial_event_test_client + initial_event_test_service + initial_event_test_availability_checker + initial_event_test_stop_service +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Initial Events Tests - Single Event + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_diff_ports_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_udp.json + UDP +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_diff_ports_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_tcp.json + TCP +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master.json + TCP_AND_UDP +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_same_ports_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master_udp.json + UDP +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_same_ports_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master_tcp.json + TCP +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master.json + TCP_AND_UDP +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_partial_same_ports_master.json + TCP_AND_UDP +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json + TCP_AND_UDP SAME_SERVICE_ID +) + +# Initial Events Tests - Multiple Events + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_diff_ports_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_udp.json + UDP MULTIPLE_EVENTS +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_diff_ports_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_tcp.json + TCP MULTIPLE_EVENTS +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_diff_ports_udp_and_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master.json + TCP_AND_UDP MULTIPLE_EVENTS +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_same_ports_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master_udp.json + UDP MULTIPLE_EVENTS +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_same_ports_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master_tcp.json + TCP MULTIPLE_EVENTS +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master.json + TCP_AND_UDP MULTIPLE_EVENTS +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_partial_same_ports_master.json + TCP_AND_UDP MULTIPLE_EVENTS +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json + TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS +) + +# Initial Events Tests - Multiple Events, Subscribe On Availability + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_udp.json + UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_tcp.json + TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp_and_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master.json + TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master_udp.json + UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master_tcp.json + TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_same_ports_master.json + TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_partial_same_ports_master.json + TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json + TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY +) + +# Initial Events Tests - Multiple Events, Subscribe Only One + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_udp.json + UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_tcp.json + TCP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE +) + +# Add custom test command. +add_custom_test( + NAME initial_event_test_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp_and_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master.json + TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE +) + +# Initial Events Tests - Subscribe Twice + +# Add custom test command. +add_custom_test( + NAME initial_event_test_diff_client_ids_diff_ports_client_subscribes_twice + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/initial_event_test_master_starter.sh + initial_event_test_diff_client_ids_diff_ports_master_udp.json + UDP CLIENT_SUBSCRIBES_TWICE +) diff --git a/test/network_tests/initial_event_tests/initial_event_test_master_starter.sh b/test/network_tests/initial_event_tests/conf/initial_event_test_master_starter.sh.in similarity index 97% rename from test/network_tests/initial_event_tests/initial_event_test_master_starter.sh rename to test/network_tests/initial_event_tests/conf/initial_event_test_master_starter.sh.in index b8f673350..bd46819f8 100755 --- a/test/network_tests/initial_event_tests/initial_event_test_master_starter.sh +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_master_starter.sh.in @@ -28,7 +28,7 @@ print_starter_message () { if [ ! -z "$USE_LXC_TEST" ]; then echo "starting initial event test on slave LXC with params $CLIENT_JSON_FILE $REMAINING_OPTIONS" - 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/network_tests; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\"" & + 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/network_tests/initial_event_tests; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS" & else diff --git a/test/network_tests/initial_event_tests/initial_event_test_master_starter_qnx.sh b/test/network_tests/initial_event_tests/conf/initial_event_test_master_starter_qnx.sh.in similarity index 100% rename from test/network_tests/initial_event_tests/initial_event_test_master_starter_qnx.sh rename to test/network_tests/initial_event_tests/conf/initial_event_test_master_starter_qnx.sh.in diff --git a/test/network_tests/initial_event_tests/initial_event_test_slave_starter.sh b/test/network_tests/initial_event_tests/conf/initial_event_test_slave_starter.sh.in similarity index 100% rename from test/network_tests/initial_event_tests/initial_event_test_slave_starter.sh rename to test/network_tests/initial_event_tests/conf/initial_event_test_slave_starter.sh.in diff --git a/test/network_tests/lazy_load_tests/CMakeLists.txt b/test/network_tests/lazy_load_tests/CMakeLists.txt new file mode 100644 index 000000000..343093e30 --- /dev/null +++ b/test/network_tests/lazy_load_tests/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(lazy_load_tests LANGUAGES CXX) + +if (TEST_SECURITY) + + # Configure necessary files into build folder. + set(configuration_files + lazy_load_test_start.sh + vsomeip/lazy_load_test_config.json + vsomeip/vsomeip_ext/1_1/vsomeip_security.json + vsomeip/vsomeip_policy_extensions.json + ) + configure_files("${configuration_files}") + + # Add test executable. + add_executable(lazy_load_test_service + lazy_load_test_service.cpp + ) + + # Add test executable. + add_executable(lazy_load_test_client + lazy_load_test_client.cpp + ) + + # Add test executable. + add_executable(lazy_load_test_lazy_client + lazy_load_test_lazy_client.cpp + ) + + # Add build dependencies and link libraries to executables. + set(executables + lazy_load_test_service + lazy_load_test_client + lazy_load_test_lazy_client + ) + targets_link_default_libraries("${executables}") + targets_add_default_dependencies("${executables}") + + # Add custom test command. + add_custom_test( + NAME lazy_load_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/lazy_load_test_start.sh + ) + +endif() diff --git a/test/network_tests/lazy_load_tests/conf/lazy_load_test_start.sh.in b/test/network_tests/lazy_load_tests/conf/lazy_load_test_start.sh.in new file mode 100755 index 000000000..6a3b3381d --- /dev/null +++ b/test/network_tests/lazy_load_tests/conf/lazy_load_test_start.sh.in @@ -0,0 +1,40 @@ +#!/bin/bash +# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +export VSOMEIP_CONFIGURATION=/vsomeip/ +export VSOMEIP_APPLICATION_NAME=routingmanagerd +# start daemon +../../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +sleep 1 + +export VSOMEIP_APPLICATION_NAME=service-sample +./lazy_load_test_service & + +sleep 1 + +export VSOMEIP_CONFIGURATION=lazy_load_test_service_config.json +export VSOMEIP_APPLICATION_NAME=client-sample_normal +./lazy_load_test_client & + +sleep 2 + +export VSOMEIP_CONFIGURATION=/vsomeip/ +export VSOMEIP_APPLICATION_NAME=client-sample-lazy +# start lazy client with linux user id 1 and group id 1 to use the 1_1 folder in extensions +setpriv --reuid=1 --regid=1 --clear-groups ./lazy_load_test_lazy_client + +sleep 1 + +kill $PID_VSOMEIPD +wait $PID_VSOMEIPD diff --git a/test/network_tests/lazy_load_tests/conf/vsomeip/lazy_load_test_config.json.in b/test/network_tests/lazy_load_tests/conf/vsomeip/lazy_load_test_config.json.in new file mode 100644 index 000000000..6cfbd80d7 --- /dev/null +++ b/test/network_tests/lazy_load_tests/conf/vsomeip/lazy_load_test_config.json.in @@ -0,0 +1,109 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "true" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277" + }, + { + "name" : "client-sample-normal", + "id" : "0x1255" + }, + { + "name" : "client-sample-lazy", + "id" : "0x1256" + }, + { + "name" : "routingmanagerd", + "id" : "0x1111" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x111", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x1234", + "instance" : "0x02", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + "security" : + { + "check_credentials" : "true", + "allow_remote_clients" : "true", + "policies" : + [ + { + "credentials" : [ + {"uid" : "@TEST_UID@", "gid" : "@TEST_GID@"} , + {"uid" : "1", "gid" : "1"} + ], + "allow" : + { + "offers": + [ + { + "service" : "0x1234", + "instances" : ["0x5678", "0x02"] + } + ] + } + }, + { + "credentials" : {"uid" : "@TEST_UID@", "gid" : "@TEST_GID@"}, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : + [ + { + "ids" : ["0x5678"], + "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8001", "0x7777" ] + } + ] + } + ] + } + } + ] + }, + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/lazy_load_tests/conf/vsomeip/vsomeip_ext/1_1/vsomeip_security.json.in b/test/network_tests/lazy_load_tests/conf/vsomeip/vsomeip_ext/1_1/vsomeip_security.json.in new file mode 100644 index 000000000..c1b64997e --- /dev/null +++ b/test/network_tests/lazy_load_tests/conf/vsomeip/vsomeip_ext/1_1/vsomeip_security.json.in @@ -0,0 +1,27 @@ +{ + "security" : + { + "policies" : + [ + { + "credentials" : { "uid" : "1", "gid" : "1" }, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : + [ + { + "ids" : ["0x02"], + "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8002", "0x7777" ] + } + ] + } + ] + } + } + ] + } +} diff --git a/test/network_tests/lazy_load_tests/conf/vsomeip/vsomeip_policy_extensions.json.in b/test/network_tests/lazy_load_tests/conf/vsomeip/vsomeip_policy_extensions.json.in new file mode 100644 index 000000000..5934604fb --- /dev/null +++ b/test/network_tests/lazy_load_tests/conf/vsomeip/vsomeip_policy_extensions.json.in @@ -0,0 +1,8 @@ +{ + "container_policy_extensions": + [ + { + "container": "@HOSTNAME@", "path": "../..@CMAKE_CURRENT_BINARY_DIR@/vsomeip/vsomeip_ext" + } + ] +} diff --git a/test/network_tests/lazy_load_tests/lazy_load_test_client.cpp b/test/network_tests/lazy_load_tests/lazy_load_test_client.cpp new file mode 100644 index 000000000..e078374d7 --- /dev/null +++ b/test/network_tests/lazy_load_tests/lazy_load_test_client.cpp @@ -0,0 +1,232 @@ +// Copyright (C) 2023 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 "lazy_load_test_client.hpp" + +lazy_load_test_client::lazy_load_test_client() + : app_(vsomeip::runtime::get()->create_application()), + current_service_availability_status_(false), + sender_(std::bind(&lazy_load_test_client::run, this)), + received_responses_(0), + received_allowed_events_(0) {} + +bool lazy_load_test_client::init() { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&lazy_load_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&lazy_load_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + TEST_INSTANCE_LAZY, vsomeip::ANY_METHOD, + std::bind(&lazy_load_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&lazy_load_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->register_availability_handler(SERVICE_TO_BE_REFUSED, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&lazy_load_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + TEST_INSTANCE_LAZY, + std::bind(&lazy_load_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void lazy_load_test_client::start() { + VSOMEIP_INFO << "Starting..."; + + app_->start(); +} + +void lazy_load_test_client::stop() { + VSOMEIP_INFO << "Stopping..."; + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + app_->clear_all_handler(); + app_->stop(); +} + +void lazy_load_test_client::on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "CLIENT ON_STATE..."; + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + + // request not allowed service ID + app_->request_service(SERVICE_TO_BE_REFUSED, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + + // request not allowed instance ID + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + TEST_INSTANCE_LAZY, false); + + // request events of eventgroup 0x01 which holds events 0x8001 (allowed) and 0x8002 (denied) + std::set its_eventgroups; + its_eventgroups.insert(EVENT_GROUP); + + app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(EVENT_TO_ACCEPT), + 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(EVENT_TO_REFUSE), + 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, EVENT_GROUP, + vsomeip::DEFAULT_MAJOR, static_cast(EVENT_TO_ACCEPT)); + + app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, EVENT_GROUP, + vsomeip::DEFAULT_MAJOR, static_cast(EVENT_TO_REFUSE)); + + } +} + +void lazy_load_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_service_available) { + + VSOMEIP_INFO << "CLIENT ON_AVAILABILITY..."; + VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() + << " : Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << '.' << _instance << "] is " + << (_is_service_available ? "available." : "NOT available."); + + // Check that only the allowed service is available + if (_is_service_available) { + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _service) + << "Unexpected Service ID on_availability"; + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _instance) + << "Unexpected Instance ID on_availability"; + } + if (vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { + std::unique_lock its_lock(mutex_); + if (current_service_availability_status_ && !_is_service_available) { + current_service_availability_status_ = false; + } else if (_is_service_available && !current_service_availability_status_) { + current_service_availability_status_ = true; + condition_.notify_one(); + } + } +} + +void lazy_load_test_client::on_message(const std::shared_ptr &_response) { + VSOMEIP_INFO << "Received a response from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << '.' + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << '/' + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << ']'; + + if (_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()) + << "Unexpected Service ID on_message response"; + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()) + << "Unexpected Instance ID on_message response"; + EXPECT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _response->get_method()) + << "Unexpected Method ID on_message response"; + + + if (_response->get_service() == vsomeip_test::TEST_SERVICE_SERVICE_ID && + _response->get_instance() == vsomeip_test::TEST_SERVICE_INSTANCE_ID && + _response->get_method() == vsomeip_test::TEST_SERVICE_METHOD_ID) { + received_responses_++; + if (received_responses_ == NUMBER_OF_MESSAGES_TO_SEND) { + VSOMEIP_WARNING << std::hex << app_->get_client() + << ": Received all messages ~> going down!"; + } + } + + } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + + // check that only allowed event 0x8001 is received for client-sample-a + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()) + << "Unexpected Service ID on_message notification"; + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()) + << "Unexpected Instance ID on_message notification"; + EXPECT_EQ(EVENT_TO_ACCEPT, _response->get_method()) + << "Unexpected Method ID on_message notification"; + + received_allowed_events_++; + } +} + +void lazy_load_test_client::run() { + for (std::uint32_t i = 0; i < NUMBER_OF_MESSAGES_TO_SEND; ++i) { + { + std::unique_lock its_lock(mutex_); + while (!current_service_availability_status_) { + condition_.wait(its_lock); + } + } + + auto request = vsomeip::runtime::get()->create_request(false); + + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + + // send a request which is allowed by policy -> expect answer + app_->send(request); + + // send a request with a not allowed method ID -> expect no answer + request->set_method(METHOD_TO_BE_REFUSED); + app_->send(request); + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + + EXPECT_EQ(NUMBER_OF_MESSAGES_TO_SEND, received_responses_) + << "Unexpected received_responses_ run()"; + EXPECT_EQ(received_allowed_events_, static_cast(EXPECTED_EVENTS)) + << "Unexpected received_allowed_events run()"; + + stop(); +} + +void lazy_load_test_client::join_sender_thread() { + if (sender_.joinable()) { + sender_.join(); + } +} + +TEST(someip_lazy_load_test, normal_client) { + lazy_load_test_client test_client; + if (test_client.init()) { + test_client.start(); + test_client.join_sender_thread(); + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/lazy_load_tests/lazy_load_test_client.hpp b/test/network_tests/lazy_load_tests/lazy_load_test_client.hpp new file mode 100644 index 000000000..245ac1f2f --- /dev/null +++ b/test/network_tests/lazy_load_tests/lazy_load_test_client.hpp @@ -0,0 +1,61 @@ +// Copyright (C) 2023 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 LAZY_LOAD_TEST_CLIENT_HPP +#define LAZY_LOAD_TEST_CLIENT_HPP + +#include +#include +#include +#include + +#include +#include + +#include "../someip_test_globals.hpp" + +class lazy_load_test_client { +public: + lazy_load_test_client(); + bool init(); + void start(); + void stop(); + + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + + void run(); + void join_sender_thread(); + +private: + void shutdown_service(); + + std::shared_ptr app_; + + std::mutex mutex_; + std::condition_variable condition_; + bool current_service_availability_status_; + + std::thread sender_; + + std::atomic received_responses_; + std::atomic received_allowed_events_; + + const std::uint16_t METHOD_TO_BE_REFUSED = 0x888; + const std::uint16_t SERVICE_TO_BE_REFUSED = 0x111; + const std::uint16_t TEST_INSTANCE_LAZY = 0x02; + const std::uint16_t EXPECTED_EVENTS = 0x01; + + const std::uint16_t EVENT_GROUP = 0x01; + const std::uint16_t EVENT_TO_ACCEPT = 0x8001; + const std::uint16_t EVENT_TO_REFUSE = 0x8002; + + const std::uint16_t NUMBER_OF_MESSAGES_TO_SEND = 10; + +}; + +#endif // LAZY_LOAD_TEST_CLIENT_HPP diff --git a/test/network_tests/lazy_load_tests/lazy_load_test_lazy_client.cpp b/test/network_tests/lazy_load_tests/lazy_load_test_lazy_client.cpp new file mode 100644 index 000000000..8e9a68a60 --- /dev/null +++ b/test/network_tests/lazy_load_tests/lazy_load_test_lazy_client.cpp @@ -0,0 +1,242 @@ +// Copyright (C) 2023 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 "lazy_load_test_lazy_client.hpp" + +lazy_load_lazy_client::lazy_load_lazy_client() + : app_(vsomeip::runtime::get()->create_application()), + current_service_availability_status_(false), + sender_(std::bind(&lazy_load_lazy_client::run, this)), + received_responses_(0), + received_allowed_events_(0) {} + +bool lazy_load_lazy_client::init() { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&lazy_load_lazy_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&lazy_load_lazy_client::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + TEST_INSTANCE_LAZY, vsomeip::ANY_METHOD, + std::bind(&lazy_load_lazy_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&lazy_load_lazy_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->register_availability_handler(SERVICE_TO_BE_REFUSED, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&lazy_load_lazy_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + TEST_INSTANCE_LAZY, + std::bind(&lazy_load_lazy_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void lazy_load_lazy_client::start() { + VSOMEIP_INFO << "Starting..."; + + app_->start(); +} + +void lazy_load_lazy_client::stop() { + VSOMEIP_INFO << "Stopping..."; + shutdown_service(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + app_->clear_all_handler(); + app_->stop(); +} + +void lazy_load_lazy_client::on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "CLIENT ON_STATE..."; + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + // request not allowed instance ID + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + + // request not allowed service ID + app_->request_service(SERVICE_TO_BE_REFUSED, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + TEST_INSTANCE_LAZY, false); + + // request events of eventgroup 0x01 which holds events 0x8001 (denied) and 0x8002 (allowed) + std::set its_eventgroups; + its_eventgroups.insert(EVENT_GROUP); + + app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, + static_cast(EVENT_TO_REFUSE_LAZY), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, + static_cast(EVENT_TO_ACCEPT_LAZY), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + + app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, EVENT_GROUP, + vsomeip::DEFAULT_MAJOR, static_cast(EVENT_TO_REFUSE_LAZY)); + + app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, EVENT_GROUP, + vsomeip::DEFAULT_MAJOR, static_cast(EVENT_TO_ACCEPT_LAZY)); + } +} + +void lazy_load_lazy_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_service_available) { + + VSOMEIP_INFO << "CLIENT ON_AVAILABILITY..."; + VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() + << " : Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << '.' << _instance << "] is " + << (_is_service_available ? "available." : "NOT available."); + + // Check that only the allowed service is available + if (_is_service_available) { + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _service) + << "Unexpected Service ID on_available"; + EXPECT_EQ(TEST_INSTANCE_LAZY, _instance) + << "Unexpected Instance ID on_available"; + } + + if (vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && TEST_INSTANCE_LAZY == _instance) { + std::unique_lock its_lock(mutex_); + if (current_service_availability_status_ && !_is_service_available) { + current_service_availability_status_ = false; + } else if (_is_service_available && !current_service_availability_status_) { + current_service_availability_status_ = true; + condition_.notify_one(); + } + } + +} + +void lazy_load_lazy_client::on_message(const std::shared_ptr &_response) { + VSOMEIP_INFO << "Received a response from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << '.' + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << '/' + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << ']'; + + if (_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()) + << "Unexpected Service ID on_message response"; + EXPECT_EQ(TEST_INSTANCE_LAZY, _response->get_instance()) + << "Unexpected Instance ID on_message response"; + EXPECT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _response->get_method()) + << "Unexpected Method ID on_message response"; + + + if (_response->get_service() == vsomeip_test::TEST_SERVICE_SERVICE_ID && + _response->get_method() == vsomeip_test::TEST_SERVICE_METHOD_ID) { + received_responses_++; + if (received_responses_ == NUMBER_OF_MESSAGES_TO_SEND) { + VSOMEIP_WARNING << std::hex << app_->get_client() + << ": Received all messages ~> going down!"; + } + } + + } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + + // check that only allowed event 0x8002 is received for client-sample-lazy + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()) + << "Unexpected Service ID on_message notification"; + EXPECT_EQ(TEST_INSTANCE_LAZY, _response->get_instance()) + << "Unexpected Instance ID on_message notification"; + EXPECT_EQ(EVENT_TO_ACCEPT_LAZY, _response->get_method()) + << "Unexpected Method ID on_message notification"; + received_allowed_events_++; + } +} + +void lazy_load_lazy_client::run() { + for (std::uint32_t i = 0; i < NUMBER_OF_MESSAGES_TO_SEND; ++i) { + { + std::unique_lock its_lock(mutex_); + while (!current_service_availability_status_) { + condition_.wait(its_lock); + } + } + + auto request = vsomeip::runtime::get()->create_request(false); + + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(TEST_INSTANCE_LAZY); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + + + // send a request which is allowed by policy -> expect answer + app_->send(request); + + // send a request with a not allowed method ID -> expect no answer + request->set_method(METHOD_TO_BE_REFUSED); + app_->send(request); + + std::this_thread::sleep_for(std::chrono::milliseconds(400)); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + EXPECT_EQ(NUMBER_OF_MESSAGES_TO_SEND,received_responses_) + << "Unexpected received_responses_ run"; + EXPECT_EQ(received_allowed_events_, static_cast(EXPECTED_EVENTS)) + << "Unexpected received_allowed_events_ run"; + + stop(); +} + +void lazy_load_lazy_client::join_sender_thread() { + if (sender_.joinable()) { + sender_.join(); + } +} + +void lazy_load_lazy_client::shutdown_service() { + VSOMEIP_INFO << "SHUTDOWN_SERVICE called from LAZY client"; + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(TEST_INSTANCE_LAZY); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(request); +} + +TEST(someip_lazy_load_test, lazy_client) { + lazy_load_lazy_client test_lazy_client; + if (test_lazy_client.init()) { + test_lazy_client.start(); + test_lazy_client.join_sender_thread(); + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/lazy_load_tests/lazy_load_test_lazy_client.hpp b/test/network_tests/lazy_load_tests/lazy_load_test_lazy_client.hpp new file mode 100644 index 000000000..0d8aaadb6 --- /dev/null +++ b/test/network_tests/lazy_load_tests/lazy_load_test_lazy_client.hpp @@ -0,0 +1,60 @@ +// Copyright (C) 2023 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 LAZY_LOAD_TEST_LAZY_CLIENT_HPP +#define LAZY_LOAD_TEST_LAZY_CLIENT_HPP + +#include +#include +#include +#include + +#include +#include + +#include "../someip_test_globals.hpp" + +class lazy_load_lazy_client { +public: + lazy_load_lazy_client(); + bool init(); + void start(); + void stop(); + + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + + void run(); + void join_sender_thread(); + +private: + void shutdown_service(); + + std::shared_ptr app_; + + std::mutex mutex_; + std::condition_variable condition_; + bool current_service_availability_status_; + + std::thread sender_; + + std::atomic received_responses_; + std::atomic received_allowed_events_; + + const std::uint16_t METHOD_TO_BE_REFUSED = 0x888; + const std::uint16_t SERVICE_TO_BE_REFUSED = 0x111; + const std::uint16_t TEST_INSTANCE_LAZY = 0x02; + const std::uint16_t EXPECTED_EVENTS = 0x01; + + const std::uint16_t EVENT_GROUP = 0x01; + const std::uint16_t EVENT_TO_ACCEPT_LAZY = 0x8002; + const std::uint16_t EVENT_TO_REFUSE_LAZY = 0x8001; + + const std::uint16_t NUMBER_OF_MESSAGES_TO_SEND = 10; +}; + +#endif // LAZY_LOAD_TEST_LAZY_CLIENT_HPP diff --git a/test/network_tests/lazy_load_tests/lazy_load_test_service.cpp b/test/network_tests/lazy_load_tests/lazy_load_test_service.cpp new file mode 100644 index 000000000..001bff656 --- /dev/null +++ b/test/network_tests/lazy_load_tests/lazy_load_test_service.cpp @@ -0,0 +1,197 @@ +// Copyright (C) 2023 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 "lazy_load_test_service.hpp" + +lazy_load_test_service::lazy_load_test_service() : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&lazy_load_test_service::run, this)) {} + +bool lazy_load_test_service::init() { + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&lazy_load_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + TEST_INSTANCE_LAZY, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&lazy_load_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + TEST_INSTANCE_LAZY, + vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&lazy_load_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&lazy_load_test_service::on_state, this, + std::placeholders::_1)); + + // offer eventgroup 0x01 + std::set its_eventgroups; + its_eventgroups.insert(EVENT_GROUP); + + app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(EVENT_TO_ACCEPT_DEFAULT), its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + 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(EVENT_TO_ACCEPT_LAZY), its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + // Used with lazy client also offer field 0x8001 which is not allowed to be received by lazy client + app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, + static_cast(EVENT_TO_ACCEPT_DEFAULT), its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, + static_cast(EVENT_TO_ACCEPT_LAZY), its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + // set value to fields + std::shared_ptr its_payload = + vsomeip::runtime::get()->create_payload(); + vsomeip::byte_t its_data[2]{ + static_cast((vsomeip_test::TEST_SERVICE_SERVICE_ID & 0xFF00) >> 8), + static_cast((vsomeip_test::TEST_SERVICE_SERVICE_ID & 0xFF)) + }; + its_payload->set_data(its_data, 2); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(EVENT_TO_ACCEPT_DEFAULT), its_payload); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(EVENT_TO_ACCEPT_LAZY), its_payload); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, + static_cast(EVENT_TO_ACCEPT_DEFAULT), its_payload); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY, + static_cast(EVENT_TO_ACCEPT_LAZY), its_payload); + + return true; +} + +void lazy_load_test_service::start() { + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void lazy_load_test_service::stop() { + VSOMEIP_INFO << "Stopping..."; + stop_offer(); + app_->clear_all_handler(); + app_->stop(); +} + +void lazy_load_test_service::join_offer_thread() { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } +} + +void lazy_load_test_service::offer() { + // Instance used by client a + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); + + // Instance used by client b + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY); + + // try to offer a not allowed service ID 0x111 (client requesting the service should not get available) + app_->offer_service(SERVICE_TO_BE_REFUSED, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void lazy_load_test_service::stop_offer() { + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, TEST_INSTANCE_LAZY); +} + +void lazy_load_test_service::on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + if (!is_registered_) { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } else { + is_registered_ = false; + } +} + +void lazy_load_test_service::on_message(const std::shared_ptr& _request) { + ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); + ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method()); + + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << '/' + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "] method: " << _request->get_method() + << " Instance ID: " << _request->get_instance(); + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + VSOMEIP_INFO << "service on_message response service : " << its_response->get_service(); + app_->send(its_response); + + number_of_received_messages_++; + if (number_of_received_messages_ == NUMBER_OF_MESSAGES_TO_RECEIVE) { + VSOMEIP_INFO << "Received all messages!"; + } +} + +void lazy_load_test_service::on_message_shutdown( + const std::shared_ptr&) { + VSOMEIP_INFO << "Shutdown method was called, going down now."; + stop(); +} + +void lazy_load_test_service::run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); +} + +TEST(someip_lazy_load_test, service) { + lazy_load_test_service test_service; + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#ifdef __linux__ +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/lazy_load_tests/lazy_load_test_service.hpp b/test/network_tests/lazy_load_tests/lazy_load_test_service.hpp new file mode 100644 index 000000000..fa347b509 --- /dev/null +++ b/test/network_tests/lazy_load_tests/lazy_load_test_service.hpp @@ -0,0 +1,53 @@ +// Copyright (C) 2023 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 LAZY_LOAD_TEST_SERVICE_HPP +#define LAZY_LOAD_TEST_SERVICE_HPP + +#include +#include +#include + +#include +#include + +#include "../someip_test_globals.hpp" + +class lazy_load_test_service { +public: + lazy_load_test_service(); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void on_message_shutdown(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; + + const std::uint16_t SERVICE_TO_BE_REFUSED = 0x111; + const std::uint16_t TEST_INSTANCE_LAZY = 0x02; + + const std::uint16_t EVENT_GROUP = 0x01; + const std::uint16_t EVENT_TO_ACCEPT_LAZY = 0x8002; + const std::uint16_t EVENT_TO_ACCEPT_DEFAULT = 0x8001; + + // Twice as big as messages to send, account for all messages from both clients + const std::uint16_t NUMBER_OF_MESSAGES_TO_RECEIVE = 20; +}; + +#endif // LAZY_LOAD_TEST_SERVICE_HPP diff --git a/test/network_tests/lazy_load_tests/readme b/test/network_tests/lazy_load_tests/readme new file mode 100644 index 000000000..e58f99bba --- /dev/null +++ b/test/network_tests/lazy_load_tests/readme @@ -0,0 +1,112 @@ +Lazy Load Test + +Quick description: + +client-sample-normal: communicates with service id 0x1234, instance id 0x5678 without utilizing lazy loading. +client-sample-lazy: communicates with service id 0x1234, instance id 0x02. + +During the test registrations are made to the 0x01 eventgroup for both cases. +the normal client expects to receive the event 0x8001 while the lazy client expects the 0x8002 event. + +Multiple messages are then sent to the 0x8421, and the 0x888 methods of the respective service/instance for each test. Only responses from 0x8421 are expected. + +Details: + +Configs +The lazy load tests consists of 3 config jsons. +Two are configured json.in files, one is a direct json. + +-The lazy_load_test_config.json.in contains the basic app information: + --logging + + default configs + + --applications + + This tests uses 4 applications + "service-sample", "id" : "0x1277" runs the service app and will receive the requests from the clients + "client-sample-normal", "id" : "0x1255" client normal + "client-sample-lazy", "id" : "0x1256" client lazy + "routingmanagerd", "id" : "0x1111" in charge of the routing + + --services + + the list of services to be used in the app + service : "0x1234" holds 2 instance 0x5678 to interact with client a and 0x02 lazy client + service : "0x111" a dummy service which will not be permitted to be offered by policies + + --security: + + The security policy included in this json has the check_credentials set to true to enable the security feature to use Linux UserId and GroupId as credentials. + it always includes a policy that enables the offers of the service 0x1234 instances 0x5678 and 0x02 for the given credentials 0 0 and 1 1 + And holds the request part of the 0 0 credential (client sample) + + The request part of the security for lazy client is loaded subsequently by lazy loading + + --routing + + Routing will be handled by the routingmanagerd app + + --service discovery + default configs + +-The vsomeip_policy_extensions.json.in contains the container_policy_extensions which is a key value pair of the host container to the path of the vsomeip_security.json + +-The vsomeip_security.json contains the security policy for the requests allowed to credentials 1 1 (client-sample-lazy) + + + +The test + +Routingmanagerd app + The routingmanagerd app is brought up using the /vsomeip/ folder as its VSOMEIP_CONFIGURATION + Forcing it to parse the entire folder, and load the lazy_load_test_config.json + as well as the vsomeip_policy_extenions.json + The routingmanagerd is the routing manager and will handle communications between vsomeip apps. + +Service-sample app + The service-sample app is brought up using the same path as the routingmanagerd app. + The service-sample app offers 3 services + service 0x1234, instance 0x5678 (instance to interact with client-sample-normal due to security) + service 0x1234, instance 0x02 (instance to interact with client-sample-lazy due to security) + service 0x111, instance 0x5678 (dummy services offered, to be denied by security policies) + + The service 0x1234 + Contains an eventgroup 0x01 which has two offered events 0x8001 and 0x8002 + Both those events are populated with the payload 1234 and notified + Shutdown method 0x7777, used to shutdown the whole app + Method TEST_SERVICE_METHOD_ID = 0x8421 the method which will receive messages from the clients + + The service 0x111 + Offered but the security policies should prohibit the offer from happening. + Expect no interactions + + The test verifies the service-sample only receives message for the 0x1234 service and 0x8421 method + +Client-sample-normal app + The client-sample-normal app is brought up using direct injection of the lazy_load_test_config.json it will not undergo the lazy load process, used and will be used as the control case in this test. + + The app is initialized, request handlers are registered. + Upon registration of the app (app_state = registered) the client will request all three services offered by the service-sample. The on_availibity handler is the same for all 3 services. And tries to subscribe to both event of the 0x1234 0x5678 eventgroup 0x01 event 0x8001 and 0x8002 + + The first step of the test is to check that only the service 0x1234 instance 0x5678 becomes available to client-sample-normal + + The second step is to verify that only the notification from 0x8001 is received + + The third and final step is to send NUMBER_OF_MESSAGES_TO_SEND (32 as of writing this read me) messages to method 0x8421 and 0x888 of 0x1234 0x02 only responses from 0x8421 are expected. The tests expect to receive a total of NUMBER_OF_MESSAGES_TO_SEND + +Client-sample-lazy app + The client-sample-lazy app is brought up using the /vsomeip/ folder as its VSOMEIP_CONFIGURATION + Forcing it to parse the entire folder, and load the lazy_load_test_config.json + as well as the vsomeip_policy_extenions.json as well as execute the lazy loading of the vsomeip_security.json in the /vsomeip/vsomeip_ext/1_1/ folder + client-sample-lazy is the test case for lazy loading. + client-sample-lazy uses linux user-id uid: 1 and group-id gid: 1 + + The app is initialized, request handlers are registered. + Upon registration of the app (app_state = registered) the client will request all three services offered by the service-sample. The on_availibity handler is the same for all 3 services. And tries to subscribe to both event of the 0x1234 0x02 eventgroup 0x01 event 0x8001 and 0x8002 + + The first step of the test is to check that only the service 0x1234 instance 0x02 becomes available to client-sample-lazy + + The second step is to verify that only the notification from 0x8002 is received + + The third and final step is to send NUMBER_OF_MESSAGES_TO_SEND messages to method 0x8421 and 0x888 of 0x1234 0x02 only responses from 0x8421 are expected. The tests expect to receive a total of NUMBER_OF_MESSAGES_TO_SEND diff --git a/test/network_tests/magic_cookies_tests/CMakeLists.txt b/test/network_tests/magic_cookies_tests/CMakeLists.txt new file mode 100644 index 000000000..36e77a85d --- /dev/null +++ b/test/network_tests/magic_cookies_tests/CMakeLists.txt @@ -0,0 +1,48 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(magic_cookies_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + magic_cookies_test_client.json + magic_cookies_test_client_start.sh + magic_cookies_test_service.json + magic_cookies_test_service_start.sh + magic_cookies_test_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(magic_cookies_test_client + magic_cookies_test_client.cpp +) + +# Add test executable. +add_executable(magic_cookies_test_service + magic_cookies_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + magic_cookies_test_client + magic_cookies_test_service +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Link thread libraries to executables. +foreach(target ${executables}) + target_link_libraries(${target} ${CMAKE_THREAD_LIBS_INIT}) +endforeach() + +# Add custom test command. +add_custom_test( + NAME magic_cookies_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/magic_cookies_test_starter.sh + TIMEOUT 250 +) diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client_start.sh.in similarity index 100% rename from test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh rename to test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client_start.sh.in diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service_start.sh.in similarity index 100% rename from test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh rename to test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service_start.sh.in diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_starter.sh.in similarity index 96% rename from test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh rename to test/network_tests/magic_cookies_tests/conf/magic_cookies_test_starter.sh.in index 1e9cfc4d6..d077b149e 100755 --- a/test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh +++ b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_starter.sh.in @@ -17,7 +17,7 @@ FAIL=0 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting magic cookies test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./magic_cookies_test_client_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/magic_cookies_tests; ./magic_cookies_test_client_start.sh\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./magic_cookies_test_client_start.sh" & else diff --git a/test/network_tests/malicious_data_tests/CMakeLists.txt b/test/network_tests/malicious_data_tests/CMakeLists.txt new file mode 100644 index 000000000..c4ac4d958 --- /dev/null +++ b/test/network_tests/malicious_data_tests/CMakeLists.txt @@ -0,0 +1,96 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(malicious_data_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + malicious_data_test_master.json + malicious_data_test_master_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(malicious_data_test_service + malicious_data_test_service.cpp +) + +# Add test executable. +set(service_discovery_sources + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/configuration_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/entry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/eventgroupentry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ip_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ipv4_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ipv6_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/load_balancing_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/message_element_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/message_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/protection_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/selective_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/serviceentry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/unknown_option_impl.cpp +) +set(message_sources + ${CMAKE_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${CMAKE_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/message/src/payload_impl.cpp +) +add_executable(malicious_data_test_msg_sender + malicious_data_test_msg_sender.cpp + ${service_discovery_sources} + ${message_sources} +) + +# Link the vsomeip-sd library to the executable. +target_link_libraries(malicious_data_test_msg_sender + ${VSOMEIP_NAME}-sd +) + +# Add build dependencies and link libraries to executables. +set(executables + malicious_data_test_service + malicious_data_test_msg_sender +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME malicious_data_test_events + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/malicious_data_test_master_starter.sh MALICIOUS_EVENTS + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME malicious_data_test_protocol_version + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/malicious_data_test_master_starter.sh PROTOCOL_VERSION + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME malicious_data_test_message_type + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/malicious_data_test_master_starter.sh MESSAGE_TYPE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME malicious_data_test_return_code + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/malicious_data_test_master_starter.sh RETURN_CODE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME malicious_data_test_wrong_header_fields_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/malicious_data_test_master_starter.sh WRONG_HEADER_FIELDS_UDP + TIMEOUT 180 +) diff --git a/test/network_tests/malicious_data_tests/conf/malicious_data_test_master_starter.sh.in b/test/network_tests/malicious_data_tests/conf/malicious_data_test_master_starter.sh.in index 6cdefc621..301ecfa4b 100755 --- a/test/network_tests/malicious_data_tests/conf/malicious_data_test_master_starter.sh.in +++ b/test/network_tests/malicious_data_tests/conf/malicious_data_test_master_starter.sh.in @@ -24,7 +24,7 @@ TESTMODE=$1 export VSOMEIP_CONFIGURATION=malicious_data_test_master.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! # Start the services ./malicious_data_test_service $TESTMODE & @@ -36,7 +36,7 @@ if [ ! -z "$USE_LXC_TEST" ]; then echo "Waiting for 5s" sleep 5 echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./malicious_data_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $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/network_tests/malicious_data_tests; ./malicious_data_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\"" & echo "remote ssh pid: $!" elif [ ! -z "$USE_DOCKER" ]; then echo "Waiting for 5s" diff --git a/test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp b/test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp index 4c75e9f3f..f5f15927e 100644 --- a/test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp +++ b/test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp @@ -16,7 +16,7 @@ #include -#include "../../implementation/utility/include/byteorder.hpp" +#include "../../implementation/utility/include/bithelper.hpp" #include "../../implementation/message/include/deserializer.hpp" #include "../../implementation/service_discovery/include/service_discovery.hpp" #include "../../implementation/service_discovery/include/message_impl.hpp" @@ -84,10 +84,9 @@ TEST_F(malicious_data, send_malicious_events) #endif vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_METHOD_POS_MIN]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { vsomeip::sd::message_impl sd_msg; EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); @@ -313,10 +312,9 @@ TEST_F(malicious_data, send_wrong_protocol_version) return; } else { vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_METHOD_POS_MIN]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { vsomeip::sd::message_impl sd_msg; EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); @@ -700,10 +698,9 @@ TEST_F(malicious_data, send_wrong_message_type) return; } else { vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_METHOD_POS_MIN]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { vsomeip::sd::message_impl sd_msg; EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); @@ -999,10 +996,9 @@ TEST_F(malicious_data, send_wrong_return_code) return; } else { vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_METHOD_POS_MIN]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { vsomeip::sd::message_impl sd_msg; EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); @@ -1303,10 +1299,9 @@ TEST_F(malicious_data, wrong_header_fields_udp) return; } else { vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_METHOD_POS_MIN]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { vsomeip::sd::message_impl sd_msg; EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); diff --git a/test/network_tests/memory_tests/CMakeLists.txt b/test/network_tests/memory_tests/CMakeLists.txt new file mode 100644 index 000000000..9a3f8c068 --- /dev/null +++ b/test/network_tests/memory_tests/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (C) 2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(memory_tests LANGUAGES CXX) + +# Configure necessary files into the build directory. +set(configuration_files + memory_test_client.json + memory_test_master_starter.sh + memory_test_service.json + memory_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(memory_test_client + memory_test_client.cpp +) + +# Add test executable. +add_executable(memory_test_service + memory_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + memory_test_service + memory_test_client +) +targets_link_default_libraries("${executables}") +targets_add_default_dependencies("${executables}") + +# Add custom test command. +add_custom_test( + NAME memory_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/memory_test_master_starter.sh + TIMEOUT 600 +) diff --git a/test/network_tests/memory_tests/conf/memory_test_client.json.in b/test/network_tests/memory_tests/conf/memory_test_client.json.in new file mode 100644 index 000000000..0964655f2 --- /dev/null +++ b/test/network_tests/memory_tests/conf/memory_test_client.json.in @@ -0,0 +1,37 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging": { + "level": "verbose", + "console": "true", + "file": { + "enable": "true", + "path": "/tmp/foo.log" + }, + "dlt": "true" + }, + "tracing" : + { + "enable" : "false" + } +, + "services" : + [ + { + "service" : "0xb519", + "instance" : "0x0001", + "unicast" : "@TEST_IP_SLAVE@", + "unreliable" : "30503", + "someip-tp" : { + "client-to-service": [ "0x8008", "0x8009", "0x800a", "0x800b", "0x800c", "0x800d", "0x800e", "0x800f", "0x8010", "0x8011", "0x8012", "0x8013", "0x8014", "0x8015", "0x8016", "0x8017", "0x8018", "0x8019", "0x801a", "0x801b"] + } + } + ], + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.251.192.252", + "port" : "30490", + "protocol" : "udp", + "cyclic_offer_delay" : "1000" + } +} diff --git a/test/network_tests/memory_tests/conf/memory_test_master_starter.sh.in b/test/network_tests/memory_tests/conf/memory_test_master_starter.sh.in new file mode 100755 index 000000000..f0c57e4f9 --- /dev/null +++ b/test/network_tests/memory_tests/conf/memory_test_master_starter.sh.in @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright (C) 2024 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/. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=memory_test_client.json + +./memory_test_client & +PID_MASTER=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting memory test on slave LXC memory_test_slave_starter.sh" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/memory_tests; ./memory_test_slave_starter.sh\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./memory_test_slave_starter.sh" & +else +cat < +#include +#include + +#include +#include "memory_test_client.hpp" + +void check_memory(std::vector &test_memory_, std::atomic &stop_checking_) +{ + while (!stop_checking_) { + std::this_thread::sleep_for(MEMORY_CHECKER_INTERVAL); + + static const std::uint32_t its_pagesize = static_cast(getpagesize() / 1024); + + std::FILE *its_file = std::fopen("/proc/self/statm", "r"); + if (!its_file) { + VSOMEIP_ERROR << "check_memory: couldn't open:" + << std::string(std::strerror(errno)); + return; + } + std::uint64_t its_size(0); + std::uint64_t its_rsssize(0); + std::uint64_t its_sharedpages(0); + std::uint64_t its_text(0); + std::uint64_t its_lib(0); + std::uint64_t its_data(0); + std::uint64_t its_dirtypages(0); + + if (EOF + == std::fscanf(its_file, "%lu %lu %lu %lu %lu %lu %lu", &its_size, &its_rsssize, + &its_sharedpages, &its_text, &its_lib, &its_data, &its_dirtypages)) { + VSOMEIP_ERROR << "check_memory: error reading:" + << std::string(std::strerror(errno)); + } + std::fclose(its_file); + + test_memory_.push_back(its_rsssize * its_pagesize); + VSOMEIP_INFO << "logged client: "<< its_rsssize * its_pagesize; + + } +} + +// Flag the desired event availability +void memory_test_client::on_availability(vsomeip::service_t service_, vsomeip::instance_t instance_, + bool is_available_) +{ + if (is_available_ && service_ == MEMORY_SERVICE && instance_ == MEMORY_INSTANCE) { + std::unique_lock lk(availability_mutex); + availability = true; + condition_availability.notify_one(); + } +} + +void memory_test_client::on_message(const std::shared_ptr &message_) +{ + if (MEMORY_SERVICE == message_->get_service() && message_->get_method() <= MEMORY_EVENT + TEST_EVENT_NUMBER + && message_->get_method() >= MEMORY_EVENT) { + auto its_runtime = vsomeip::runtime::get(); + auto its_message = its_runtime->create_request(false); + its_message->set_service(message_->get_service()); + its_message->set_instance(message_->get_instance()); + its_message->set_method(message_->get_method()); + its_message->set_interface_version(message_->get_interface_version()); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_payload(message_->get_payload()); + _app->send(its_message); + std::lock_guard lk(event_counter_mutex); + received_messages_counter++; + sec = std::chrono::system_clock::now(); + } +} + +memory_test_client::memory_test_client(const char *app_name_, const char *app_id_, + std::map map_events_) + : vsomeip_utilities::base_vsip_app(app_name_, app_id_), map_events(map_events_) +{ + sec = std::chrono::system_clock::now(); + _app->register_availability_handler(MEMORY_SERVICE, MEMORY_INSTANCE, + std::bind(&memory_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), + MEMORY_MAJOR, MEMORY_MINOR); + _app->register_message_handler( + MEMORY_SERVICE, MEMORY_INSTANCE, vsomeip::ANY_EVENT, + std::bind(&memory_test_client::on_message, this, std::placeholders::_1)); + for (uint16_t i = 0; i < TEST_EVENT_NUMBER; i++) { + _app->request_event(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_EVENT + i, + { MEMORY_EVENTGROUP }, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + } + _app->request_service(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_MAJOR, MEMORY_MINOR); + for (uint16_t i = 0; i < TEST_EVENT_NUMBER; i++) { + _app->subscribe(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_EVENTGROUP, MEMORY_MAJOR, + MEMORY_EVENT + i); + } +} + +void memory_test_client::send_request(std::atomic &stop_checking_) +{ + std::unique_lock lk(availability_mutex); + // Only send the requests when the service availability is secured + if (condition_availability.wait_for(lk, WAIT_AVAILABILITY, + [=] { return availability; })) { + + // Trigger the test + auto its_message = vsomeip_utilities::create_standard_vsip_request( + MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_START_METHOD, MEMORY_MAJOR, + vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + _app->send(its_message); + } + + EXPECT_TRUE(availability) << "Events expected by the client were not available for 15 seconds "; + + bool stop_watchdog { false }; + + // 3. Wait for service to send all the messages + while (!stop_watchdog) { + std::this_thread::sleep_for(WATCHDOG_INTERVAL); + std::lock_guard lk(event_counter_mutex); + if (std::chrono::duration_cast(std::chrono::system_clock::now() - sec) + .count() + > 10) { + stop_watchdog = true; + } + } + VSOMEIP_INFO << "received " << received_messages_counter; + stop_checking_ = true; +} + +void memory_test_client::unsubscribe_all() +{ + _app->unsubscribe(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_EVENTGROUP); +} + +void memory_test_client::stop_service() +{ + auto its_message = vsomeip_utilities::create_standard_vsip_request( + MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_STOP_METHOD, MEMORY_MAJOR, + vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + _app->send(its_message); + VSOMEIP_INFO << "sending stop " << received_messages_counter; + +} + +memory_test_client::~memory_test_client() +{ + stop_service(); + unsubscribe_all(); +} + +TEST(memory_tests, receive_messages) +{ + + // Test steps: + // 1: Start measuring memory load + // 2: Send requests for 20 different events + // 3: Wait for receiving all responses from service + // 4: Stop measuring load and evaluate load increase + // + // At the end evaluate if the threshold of 5% increase in memory load was not surpassed + + std::map events_to_subscribe; + + for (vsomeip::event_t i = 0; i < TEST_EVENT_NUMBER; i++) { + events_to_subscribe[MEMORY_EVENT + i] = 0; + } + + memory_test_client memory_test_client("memory_tests_client", "MTC", events_to_subscribe); + + std::atomic stop_checking { false }; + + // 1. Measure load until stop_checking is triggered + std::thread memory_checker_thread; + memory_checker_thread = std::thread([&stop_checking] { + std::vector test_memory_array; + std::uint64_t sum { 0 }; + + check_memory(test_memory_array, stop_checking); + + for (auto memory_stat : test_memory_array) { + sum += memory_stat; + VSOMEIP_INFO << memory_stat; + } + double memory_average = static_cast(sum) / static_cast(test_memory_array.size()); + VSOMEIP_INFO << memory_average; + + // 4. Evaluate memory load increase + for (auto memory_stat : test_memory_array) { + EXPECT_LT(static_cast(memory_stat), + (static_cast(memory_average) * MEMORY_LOAD_LIMIT)) + << "memory not lesser than " + << (static_cast(memory_average) * MEMORY_LOAD_LIMIT); + } + }); + + // 2. Send a request and wait until all the messages are sent by the service + memory_test_client.send_request(stop_checking); + + if (memory_checker_thread.joinable()) { + memory_checker_thread.join(); + } +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/memory_tests/memory_test_client.hpp b/test/network_tests/memory_tests/memory_test_client.hpp new file mode 100644 index 000000000..b2950de37 --- /dev/null +++ b/test/network_tests/memory_tests/memory_test_client.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2024 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 MEMORY_TEST_CLIENT_HPP_ +#define MEMORY_TEST_CLIENT_HPP_ + +#include +#include +#include + +#include + +#include + +#include "memory_test_common.hpp" +#include + +class memory_test_client : public vsomeip_utilities::base_vsip_app +{ +public: + memory_test_client(const char *app_name_, const char *app_id_, + std::map map_events_); + void send_request(std::atomic &stop_checking_); + + ~memory_test_client(); + +private: + std::condition_variable condition_availability; + std::mutex availability_mutex; + std::mutex event_counter_mutex; + bool availability { false }; + int received_messages_counter { 0 }; + std::map map_events; + std::chrono::time_point sec; + void on_availability(vsomeip::service_t service_, vsomeip::instance_t instance_, + bool is_available_); + void on_message(const std::shared_ptr &message_); + void stop_service(); + void unsubscribe_all(); + +}; + +#endif // MEMORY_TEST_CLIENT_HPP_ diff --git a/test/network_tests/memory_tests/memory_test_common.hpp b/test/network_tests/memory_tests/memory_test_common.hpp new file mode 100644 index 000000000..3419534e5 --- /dev/null +++ b/test/network_tests/memory_tests/memory_test_common.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2024 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 MEMORY_TEST_COMMON_HPP_ +#define MEMORY_TEST_COMMON_HPP_ + +#include + +constexpr vsomeip::service_t MEMORY_SERVICE = 0xb519; +constexpr vsomeip::instance_t MEMORY_INSTANCE = 0x0001; +constexpr vsomeip::method_t MEMORY_START_METHOD = 0x0998; +constexpr vsomeip::method_t MEMORY_STOP_METHOD = 0x0999; +constexpr vsomeip::event_t MEMORY_EVENT = 0x8008; +constexpr vsomeip::eventgroup_t MEMORY_EVENTGROUP = 0x0005; +constexpr vsomeip::major_version_t MEMORY_MAJOR = 0x01; +constexpr vsomeip::minor_version_t MEMORY_MINOR = 0x01; + +constexpr auto MEMORY_CHECKER_INTERVAL = std::chrono::seconds(5); +constexpr auto MESSAGE_SENDER_INTERVAL = std::chrono::milliseconds(5); +constexpr auto WATCHDOG_INTERVAL = std::chrono::seconds(2); +constexpr auto WAIT_AVAILABILITY = std::chrono::milliseconds(15000); +constexpr auto WAIT_START_MESSAGE = std::chrono::milliseconds(10000); +constexpr auto WAIT_STOP_MESSAGE = std::chrono::seconds(30); + +constexpr uint16_t TEST_EVENT_NUMBER = 20; +constexpr uint16_t TEST_MESSAGE_NUMBER = 9000; +constexpr int NOTIFY_PAYLOAD_SIZE = 4000; +constexpr double MEMORY_LOAD_LIMIT = 1.15; // meaning 15% limit above the average value + +#endif // MEMORY_TEST_COMMON_HPP_ diff --git a/test/network_tests/memory_tests/memory_test_service.cpp b/test/network_tests/memory_tests/memory_test_service.cpp new file mode 100644 index 000000000..f5c5f2883 --- /dev/null +++ b/test/network_tests/memory_tests/memory_test_service.cpp @@ -0,0 +1,177 @@ +// Copyright (C) 2024 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 "memory_test_service.hpp" + +void check_memory(std::vector &test_memory_, std::atomic &stop_checking_) +{ + while (!stop_checking_) { + std::this_thread::sleep_for(MEMORY_CHECKER_INTERVAL); + + static const std::uint32_t its_pagesize = static_cast(getpagesize() / 1024); + + std::FILE *its_file = std::fopen("/proc/self/statm", "r"); + if (!its_file) { + VSOMEIP_ERROR << "check_memory: couldn't open:" + << std::string(std::strerror(errno)); + return; + } + std::uint64_t its_size(0); + std::uint64_t its_rsssize(0); + std::uint64_t its_sharedpages(0); + std::uint64_t its_text(0); + std::uint64_t its_lib(0); + std::uint64_t its_data(0); + std::uint64_t its_dirtypages(0); + + if (EOF + == std::fscanf(its_file, "%lu %lu %lu %lu %lu %lu %lu", &its_size, &its_rsssize, + &its_sharedpages, &its_text, &its_lib, &its_data, &its_dirtypages)) { + VSOMEIP_ERROR << "check_memory: error reading:" + << std::string(std::strerror(errno)); + } + std::fclose(its_file); + + test_memory_.push_back(its_rsssize * its_pagesize); + VSOMEIP_INFO << "logged service: "<< its_rsssize * its_pagesize; + + } +} +memory_test_service::memory_test_service(const char *app_name_, const char *app_id_) + : vsomeip_utilities::base_vsip_app(app_name_, app_id_) +{ + for (uint16_t i = 0; i < TEST_EVENT_NUMBER; i++) { + _app->offer_event(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_EVENT + i, { MEMORY_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), false, + true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + } + _app->register_message_handler( + MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_START_METHOD, + std::bind(&memory_test_service::on_start, this, std::placeholders::_1)); + _app->register_message_handler( + MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_STOP_METHOD, + std::bind(&memory_test_service::on_stop, this, std::placeholders::_1)); + _app->offer_service(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_MAJOR, MEMORY_MINOR); +} +void memory_test_service::on_start(const std::shared_ptr /*&_message*/) +{ + std::unique_lock lk(start_mutex); + received_message = true; + condition_wait_start.notify_one(); +} + +void memory_test_service::on_stop(const std::shared_ptr /*&_message*/) +{ + { + std::unique_lock lk(stop_mutex); + condition_wait_stop.notify_one(); + } + VSOMEIP_INFO << "service: " << __func__ << ": Received a STOP command."; +} + +void memory_test_service::message_sender(std::atomic &stop_checking_) +{ + auto its_payload = vsomeip::runtime::get()->create_payload(); + auto its_payload2 = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data(std::vector(NOTIFY_PAYLOAD_SIZE, 20)); + its_payload2->set_data(std::vector(NOTIFY_PAYLOAD_SIZE, 10)); + int count { 0 }; + for (int message_no = 0; message_no <= TEST_MESSAGE_NUMBER; message_no++) { + for (uint16_t i = 0; i < TEST_EVENT_NUMBER; i++) { + _app->notify(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_EVENT + i, its_payload); + count++; + } + std::this_thread::sleep_for(MESSAGE_SENDER_INTERVAL); + for (uint16_t i = 0; i < TEST_EVENT_NUMBER; i++) { + _app->notify(MEMORY_SERVICE, MEMORY_INSTANCE, MEMORY_EVENT + i, its_payload2); + count++; + } + std::this_thread::sleep_for(MESSAGE_SENDER_INTERVAL); + } + stop_checking_ = true; + VSOMEIP_INFO << "sent " << count << " messages"; +} + +// wait for the start message, run the threads to send messages +// and receive the stop message in the end +void memory_test_service::setup_app(const std::function executionHandler_) +{ + std::unique_lock lk(start_mutex); + if (condition_wait_start.wait_for(lk, WAIT_START_MESSAGE, + [=] { return received_message; })) { + + // If executionHandler_ is set / not nullptr + if (executionHandler_) { + // run send the messages + executionHandler_(); + } + + { + // 3. Wait for client to send stop message + std::unique_lock lk(stop_mutex); + condition_wait_stop.wait_for(lk, WAIT_STOP_MESSAGE); + std::cout << "service: exiting" << std::endl; + } + } +} + +TEST(memory_test, send_messages) +{ + + // Test steps: + // 1: Start measuring memory load + // 2: After receiving start message from the client, start sending + // notifications (load bigger than 1392 bytes) for each event + // TP + // 3: Wait for client stop message + // 4: Stop measuring load and evaluate load increase + // + // At the end evaluate if the threshold of 5% increase in memory load was not surpassed + + memory_test_service its_service("memory_test_service", "MTS"); + std::atomic stop_checking { false }; + + std::thread memory_checker_thread; + + // 1. Measure load until stop_checking is triggered + its_service.setup_app([&] { + memory_checker_thread = std::thread([&stop_checking] { + std::vector test_memory_array; + std::uint64_t sum { 0 }; + + check_memory(test_memory_array, stop_checking); + + for (auto memory_stat : test_memory_array) { + sum += memory_stat; + VSOMEIP_INFO << memory_stat; + } + double memory_average = static_cast(sum) / static_cast(test_memory_array.size()); + VSOMEIP_INFO << memory_average; + + // 4. Evaluate memory load increase + for (auto memory_stat : test_memory_array) { + EXPECT_LT(static_cast(memory_stat), + (static_cast(memory_average) * MEMORY_LOAD_LIMIT)) + << "memory not lesser than " + << (static_cast(memory_average) * MEMORY_LOAD_LIMIT); + } + }); + // 2. Start sending notifications + its_service.message_sender(stop_checking); + }); + + if (memory_checker_thread.joinable()) { + memory_checker_thread.join(); + } +} +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/memory_tests/memory_test_service.hpp b/test/network_tests/memory_tests/memory_test_service.hpp new file mode 100644 index 000000000..2c70e33a3 --- /dev/null +++ b/test/network_tests/memory_tests/memory_test_service.hpp @@ -0,0 +1,40 @@ +// Copyright (C) 2024 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 MEMORY_TEST_SERVICE_HPP_ +#define MEMORY_TEST_SERVICE_HPP_ + +#include +#include +#include +#include + +#include + +#include +#include + +#include "memory_test_common.hpp" + +class memory_test_service : public vsomeip_utilities::base_vsip_app +{ +public: + memory_test_service(const char *app_name_, const char *app_id_); + void setup_app(const std::function executionHandler_); + void message_sender(std::atomic &stop_checking_); + +private: + std::condition_variable condition_wait_start; + std::condition_variable condition_wait_stop; + std::mutex start_mutex; + std::mutex stop_mutex; + bool received_message { false }; + + void on_start(const std::shared_ptr /*&_message*/); + void on_stop(const std::shared_ptr /*&_message*/); +}; +void check_memory(std::vector &test_memory_); + +#endif // MEMORY_TEST_SERVICE_HPP_ diff --git a/test/network_tests/npdu_tests/CMakeLists.txt b/test/network_tests/npdu_tests/CMakeLists.txt new file mode 100644 index 000000000..6bf2047d3 --- /dev/null +++ b/test/network_tests/npdu_tests/CMakeLists.txt @@ -0,0 +1,139 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(npdu_tests LANGUAGES CXX) + +if(NOT TESTS_BAT AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "QNX") + + # Configure necessary files into the build folder. + set(configuration_files + npdu_test_client_no_npdu.json + npdu_test_client_no_npdu_start.sh + npdu_test_client_npdu.json + npdu_test_client_npdu_start.sh + npdu_test_service_no_npdu.json + npdu_test_service_no_npdu_start.sh + npdu_test_service_npdu.json + npdu_test_service_npdu_start.sh + npdu_test_starter.sh + ) + configure_files("${configuration_files}") + + # Routing managers. + + # Add test executable. + add_executable(npdu_test_rmd_client_side + npdu_test_rmd.cpp + ) + set_target_properties(npdu_test_rmd_client_side + PROPERTIES COMPILE_FLAGS -DRMD_CLIENT_SIDE + ) + + # Add test executable. + add_executable(npdu_test_rmd_service_side + npdu_test_rmd.cpp + ) + set_target_properties(npdu_test_rmd_service_side + PROPERTIES COMPILE_FLAGS -DRMD_SERVICE_SIDE + ) + + # Add build dependencies and link libraries to executables. + set(routing_managers + npdu_test_rmd_client_side + npdu_test_rmd_service_side + ) + targets_add_default_dependencies("${routing_managers}") + targets_link_default_libraries("${routing_managers}") + + # Clients and Services. + + # Add test executable. + add_executable(npdu_test_service_1 + npdu_test_service.cpp + ) + set_target_properties(npdu_test_service_1 + PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=0 + ) + + # Add test executable. + add_executable(npdu_test_service_2 + npdu_test_service.cpp + ) + set_target_properties(npdu_test_service_2 + PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=1 + ) + + # Add test executable. + add_executable(npdu_test_service_3 + npdu_test_service.cpp + ) + set_target_properties(npdu_test_service_3 + PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=2 + ) + + # Add test executable. + add_executable(npdu_test_service_4 + npdu_test_service.cpp + ) + set_target_properties(npdu_test_service_4 + PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=3 + ) + + # Add test executable. + add_executable(npdu_test_client_1 + npdu_test_client.cpp + ) + + # Add test executable. + add_executable(npdu_test_client_2 + npdu_test_client.cpp + ) + + # Add test executable. + add_executable(npdu_test_client_3 + npdu_test_client.cpp + ) + + # Add test executable. + add_executable(npdu_test_client_4 + npdu_test_client.cpp + ) + + # Add build dependencies and link libraries to executables. + set(executables + npdu_test_service_1 + npdu_test_service_2 + npdu_test_service_3 + npdu_test_service_4 + npdu_test_client_1 + npdu_test_client_2 + npdu_test_client_3 + npdu_test_client_4 + ) + targets_add_default_dependencies("${executables}") + targets_link_default_libraries("${executables}") + + # Link executables to vsomeip-cfg. + foreach(target ${executables}) + target_link_libraries(${target} ${VSOMEIP_NAME}-cfg) + endforeach() + + # Add custom test command. + add_custom_test( + NAME npdu_test_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/npdu_test_starter.sh UDP sync + TIMEOUT 840 + ) + + # Add custom test command. + add_custom_test( + NAME npdu_test_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/npdu_test_starter.sh TCP sync + TIMEOUT 840 + ) + +endif() diff --git a/test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh b/test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu_start.sh.in similarity index 100% rename from test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh rename to test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu_start.sh.in diff --git a/test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh b/test/network_tests/npdu_tests/conf/npdu_test_client_npdu_start.sh.in similarity index 100% rename from test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh rename to test/network_tests/npdu_tests/conf/npdu_test_client_npdu_start.sh.in diff --git a/test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh b/test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu_start.sh.in similarity index 100% rename from test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh rename to test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu_start.sh.in diff --git a/test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh b/test/network_tests/npdu_tests/conf/npdu_test_service_npdu_start.sh.in similarity index 100% rename from test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh rename to test/network_tests/npdu_tests/conf/npdu_test_service_npdu_start.sh.in diff --git a/test/network_tests/npdu_tests/npdu_test_starter.sh b/test/network_tests/npdu_tests/conf/npdu_test_starter.sh.in similarity index 97% rename from test/network_tests/npdu_tests/npdu_test_starter.sh rename to test/network_tests/npdu_tests/conf/npdu_test_starter.sh.in index 51904c9ed..b6aa490b5 100755 --- a/test/network_tests/npdu_tests/npdu_test_starter.sh +++ b/test/network_tests/npdu_tests/conf/npdu_test_starter.sh.in @@ -71,7 +71,7 @@ start_services if [ ! -z "$USE_LXC_TEST" ]; then echo "starting magic cookies test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./npdu_test_client_npdu_start.sh $*\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/npdu_tests; ./npdu_test_client_npdu_start.sh $*\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./npdu_test_client_npdu_start.sh $*" & else diff --git a/test/network_tests/npdu_tests/npdu_test_client.cpp b/test/network_tests/npdu_tests/npdu_test_client.cpp index 08c6dbb41..cba54f281 100644 --- a/test/network_tests/npdu_tests/npdu_test_client.cpp +++ b/test/network_tests/npdu_tests/npdu_test_client.cpp @@ -2,6 +2,9 @@ // 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 "../npdu_tests/npdu_test_client.hpp" #include diff --git a/test/network_tests/npdu_tests/npdu_test_service.cpp b/test/network_tests/npdu_tests/npdu_test_service.cpp index 5fdc87dc4..3b13802a5 100644 --- a/test/network_tests/npdu_tests/npdu_test_service.cpp +++ b/test/network_tests/npdu_tests/npdu_test_service.cpp @@ -3,6 +3,8 @@ // 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 "../npdu_tests/npdu_test_service.hpp" #include "../npdu_tests/npdu_test_globals.hpp" diff --git a/test/network_tests/offer_stop_offer_test/CMakeLists.txt b/test/network_tests/offer_stop_offer_test/CMakeLists.txt new file mode 100644 index 000000000..716eb2225 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright (C) 2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) +if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "QNX") +# Configure necessary files into the build folder. +set(configuration_files + offer_stop_offer_test_client.json + offer_stop_offer_test_client_starter.sh + offer_stop_offer_test_service.json + offer_stop_offer_test_service_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(offer_stop_offer_test_client + offer_stop_offer_test_client.cpp + applications/client.cpp +) + +# Add test executable. +add_executable(offer_stop_offer_test_service + offer_stop_offer_test_service.cpp + applications/service.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + offer_stop_offer_test_client + offer_stop_offer_test_service +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME offer_stop_offer_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/offer_stop_offer_test_client_starter.sh + TIMEOUT 30 +) +endif() diff --git a/test/network_tests/offer_stop_offer_test/applications/client.cpp b/test/network_tests/offer_stop_offer_test/applications/client.cpp new file mode 100644 index 000000000..d31f067c2 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/applications/client.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2024 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 "client.hpp" +#include "service_ids.hpp" + +client_t::client_t() : + vsomeip_utilities::base_logger("CLI", "VSOMEIP SERVICE CONSUMER"), + vsomeip_app(vsomeip::runtime::get()->create_application("client-sample")) { + + availability_table[SERVICE_ID] = false; + availability_table[OTHER_SERVICE_ID] = false; +} + +client_t::~client_t() { + stop(); +} + +bool client_t::init() { + if (!vsomeip_app->init()) { + VSOMEIP_ERROR << "Couldn't initialize application"; + return false; + } + + vsomeip_app->register_message_handler( + SERVICE_ID, INSTANCE_ID, METHOD_ID, + std::bind(&client_t::on_message, this, std::placeholders::_1)); + vsomeip_app->register_message_handler( + OTHER_SERVICE_ID, OTHER_INSTANCE_ID, OTHER_METHOD_ID, + std::bind(&client_t::on_message, this, std::placeholders::_1)); + vsomeip_app->request_service(SERVICE_ID, INSTANCE_ID); + + vsomeip_app->register_availability_handler( + SERVICE_ID, INSTANCE_ID, + std::bind(&client_t::on_availability, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); + vsomeip_app->register_availability_handler( + OTHER_SERVICE_ID, OTHER_INSTANCE_ID, + std::bind(&client_t::on_availability, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); + vsomeip_app->request_service(OTHER_SERVICE_ID, OTHER_INSTANCE_ID); + + return true; +} + +void client_t::start() { + worker = std::thread([&] { vsomeip_app->start(); }); +} + +void client_t::stop() { + vsomeip_app->stop(); + if (worker.joinable()) { + worker.join(); + } +} + +std::future client_t::request(bool is_tcp, vsomeip::service_t service, + vsomeip::instance_t instance, vsomeip::method_t method) { + auto promise_response = std::promise(); + auto future_response = std::future(promise_response.get_future()); + + std::lock_guard lk(availability_mutex); + if (availability_table[service]) { + auto request = vsomeip::runtime::get()->create_request(is_tcp); + + request->set_service(service); + request->set_instance(instance); + request->set_method(method); + + // store the pending request, so that we can set the promise later in on_message + pending_requests.push_back({service, instance, method, std::move(promise_response)}); + vsomeip_app->send(request); + + } else { + // set the value to false to notify the future that the request was not sent + promise_response.set_value(false); + } + + return future_response; +} + +bool client_t::is_available() { + std::lock_guard lk(availability_mutex); + + for (const auto& availability_entry : availability_table) { + if (!availability_entry.second) { + return false; + } + } + return true; +} + +void client_t::on_message(const std::shared_ptr& message) { + std::lock_guard lk(availability_mutex); + + if (message->get_payload()->get_data()) { + VSOMEIP_INFO << "client_t::" << __func__ << ": " + << static_cast(message->get_payload()->get_data()[0]) << " from 0x" + << std::setw(4) << std::setfill('0') << std::hex << message->get_service(); + } else { + VSOMEIP_WARNING << "client_t::" << __func__ << ": Empty payload for service " + << " from 0x" << std::setw(4) << std::setfill('0') << std::hex + << message->get_service(); + } + + for (auto it = pending_requests.begin(); it != pending_requests.end(); ++it) { + if (it->service == message->get_service() && it->instance == message->get_instance() + && it->method == message->get_method()) { + // set promise true as request was received and remove the pending_response + it->promise_response.set_value(true); + pending_requests.erase(it); + break; + } + } +} + +void client_t::on_availability(vsomeip::service_t service, vsomeip::instance_t instance, + bool is_available) { + std::lock_guard lk(availability_mutex); + + VSOMEIP_INFO << "client_t::" << __func__ << " Service [" << std::setw(4) << std::setfill('0') + << std::hex << service << "." << instance << "] is " + << (is_available ? "available." : "NOT available."); + + availability_table[service] = is_available; + + // Service became unavailable -> set unblock futures + if (!is_available) { + pending_requests.erase(std::remove_if(pending_requests.begin(), pending_requests.end(), + [&](client_request_t& request) { + bool should_remove = (request.service == service) + && (request.instance == instance); + if (should_remove) { + request.promise_response.set_value(true); + } + return should_remove; + }), + pending_requests.end()); + } +} diff --git a/test/network_tests/offer_stop_offer_test/applications/client.hpp b/test/network_tests/offer_stop_offer_test/applications/client.hpp new file mode 100644 index 000000000..f11e81417 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/applications/client.hpp @@ -0,0 +1,104 @@ +// Copyright (C) 2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_CLIENT_HPP +#define VSOMEIP_CLIENT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/// @brief Wrapper for a vsomeip application that requests 2 services with a GET method +class client_t : public vsomeip_utilities::base_logger { +public: + /// @brief Initializes vsomeip application and availability table + client_t(); + + /// @brief Stops vsomeip application + ~client_t(); + + /// @brief Initializes vsomeip application and registers message and availability handlers + /// Also requests services. + /// + /// @return true if vsomeip->init() was successful + bool init(); + void start(); + void stop(); + + /// @brief Sends a someip request to the specified service. Will associate a promise with the + /// request, to later notify a future of the reception of its response. + /// + /// @param is_tcp If true the request will be sent via TCP. UDP will be used otherwise. + /// @param service Service to send the request to. + /// @param instance Instance to send the request to. + /// @param method Method to send the request to. + /// + /// @return returns a future that will notify that responde to this requests was received + std::future request(bool is_tcp, vsomeip::service_t service, + vsomeip::instance_t instance, + vsomeip::method_t method); + + /// @brief Check if both services are available + /// + /// @return true if both services are available; false if one or both were not available. + bool is_available(); + +private: + /// @brief handler for receiving responses. Will set the promise value of the received service. + /// + /// @param message Request message received + void on_message(const std::shared_ptr& message); + + /// @brief handler for services availability. + /// + /// @param service Service that had its availability state changed + /// @param instance Instance that had its availability state changed + /// @param is_available New availability state + void on_availability(vsomeip::service_t service, vsomeip::instance_t instance, + bool is_available); + + /// @brief vsomeip app interface + std::shared_ptr vsomeip_app; + + /// @brief availability table containing the availability state of both services + std::map availability_table; + + /// @brief availability table mutex + std::mutex availability_mutex; + + /// @brief background thread that will serve as context for the vsomeip application + std::thread worker; + + /// @brief Struct to hold the information of requests awaiting reponses + struct client_request_t { + /// @brief Request service + vsomeip::service_t service; + + /// @brief Request instance + vsomeip::instance_t instance; + + /// @brief Request method + vsomeip::method_t method; + + /// @brief promise which value shall be set once the response is received + std::promise promise_response; + }; + + /// @brief List to hold the current client_request_t awaiting responses. + /// client_request_t are removed after the response is received and promise is set. + std::list pending_requests; + +}; + +#endif // VSOMEIP_CLIENT_HPP diff --git a/test/network_tests/offer_stop_offer_test/applications/service.cpp b/test/network_tests/offer_stop_offer_test/applications/service.cpp new file mode 100644 index 000000000..1c6bac005 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/applications/service.cpp @@ -0,0 +1,138 @@ +// Copyright (C) 2024 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 "service.hpp" +#include "service_ids.hpp" + +constexpr std::size_t PAYLOAD_SIZE = 1000UL; + +service_t::service_t() : + vsomeip_utilities::base_logger("SRV", "VSOMEIP SERVICE PROVIDER"), + vsomeip_app(vsomeip::runtime::get()->create_application("service-sample")), + payload(std::vector(PAYLOAD_SIZE, 0)) { + + availability_table[SERVICE_ID] = false; + availability_table[OTHER_SERVICE_ID] = false; +} + +service_t::~service_t() { + stop(); +} + +bool service_t::init() { + if (!vsomeip_app->init()) { + VSOMEIP_ERROR << "Couldn't initialize application" << std::endl; + return false; + } + + vsomeip_app->register_message_handler( + SERVICE_ID, INSTANCE_ID, METHOD_ID, + std::bind(&service_t::on_message, this, std::placeholders::_1)); + vsomeip_app->register_message_handler( + OTHER_SERVICE_ID, OTHER_INSTANCE_ID, OTHER_METHOD_ID, + std::bind(&service_t::on_message, this, std::placeholders::_1)); + + vsomeip_app->register_availability_handler( + SERVICE_ID, INSTANCE_ID, + std::bind(&service_t::on_availability, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); + vsomeip_app->register_availability_handler( + OTHER_SERVICE_ID, OTHER_INSTANCE_ID, + std::bind(&service_t::on_availability, this, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3)); + + vsomeip_app->offer_event(SERVICE_ID, INSTANCE_ID, EVENT_ID, {EVENTGROUP_ID}, + vsomeip::event_type_e::ET_FIELD); + vsomeip_app->offer_event(OTHER_SERVICE_ID, OTHER_INSTANCE_ID, EVENT_ID, {EVENTGROUP_ID}, + vsomeip::event_type_e::ET_FIELD); + + vsomeip_app->request_service(SERVICE_ID, INSTANCE_ID); + vsomeip_app->request_service(OTHER_SERVICE_ID, OTHER_INSTANCE_ID); + + return true; +} + +void service_t::start() { + worker = std::thread([&] { vsomeip_app->start(); }); +} + +void service_t::stop() { + vsomeip_app->stop(); + if (worker.joinable()) { + worker.join(); + } +} + +std::future service_t::offer() { + // Lock the entire function to not allow the on_availability callback to interfier while the + // offer is being created + std::lock_guard lk(availability_mutex); + + VSOMEIP_INFO << "service_t::" << __func__; + vsomeip_app->offer_service(SERVICE_ID, INSTANCE_ID, 0, 0); + vsomeip_app->offer_service(OTHER_SERVICE_ID, OTHER_INSTANCE_ID, 0, 0); + + promise_availability = std::promise(); + auto future_availability = std::future(promise_availability.get_future()); + + is_offering = true; + return future_availability; +} + +std::future service_t::stop_offer() { + // Lock the entire function to not allow the on_availability callback to interfier while the + // offer is being created + std::lock_guard lk(availability_mutex); + + VSOMEIP_INFO << "service_t::" << __func__; + vsomeip_app->stop_offer_service(SERVICE_ID, INSTANCE_ID, 0, 0); + vsomeip_app->stop_offer_service(OTHER_SERVICE_ID, OTHER_INSTANCE_ID, 0, 0); + + promise_availability = std::promise(); + auto future_availability = std::future(promise_availability.get_future()); + + is_offering = false; + return future_availability; +} + +void service_t::on_message(const std::shared_ptr& message) { + std::lock_guard lk(availability_mutex); + + payload.at(0)++; + VSOMEIP_INFO << "service_t::" << __func__ << ": [" << std::hex << message->get_service() << "] " + << static_cast(payload.at(0)); + + auto vsomeip_payload = vsomeip::runtime::get()->create_payload(payload); + auto its_response = vsomeip::runtime::get()->create_response(message); + its_response->set_payload(vsomeip_payload); + + vsomeip_app->send(its_response); +} + +void service_t::on_availability(vsomeip::service_t service, vsomeip::instance_t instance, + bool is_available) { + std::lock_guard lk(availability_mutex); + + VSOMEIP_INFO << "service_t::" << __func__ << " Service [" << std::setw(4) << std::setfill('0') + << std::hex << service << "." << instance << "] is " + << (is_available ? "available." : "NOT available."); + + availability_table[service] = is_available; + + // check if all services are in the same state of is_offering + bool all_availabilities_confirmed = true; + for (const auto& availability_entry : availability_table) { + if (availability_entry.second != is_offering) { + all_availabilities_confirmed = false; + } + } + if (all_availabilities_confirmed) { + // If all services are -> set promise + promise_availability.set_value(is_offering); + } +} diff --git a/test/network_tests/offer_stop_offer_test/applications/service.hpp b/test/network_tests/offer_stop_offer_test/applications/service.hpp new file mode 100644 index 000000000..2802959aa --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/applications/service.hpp @@ -0,0 +1,89 @@ +// Copyright (C) 2024 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_SERVICE_HPP +#define VSOMEIP_SERVICE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/// @brief Wrapper for a vsomeip application that offers 2 services with a GET method +class service_t : public vsomeip_utilities::base_logger { +public: + /// @brief Initializes vsomeip application and availability table + service_t(); + + /// @brief Stops vsomeip application + ~service_t(); + + /// @brief Initializes vsomeip application and registers message and availability handlers + /// Also requests own services to force the routing manager to offer them. + /// + /// @return true if vsomeip->init() was successful + bool init(); + + /// @brief Starts vsomeip application on a background thread. Non blocking call. + void start(); + + /// @brief Stops vsomeip application + void stop(); + + /// @brief Offers both services + /// + /// @return returns a future that will notify that the availability to this service was changed + std::future offer(); + + /// @brief Stops offering both services + /// + /// @return returns a future that will notify that the availability to this service was changed + std::future stop_offer(); + +private: + /// @brief handler for receiving requests. Will send a response back with a big payload and a + /// changing first byte + /// + /// @param message Request message received + void on_message(const std::shared_ptr& message); + + /// @brief handler for services availability. + /// + /// @param service Service that had its availability state changed + /// @param instance Instance that had its availability state changed + /// @param is_available New availability state + void on_availability(vsomeip::service_t service, vsomeip::instance_t instance, + bool is_available); + + /// @brief vsomeip app interface + std::shared_ptr vsomeip_app; + + /// @brief payload sent in the responde of the requests + std::vector payload; + + /// @brief availability table containing the availability state of both services + std::map availability_table; + /// @brief availability table mutex + std::mutex availability_mutex; + + /// @brief background thread that will serve as context for the vsomeip application + std::thread worker; + + /// @brief application offer state for both services. + bool is_offering; + + /// @brief promise which value shall be set once the availability is received + std::promise promise_availability; +}; + +#endif // VSOMEIP_SERVICE_HPP diff --git a/test/network_tests/offer_stop_offer_test/applications/service_ids.hpp b/test/network_tests/offer_stop_offer_test/applications/service_ids.hpp new file mode 100644 index 000000000..0a44b76e7 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/applications/service_ids.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2024 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_SERVICE_IDS_HPP +#define VSOMEIP_SERVICE_IDS_HPP + +#include + +/// @brief First service id +constexpr vsomeip::service_t SERVICE_ID = 0x1234; + +/// @brief First service instance id +constexpr vsomeip::instance_t INSTANCE_ID = 0x5678; + +/// @brief First service method id +constexpr vsomeip::method_t METHOD_ID = 0x0421; + +/// @brief Second service id +constexpr vsomeip::service_t OTHER_SERVICE_ID = 0x1235; + +/// @brief Second service instance id +constexpr vsomeip::instance_t OTHER_INSTANCE_ID = 0x5678; + +/// @brief Second service method id +constexpr vsomeip::method_t OTHER_METHOD_ID = 0x0421; + +/// @brief Both services event id +constexpr vsomeip::event_t EVENT_ID = 0x8778; + +/// @brief Both services eventgroup id +constexpr vsomeip::eventgroup_t EVENTGROUP_ID = 0x4465; + + +#endif // VSOMEIP_EXAMPLES_IDS_HPP diff --git a/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_client.json.in b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_client.json.in new file mode 100644 index 000000000..da44753c0 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_client.json.in @@ -0,0 +1,32 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging" : + { + "level" : "debug", + "console" : "true", + "dlt" : "true" + }, + "applications" : + [ + { + "name" : "client-sample", + "id" : "0x1343" + } + ], + "clients" : + [ + { + "reliable_remote_ports" : { "first" : "30501", "last" : "30506" }, + "reliable_client_ports" : { "first" : "30491", "last" : "30493" } + } + ], + "routing" : "client-sample", + "service-discovery": + { + "enable": "true", + "multicast": "224.244.224.245", + "port": "30490", + "protocol": "udp", + "cyclic_offer_delay": "1000" + } +} diff --git a/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_client_starter.sh.in b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_client_starter.sh.in new file mode 100755 index 000000000..ee6676de0 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_client_starter.sh.in @@ -0,0 +1,19 @@ +#!/bin/bash +# Copyright (C) 2024 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/. + +FAIL=0 + +# call other container +if [ ! -z "$USE_LXC_TEST" ]; then + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/offer_stop_offer_test; ./offer_stop_offer_test_service_starter.sh\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./offer_stop_offer_test_service_starter.sh" & +fi + +# start client +export VSOMEIP_CONFIGURATION=offer_stop_offer_test_client.json +export VSOMEIP_APPLICATION_NAME="client-sample" +./offer_stop_offer_test_client diff --git a/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_service.json.in b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_service.json.in new file mode 100644 index 000000000..88386277b --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_service.json.in @@ -0,0 +1,73 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "logging" : + { + "level" : "debug", + "console" : "true", + "dlt" : "true" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277" + }, + { + "name" : "routingmanagerd", + "id" : "0x1200" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "reliable" : "30506", + "events" : + [ + { + "event" : "0x8778", + "is_field" : "true" + } + ], + "eventgroups" : + [ + { + "eventgroup" : "0x4465", + "events" : [ "0x8778" ] + + } + ] + }, + { + "service" : "0x1235", + "instance" : "0x5678", + "reliable" : "30506", + "unreliable" : "30506", + "events" : + [ + { + "event" : "0x8778", + "is_field" : "true" + } + ], + "eventgroups" : + [ + { + "eventgroup" : "0x4465", + "events" : [ "0x8778" ] + + } + ] + } + ], + "routing" : "routingmanagerd", + "service-discovery": + { + "enable": "true", + "multicast": "224.244.224.245", + "port": "30490", + "protocol": "udp", + "cyclic_offer_delay": "1000" + } +} diff --git a/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_service_starter.sh.in b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_service_starter.sh.in new file mode 100755 index 000000000..451613e83 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/conf/offer_stop_offer_test_service_starter.sh.in @@ -0,0 +1,20 @@ +#!/bin/bash +# Copyright (C) 2024 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/. + +# start routing host +export VSOMEIP_CONFIGURATION=offer_stop_offer_test_service.json +export VSOMEIP_APPLICATION_NAME="routingmanagerd" +../../../examples/routingmanagerd/routingmanagerd & + +HOST_PID=$! + +# start service app +export VSOMEIP_CONFIGURATION=offer_stop_offer_test_service.json +export VSOMEIP_APPLICATION_NAME="service-sample" + +./offer_stop_offer_test_service + +kill -9 $HOST_PID diff --git a/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_client.cpp b/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_client.cpp new file mode 100644 index 000000000..b5df59ff9 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_client.cpp @@ -0,0 +1,82 @@ +// Copyright (C) 2024 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 "applications/client.hpp" +#include "applications/service_ids.hpp" +#include "offer_stop_offer_test_helper.hpp" + +TEST(test_offer_stop_offer, test_offer_stop_offer_client) { + // Precondition 1: Service consumer application initializes correctly + client_t service_consumer; + + ASSERT_TRUE(service_consumer.init()); + service_consumer.start(); + + // Test steps: + // > If service is available: + // 1: send 3 request messages (service_1 via tcp, service_2 via tcp, service_3 via udp) + // 2: validate that the requests were sent + // 3: validate that the response was received + // + // *Note_1: The value of the future itself is not relavant, only that is was set + // *Note_2: There can be the situation where the service goes unavailable while the + // requests are being sent. In that case the future is set either way, so we don't + // need to worry here in the test. + // + // > If service is not available + // 1: do nothing + // + // At the end validate that the service was available, atleast once + test_timer_t test_timer(CLIENT_UP_TIME); + bool service_was_available = false; + bool request_was_received = false; + while (!test_timer.has_elapsed()) { + if (service_consumer.is_available()) { + service_was_available = true; + + auto request_service1_tcp = + service_consumer.request(true, SERVICE_ID, INSTANCE_ID, METHOD_ID); + auto request_service2_tcp = + service_consumer.request(true, OTHER_SERVICE_ID, OTHER_INSTANCE_ID, METHOD_ID); + auto request_service2_udp = + service_consumer.request(false, OTHER_SERVICE_ID, OTHER_INSTANCE_ID, METHOD_ID); + + // check if futures are valid + ASSERT_TRUE(request_service1_tcp.valid()); + ASSERT_TRUE(request_service2_tcp.valid()); + ASSERT_TRUE(request_service2_udp.valid()); + + // wait for responses + request_service1_tcp.wait(); + request_service2_tcp.wait(); + request_service2_udp.wait(); + + request_was_received = true; + } + } + + // to not get mislead if the service was never up + EXPECT_TRUE(service_was_available); + // to not get mislead if the request was never received + EXPECT_TRUE(request_was_received); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_helper.hpp b/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_helper.hpp new file mode 100644 index 000000000..33474c423 --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_helper.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2024 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 TEST_OFFER_STOP_OFFER_HELPER_HPP +#define TEST_OFFER_STOP_OFFER_HELPER_HPP + +#include + +/// @brief Time for which the service application is active +constexpr auto SERVICE_UP_TIME = std::chrono::seconds(9); + +/// @brief Time for which the service application is offering the services and responding to +/// requests +constexpr auto SERVICE_OFFER_TIME = std::chrono::milliseconds(500); + +/// @brief Time for which the service application stops offering the services +constexpr auto SERVICE_STOP_OFFER_TIME = std::chrono::milliseconds(2); + +/// @brief Time for which the client application is active +constexpr auto CLIENT_UP_TIME = std::chrono::seconds(10); + +#endif // TEST_OFFER_STOP_OFFER_HELPER_HPP diff --git a/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_service.cpp b/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_service.cpp new file mode 100644 index 000000000..0b4ac043c --- /dev/null +++ b/test/network_tests/offer_stop_offer_test/offer_stop_offer_test_service.cpp @@ -0,0 +1,66 @@ +// Copyright (C) 2024 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 "applications/service.hpp" +#include "offer_stop_offer_test_helper.hpp" + +TEST(test_offer_stop_offer, test_offer_stop_offer_service) { + // Precondition 1: Service provider application initializes correctly + service_t service_provider; + + ASSERT_TRUE(service_provider.init()); + service_provider.start(); + + // Precondition 2: routingmanagerd is able to route + auto routing_availability_check = service_provider.offer(); + ASSERT_TRUE(routing_availability_check.valid()); + routing_availability_check.wait(); + ASSERT_TRUE(routing_availability_check.get()) << "routingmanagerd was not ready in time!"; + + test_timer_t test_timer(SERVICE_UP_TIME); + + // Test steps: + // 1: STOP_OFFERING the services for SERVICE_STOP_OFFER_TIME + // 2: validate that the services are not available + // 3: OFFER the services again + // 4: validate that the services are available + // Repeate above steps for SERVICE_UP_TIME + while (!test_timer.has_elapsed()) { + + auto stop_offer_confirmation = service_provider.stop_offer(); + // Wait confirmation that all services have became unavailable + ASSERT_TRUE(stop_offer_confirmation.valid()); + stop_offer_confirmation.wait(); + ASSERT_FALSE(stop_offer_confirmation.get()) << "stop_offer was not confirmed in time!"; + + std::this_thread::sleep_for(SERVICE_STOP_OFFER_TIME); + + auto offer_confirmation = service_provider.offer(); + // Wait confirmation that all services have became available + ASSERT_TRUE(offer_confirmation.valid()); + offer_confirmation.wait(); + ASSERT_TRUE(offer_confirmation.get()) << "offer was not confirmed in time!"; + + std::this_thread::sleep_for(SERVICE_OFFER_TIME); + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/offer_tests/CMakeLists.txt b/test/network_tests/offer_tests/CMakeLists.txt new file mode 100644 index 000000000..67ff1e7d9 --- /dev/null +++ b/test/network_tests/offer_tests/CMakeLists.txt @@ -0,0 +1,101 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(offer_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + offer_test_big_sd_msg_master.json + offer_test_big_sd_msg_master_starter.sh + offer_test_big_sd_msg_slave.json + offer_test_big_sd_msg_slave_starter.sh + offer_test_external_master.json + offer_test_external_master_starter.sh + offer_test_external_slave.json + offer_test_external_slave_starter.sh + offer_test_local.json + offer_test_local_starter.sh + offer_test_multiple_offerings.json + offer_test_multiple_offerings_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(offer_test_service + offer_test_service.cpp +) + +# Add test executable. +add_executable(offer_test_multiple_offerings + offer_test_multiple_offerings.cpp +) + +# Add test executable. +add_executable(offer_test_client + offer_test_client.cpp +) + +# Add test executable. +add_executable(offer_test_service_external + offer_test_service_external.cpp +) + +# Add test executable. +add_executable(offer_test_external_sd_msg_sender + offer_test_external_sd_msg_sender.cpp +) + +# Add test executable. +add_executable(offer_test_big_sd_msg_service + offer_test_big_sd_msg_service.cpp +) + +# Add test executable. +add_executable(offer_test_big_sd_msg_client + offer_test_big_sd_msg_client.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + offer_test_service + offer_test_multiple_offerings + offer_test_client + offer_test_service_external + offer_test_external_sd_msg_sender + offer_test_big_sd_msg_service + offer_test_big_sd_msg_client +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME offer_test_local + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/offer_test_local_starter.sh + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME offer_test_external + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/offer_test_external_master_starter.sh + TIMEOUT 360 +) + +# Add custom test command. +add_custom_test( + NAME offer_test_big_sd_msg + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/offer_test_big_sd_msg_master_starter.sh + TIMEOUT 360 +) + +# Add custom test command. +add_custom_test( + NAME offer_test_multiple_offerings + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/offer_test_multiple_offerings_starter.sh + TIMEOUT 1800 +) diff --git a/test/network_tests/offer_tests/conf/offer_test_big_sd_msg_master_starter.sh.in b/test/network_tests/offer_tests/conf/offer_test_big_sd_msg_master_starter.sh.in index 9ef516316..e934238b3 100755 --- a/test/network_tests/offer_tests/conf/offer_test_big_sd_msg_master_starter.sh.in +++ b/test/network_tests/offer_tests/conf/offer_test_big_sd_msg_master_starter.sh.in @@ -14,7 +14,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=offer_test_big_sd_msg_master.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! ./offer_test_big_sd_msg_client & @@ -27,7 +27,7 @@ if [ ! -z "$USE_LXC_TEST" ]; then echo "Waiting for 5s" sleep 5 echo "starting offer test on slave LXC offer_test_big_sd_msg_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./offer_test_big_sd_msg_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/offer_tests; ./offer_test_big_sd_msg_slave_starter.sh\"" & echo "remote ssh pid: $!" elif [ ! -z "$USE_DOCKER" ]; then echo "Waiting for 5s" diff --git a/test/network_tests/offer_tests/offer_test_big_sd_msg_slave_starter.sh b/test/network_tests/offer_tests/conf/offer_test_big_sd_msg_slave_starter.sh.in similarity index 95% rename from test/network_tests/offer_tests/offer_test_big_sd_msg_slave_starter.sh rename to test/network_tests/offer_tests/conf/offer_test_big_sd_msg_slave_starter.sh.in index 5f69c306d..5587019a8 100755 --- a/test/network_tests/offer_tests/offer_test_big_sd_msg_slave_starter.sh +++ b/test/network_tests/offer_tests/conf/offer_test_big_sd_msg_slave_starter.sh.in @@ -15,7 +15,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=offer_test_big_sd_msg_slave.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 # Start the services diff --git a/test/network_tests/offer_tests/conf/offer_test_external_master_starter.sh.in b/test/network_tests/offer_tests/conf/offer_test_external_master_starter.sh.in index cefdd43d6..4d30a8052 100755 --- a/test/network_tests/offer_tests/conf/offer_test_external_master_starter.sh.in +++ b/test/network_tests/offer_tests/conf/offer_test_external_master_starter.sh.in @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2015-2023 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/. @@ -19,11 +19,9 @@ FAIL=0 # -> should be rejected as there is already a service instance # running in the network -# Array for client pids -CLIENT_PIDS=() export VSOMEIP_CONFIGURATION=offer_test_external_master.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! # Start the services ./offer_test_service 2 & @@ -31,8 +29,8 @@ PID_SERVICE_TWO=$! echo "SERVICE_TWO pid $PID_SERVICE_TWO" ./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) -echo "client pid ${CLIENT_PIDS[0]}" +CLIENT_PID_ONE=$! +echo "client pid ${CLIENT_PIDS}" sleep 1 @@ -40,7 +38,7 @@ if [ ! -z "$USE_LXC_TEST" ]; then echo "Waiting for 5s" sleep 5 echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./offer_test_external_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/offer_tests; ./offer_test_external_slave_starter.sh\"" & echo "remote ssh pid: $!" elif [ ! -z "$USE_DOCKER" ]; then echo "Waiting for 5s" @@ -63,12 +61,10 @@ End-of-message fi # Wait until all clients and services are finished -for job in ${CLIENT_PIDS[*]} $PID_SERVICE_TWO -do - # Fail gets incremented if a client exits with a non-zero exit code - echo "waiting for $job" - wait $job || FAIL=$(($FAIL+1)) -done +# Fail gets incremented if a client exits with a non-zero exit code +echo "waiting for $job" +wait $CLIENT_PID_ONE || FAIL=$(($FAIL+1)) +wait $PID_SERVICE_TWO || FAIL=$(($FAIL+1)) # kill the services kill $PID_VSOMEIPD @@ -88,19 +84,17 @@ done # * send sd message trying to offer the same service instance as already # offered locally from a remote host -# Array for client pids -CLIENT_PIDS=() export VSOMEIP_CONFIGURATION=offer_test_external_master.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! # Start the services ./offer_test_service 2 & PID_SERVICE_TWO=$! ./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) -echo "client pid ${CLIENT_PIDS[0]}" +CLIENT_PID_ONE=$! +echo "client pid ${CLIENT_PID_ONE}" sleep 1 @@ -108,7 +102,7 @@ if [ ! -z "$USE_LXC_TEST" ]; then echo "Waiting for 5s" sleep 5 echo "starting offer test on slave LXC offer_test_external_sd_msg_sender" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./offer_test_external_sd_msg_sender @TEST_IP_MASTER@\"" & + 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/network_tests/offer_tests; ./offer_test_external_sd_msg_sender @TEST_IP_MASTER@\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then echo "Waiting for 5s" @@ -129,12 +123,10 @@ End-of-message fi # Wait until all clients and services are finished -for job in ${CLIENT_PIDS[*]} $PID_SERVICE_TWO -do - # Fail gets incremented if a client exits with a non-zero exit code - echo "waiting for $job" - wait $job || FAIL=$(($FAIL+1)) -done +# Fail gets incremented if a client exits with a non-zero exit code +echo "waiting for $job" +wait $CLIENT_PID_ONE || FAIL=$(($FAIL+1)) +wait $PID_SERVICE_TWO || FAIL=$(($FAIL+1)) # kill the services kill $PID_VSOMEIPD diff --git a/test/network_tests/offer_tests/conf/offer_test_external_master_starter_qnx.sh.in b/test/network_tests/offer_tests/conf/offer_test_external_master_starter_qnx.sh.in deleted file mode 100755 index 43cbafbbe..000000000 --- a/test/network_tests/offer_tests/conf/offer_test_external_master_starter_qnx.sh.in +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -FAIL=0 -# Rejecting offer for which there is already a remote offer: -# * start daemon -# * start application which offers service -# * start daemon remotely -# * start same application which offers the same service again remotely -# -> should be rejected as there is already a service instance -# running in the network - -export VSOMEIP_CONFIGURATION=offer_test_external_master.json -# start daemon -../../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the services -./offer_test_service 2 & -PID_SERVICE_TWO=$! -echo "SERVICE_TWO pid $PID_SERVICE_TWO" - -./offer_test_client SUBSCRIBE & -CLIENT_PID_ONE=$! -echo "client pid ${CLIENT_PIDS}" - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "Waiting for 5s" - sleep 5 - echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./offer_test_external_slave_starter.sh\"" & - echo "remote ssh pid: $!" -elif [ ! -z "$USE_DOCKER" ]; then - echo "Waiting for 5s" - sleep 5 - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./offer_test_external_slave_starter.sh" & -else -cat < should be -# rejected and an error message should be printed. -# * Message exchange with client application should not be interrupted. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# Start the services -./offer_test_service 1 & -PID_SERVICE_ONE=$! -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) - -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_SERVICE_TWO -kill $PID_SERVICE_ONE -sleep 1 - - -cat < should be -# rejected and an error message should be printed. -# * Message exchange with client application should not be interrupted. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -# Start the services -./offer_test_service 2 & -PID_SERVICE_TWO=$! -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) - -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_SERVICE_THREE -kill $PID_SERVICE_TWO -sleep 1 -kill $PID_VSOMEIPD -sleep 1 - - -cat < should be -# accepted. -# * start another client which exchanges messages with the service -# * Client should now communicate with new offerer. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the service -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Start a client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Kill the service -sleep 1 -kill -KILL $PID_SERVICE_TWO - -# reoffer the service -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# Start another client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_SERVICE_THREE -kill $PID_VSOMEIPD -sleep 1 - -cat < should be -# marked as PENDING_OFFER and a ping should be sent to the paused -# application. -# * After the timeout passed the new offer should be accepted. -# * start client which exchanges messages with the service -# * Client should now communicate with new offerer. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the service -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Start a client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Pause the service -sleep 1 -kill -STOP $PID_SERVICE_TWO - -# reoffer the service -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# Start another client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill -CONT $PID_SERVICE_TWO -kill $PID_SERVICE_TWO -kill $PID_SERVICE_THREE -kill $PID_VSOMEIPD -sleep 1 - -cat < should be -# marked as PENDING_OFFER and a ping should be sent to the paused -# application. -# * start application which offers the same service again -> should be -# rejected as there is already a PENDING_OFFER pending. -# * After the timeout passed the new offer should be accepted. -# * start client which exchanges messages with the service -# * Client should now communicate with new offerer. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the service -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Start a client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Pause the service -sleep 1 -kill -STOP $PID_SERVICE_TWO - -# reoffer the service -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# reoffer the service again to provoke rejecting as there is -# already a pending offer -./offer_test_service 4 & -PID_SERVICE_FOUR=$! - -# Start another client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill -CONT $PID_SERVICE_TWO -kill $PID_SERVICE_TWO -kill $PID_SERVICE_THREE -kill $PID_SERVICE_FOUR -kill $PID_VSOMEIPD - - -# Check if everything went well -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/offer_tests/offer_test_multiple_offerings.cpp b/test/network_tests/offer_tests/offer_test_multiple_offerings.cpp index 0c7e0f283..c25e5233b 100644 --- a/test/network_tests/offer_tests/offer_test_multiple_offerings.cpp +++ b/test/network_tests/offer_tests/offer_test_multiple_offerings.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -18,7 +19,6 @@ using namespace vsomeip; using namespace std::chrono_literals; constexpr auto TIMEOUT_RESPONSE = 1000ms; -constexpr auto TIMEOUT_AVAILABILITY = 1000ms; constexpr auto REQUESTS_NUMBER = 10; class common { @@ -34,6 +34,7 @@ class common { std::thread thread_id_; std::condition_variable condition_availability_; std::atomic_bool availability_; + std::atomic_bool msg_sent_; }; void common::on_availability(service_t _service_id, instance_t _instance_id, bool _is_available) { @@ -81,8 +82,8 @@ class client : common { bool was_message_received() { std::unique_lock lock(mutex_); - return condition_message_received_.wait_for(lock, std::chrono::milliseconds(TIMEOUT_AVAILABILITY), - [=] { return message_received_.load(); }); + condition_message_received_.wait(lock, [=] { return message_received_.load(); }); + return message_received_.load(); } std::vector getReceivedPayload() { @@ -92,11 +93,12 @@ class client : common { bool wait_availability() { std::unique_lock lock(mutex_); - return condition_availability_.wait_for(lock, std::chrono::milliseconds(TIMEOUT_AVAILABILITY), - [=] { return availability_.load(); }); + condition_availability_.wait(lock, [=] { return availability_.load(); }); + return availability_.load(); } void send_message(const std::vector& _outgoing_payload) { + msg_sent_.store(false); auto request = runtime::get()->create_request(); request->set_service(service_id_); request->set_instance(instance_id_); @@ -106,7 +108,7 @@ class client : common { app_->send(request); std::unique_lock lock(mutex_); - condition_message_sent_.wait_for(lock, std::chrono::milliseconds(TIMEOUT_AVAILABILITY)); + condition_message_sent_.wait(lock, [=] { return msg_sent_.load(); }); } ~client() { @@ -120,18 +122,30 @@ class client : common { } void on_message(const std::shared_ptr& _message) { - condition_message_sent_.notify_one(); auto its_payload = _message->get_payload(); auto const len = its_payload->get_length(); + std::stringstream msg; { std::lock_guard its_lock(payload_mutex_); received_payload_.clear(); for (uint32_t i = 0; i < len; ++i) { received_payload_.push_back(*(its_payload->get_data() + i)); + msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*(its_payload->get_data() + i)) << " "; } + } + VSOMEIP_INFO << "[TEST] Got message from " + << std::hex << std::setw(4) << std::setfill('0') << _message->get_service() << "." + << std::hex << std::setw(4) << std::setfill('0') << _message->get_instance() + << " length " << std::dec << len << " and payload " << msg.str(); + { + std::lock_guard its_lock(mutex_); + msg_sent_.store(true); + condition_message_sent_.notify_one(); } + + std::lock_guard its_lock(mutex_); if (_message->get_service() == service_id_ && _message->get_instance() == instance_id_) { message_received_.store(true); condition_message_received_.notify_one(); @@ -182,8 +196,8 @@ class server : common { bool wait_availability() { std::unique_lock lock(mutex_); - return condition_availability_.wait_for(lock, std::chrono::milliseconds(TIMEOUT_AVAILABILITY), - [=] { return availability_.load(); }); + condition_availability_.wait(lock, [=] { return availability_.load(); }); + return availability_.load(); } ~server() { @@ -195,12 +209,15 @@ class server : common { void on_message(const std::shared_ptr& _message) { const vsomeip::length_t len = _message->get_payload()->get_length(); std::vector out_payload; + std::stringstream msg; for (uint32_t i = 0; i < len; ++i) { out_payload.push_back(*(_message->get_payload()->get_data() + i)); + msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*(_message->get_payload()->get_data() + i)) << " "; } std::shared_ptr response = runtime::get()->create_response(_message); response->set_payload(vsomeip::runtime::get()->create_payload(out_payload)); + VSOMEIP_INFO << "[TEST] Sending " << msg.str(); app_->send(response); } @@ -244,21 +261,25 @@ TEST(offer_test, multiple_offerings_same_service) server service_1(service_id, instance_id, major, minor); service_1.wait_availability(); + VSOMEIP_INFO << "[TEST] Service 1 is AVAILABLE"; server service_2(service_id, instance_id, major, minor); service_2.wait_availability(); + VSOMEIP_INFO << "[TEST] Service 2 is AVAILABLE"; client client(service_id, instance_id, major, minor); client.wait_availability(); + VSOMEIP_INFO << "[TEST] Client is AVAILABLE"; // Without suspending the deamon, the client immediatly closes. daemon.set_routing_state(routing_state_e::RS_SUSPENDED); for (int i = 0; i < REQUESTS_NUMBER; ++i) { + VSOMEIP_INFO << "[TEST] Sending Loop " << i; // NOTE: Don't remove the sleep. VSOME/IP needs some time until it sends a PONG message to // services. Otherwise we can't detect service availability correctly later. std::this_thread::sleep_for(TIMEOUT_RESPONSE); - std::vector out_payload = { 2 }; + std::vector out_payload = { uint8_t(i) }; client.send_message(out_payload); // Independant of the number of offerings, the client must never fail it's assertions. ASSERT_TRUE(client.was_message_received()) << "Message was not received"; diff --git a/test/network_tests/offered_services_info_tests/CMakeLists.txt b/test/network_tests/offered_services_info_tests/CMakeLists.txt new file mode 100644 index 000000000..ac0621ed2 --- /dev/null +++ b/test/network_tests/offered_services_info_tests/CMakeLists.txt @@ -0,0 +1,40 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(offered_services_info_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + offered_services_info_test_local.json + offered_services_info_test_local_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(offered_services_info_test_service + offered_services_info_test_service.cpp +) + +# Add test executable. +add_executable(offered_services_info_test_client + offered_services_info_test_client.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + offered_services_info_test_service + offered_services_info_test_client +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME offered_services_info_test_local + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/offered_services_info_test_local_starter.sh + TIMEOUT 180 +) diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_local.json b/test/network_tests/offered_services_info_tests/conf/offered_services_info_test_local.json.in similarity index 100% rename from test/network_tests/offered_services_info_test/offered_services_info_test_local.json rename to test/network_tests/offered_services_info_tests/conf/offered_services_info_test_local.json.in diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh b/test/network_tests/offered_services_info_tests/conf/offered_services_info_test_local_starter.sh.in similarity index 100% rename from test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh rename to test/network_tests/offered_services_info_tests/conf/offered_services_info_test_local_starter.sh.in diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_client.cpp b/test/network_tests/offered_services_info_tests/offered_services_info_test_client.cpp similarity index 100% rename from test/network_tests/offered_services_info_test/offered_services_info_test_client.cpp rename to test/network_tests/offered_services_info_tests/offered_services_info_test_client.cpp diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp b/test/network_tests/offered_services_info_tests/offered_services_info_test_globals.hpp similarity index 100% rename from test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp rename to test/network_tests/offered_services_info_tests/offered_services_info_test_globals.hpp diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp b/test/network_tests/offered_services_info_tests/offered_services_info_test_service.cpp similarity index 100% rename from test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp rename to test/network_tests/offered_services_info_tests/offered_services_info_test_service.cpp diff --git a/test/network_tests/payload_tests/CMakeLists.txt b/test/network_tests/payload_tests/CMakeLists.txt new file mode 100644 index 000000000..e305ce6bc --- /dev/null +++ b/test/network_tests/payload_tests/CMakeLists.txt @@ -0,0 +1,81 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(payload_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + external_local_payload_test_client_external.json + external_local_payload_test_client_external_start.sh + external_local_payload_test_client_external_starter.sh + external_local_payload_test_client_local.json + external_local_payload_test_client_local_and_external_starter.sh + external_local_payload_test_client_local_start.sh + external_local_payload_test_client_local_starter.sh + external_local_payload_test_service.json + external_local_payload_test_service_client_external_start.sh + external_local_payload_test_service_start.sh + local_payload_test_client.json + local_payload_test_client_start.sh + local_payload_test_huge_payload_starter.sh + local_payload_test_service.json + local_payload_test_service_start.sh + local_payload_test_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(payload_test_service + payload_test_service.cpp +) + +# Add test executable. +add_executable(payload_test_client + payload_test_client.cpp + stopwatch.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + payload_test_service + payload_test_client +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME local_payload_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/local_payload_test_starter.sh +) + +# Add custom test command. +add_custom_test( + NAME local_payload_test_huge_payload + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/local_payload_test_huge_payload_starter.sh + TIMEOUT 1800 +) + +# Add custom test command. +add_custom_test( + NAME external_local_payload_test_client_local + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/external_local_payload_test_client_local_starter.sh +) + +# Add custom test command. +add_custom_test( + NAME external_local_payload_test_client_external + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/external_local_payload_test_client_external_starter.sh + TIMEOUT 480 +) + +# Add custom test command. +add_custom_test( + NAME external_local_payload_test_client_local_and_external + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/external_local_payload_test_client_local_and_external_starter.sh + TIMEOUT 480 +) diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external_start.sh.in similarity index 100% rename from test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh rename to test/network_tests/payload_tests/conf/external_local_payload_test_client_external_start.sh.in diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external_starter.sh.in similarity index 97% rename from test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh rename to test/network_tests/payload_tests/conf/external_local_payload_test_client_external_starter.sh.in index af044cfde..b0d75abd8 100755 --- a/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external_starter.sh.in @@ -58,7 +58,7 @@ SERIVCE_PID=$! # to finish the test successfully if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external local payload on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/payload_tests; ./external_local_payload_test_client_external_start.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_local_and_external_starter.sh b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local_and_external_starter.sh.in similarity index 98% rename from test/network_tests/payload_tests/external_local_payload_test_client_local_and_external_starter.sh rename to test/network_tests/payload_tests/conf/external_local_payload_test_client_local_and_external_starter.sh.in index 4d45b8507..d8e9b94c8 100755 --- a/test/network_tests/payload_tests/external_local_payload_test_client_local_and_external_starter.sh +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local_and_external_starter.sh.in @@ -75,7 +75,7 @@ wait $CLIENT_PID || ((FAIL+=1)) # to finish the test successfully if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external local payload on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/payload_tests; ./external_local_payload_test_client_external_start.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_local_start.sh b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local_start.sh.in similarity index 100% rename from test/network_tests/payload_tests/external_local_payload_test_client_local_start.sh rename to test/network_tests/payload_tests/conf/external_local_payload_test_client_local_start.sh.in diff --git a/test/network_tests/payload_tests/conf/external_local_payload_test_client_local_starter.sh.bat.in b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local_starter.sh.in similarity index 100% rename from test/network_tests/payload_tests/conf/external_local_payload_test_client_local_starter.sh.bat.in rename to test/network_tests/payload_tests/conf/external_local_payload_test_client_local_starter.sh.in diff --git a/test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh b/test/network_tests/payload_tests/conf/external_local_payload_test_service_client_external_start.sh.in similarity index 100% rename from test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh rename to test/network_tests/payload_tests/conf/external_local_payload_test_service_client_external_start.sh.in diff --git a/test/network_tests/payload_tests/external_local_payload_test_service_start.sh b/test/network_tests/payload_tests/conf/external_local_payload_test_service_start.sh.in similarity index 100% rename from test/network_tests/payload_tests/external_local_payload_test_service_start.sh rename to test/network_tests/payload_tests/conf/external_local_payload_test_service_start.sh.in diff --git a/test/network_tests/payload_tests/local_payload_test_client.json b/test/network_tests/payload_tests/conf/local_payload_test_client.json.in similarity index 100% rename from test/network_tests/payload_tests/local_payload_test_client.json rename to test/network_tests/payload_tests/conf/local_payload_test_client.json.in diff --git a/test/network_tests/payload_tests/local_payload_test_client_start.sh b/test/network_tests/payload_tests/conf/local_payload_test_client_start.sh.in similarity index 100% rename from test/network_tests/payload_tests/local_payload_test_client_start.sh rename to test/network_tests/payload_tests/conf/local_payload_test_client_start.sh.in diff --git a/test/network_tests/payload_tests/conf/local_payload_test_huge_payload_starter.sh.bat.in b/test/network_tests/payload_tests/conf/local_payload_test_huge_payload_starter.sh.in similarity index 100% rename from test/network_tests/payload_tests/conf/local_payload_test_huge_payload_starter.sh.bat.in rename to test/network_tests/payload_tests/conf/local_payload_test_huge_payload_starter.sh.in diff --git a/test/network_tests/payload_tests/local_payload_test_service.json b/test/network_tests/payload_tests/conf/local_payload_test_service.json.in similarity index 100% rename from test/network_tests/payload_tests/local_payload_test_service.json rename to test/network_tests/payload_tests/conf/local_payload_test_service.json.in diff --git a/test/network_tests/payload_tests/local_payload_test_service_start.sh b/test/network_tests/payload_tests/conf/local_payload_test_service_start.sh.in similarity index 100% rename from test/network_tests/payload_tests/local_payload_test_service_start.sh rename to test/network_tests/payload_tests/conf/local_payload_test_service_start.sh.in diff --git a/test/network_tests/payload_tests/conf/local_payload_test_starter.sh.bat.in b/test/network_tests/payload_tests/conf/local_payload_test_starter.sh.in similarity index 100% rename from test/network_tests/payload_tests/conf/local_payload_test_starter.sh.bat.in rename to test/network_tests/payload_tests/conf/local_payload_test_starter.sh.in diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_local_starter.sh b/test/network_tests/payload_tests/external_local_payload_test_client_local_starter.sh deleted file mode 100755 index 63ff279aa..000000000 --- a/test/network_tests/payload_tests/external_local_payload_test_client_local_starter.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-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/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -# Parameter 2: number of TCP/UDP sockets the process should have open -check_tcp_udp_sockets_are_open () -{ - # Check that the passed pid/process does listen on at least one TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] - then - ((FAIL+=1)) - fi -} - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the passed pid/process does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service -export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json -./payload_test_service & -SERIVCE_PID=$! -sleep 1; - -# The service should listen on a TCP and UDP socket now -check_tcp_udp_sockets_are_open $SERIVCE_PID 2 - -# Start the client -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local -export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json -./payload_test_client & -CLIENT_PID=$! - -# The service should still listen on a TCP and UDP socket now -check_tcp_udp_sockets_are_open $SERIVCE_PID 2 -# The client should use the shortcut over a local UDS instead of TCP/UDP, -# therefore he shouldn't have any open TCP/UDP sockets -check_tcp_udp_sockets_are_closed $CLIENT_PID - -if [ ! -z "$USE_DOCKER" ]; then - FAIL=0 -fi - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh b/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh deleted file mode 100755 index c23089199..000000000 --- a/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-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/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Start the service -export VSOMEIP_APPLICATION_NAME=local_payload_test_service -export VSOMEIP_CONFIGURATION=local_payload_test_service.json -./payload_test_service & -SERIVCE_PID=$! -sleep 1; - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_payload_test_client -export VSOMEIP_CONFIGURATION=local_payload_test_client.json -./payload_test_client --number-of-messages 100 --max-payload-size 10485760 & -CLIENT_PID=$! - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/payload_tests/local_payload_test_starter.sh b/test/network_tests/payload_tests/local_payload_test_starter.sh deleted file mode 100755 index 38a6f0379..000000000 --- a/test/network_tests/payload_tests/local_payload_test_starter.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-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/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the service does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=local_payload_test_service -export VSOMEIP_CONFIGURATION=local_payload_test_service.json -./payload_test_service & -SERIVCE_PID=$! -sleep 1; - -check_tcp_udp_sockets_are_closed $SERIVCE_PID - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_payload_test_client -export VSOMEIP_CONFIGURATION=local_payload_test_client.json -./payload_test_client & -CLIENT_PID=$! - -check_tcp_udp_sockets_are_closed $SERIVCE_PID -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/payload_tests/payload_test_client.cpp b/test/network_tests/payload_tests/payload_test_client.cpp index 3395668b7..ef5ba631f 100644 --- a/test/network_tests/payload_tests/payload_test_client.cpp +++ b/test/network_tests/payload_tests/payload_test_client.cpp @@ -3,6 +3,8 @@ // 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 "payload_test_client.hpp" enum class payloadsize diff --git a/test/network_tests/payload_tests/payload_test_service.cpp b/test/network_tests/payload_tests/payload_test_service.cpp index 0aa55afed..7d4c9243a 100644 --- a/test/network_tests/payload_tests/payload_test_service.cpp +++ b/test/network_tests/payload_tests/payload_test_service.cpp @@ -3,6 +3,8 @@ // 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 "payload_test_service.hpp" // this variables are changed via cmdline parameters diff --git a/test/network_tests/pending_subscription_tests/CMakeLists.txt b/test/network_tests/pending_subscription_tests/CMakeLists.txt new file mode 100644 index 000000000..88317f1a2 --- /dev/null +++ b/test/network_tests/pending_subscription_tests/CMakeLists.txt @@ -0,0 +1,115 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(pending_subscription_test LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + pending_subscription_test_master.json + pending_subscription_test_master_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(pending_subscription_test_service + pending_subscription_test_service.cpp +) + +# Add test executable. +set(service_discovery_sources + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/configuration_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/entry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/eventgroupentry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ip_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ipv4_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ipv6_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/load_balancing_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/message_element_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/message_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/protection_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/selective_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/serviceentry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/unknown_option_impl.cpp +) +set(message_sources + ${CMAKE_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${CMAKE_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/message/src/payload_impl.cpp +) +add_executable(pending_subscription_test_sd_msg_sender + pending_subscription_test_sd_msg_sender.cpp + ${service_discovery_sources} + ${message_sources} +) + +# Link vsomeip-sd to executable. +target_link_libraries(pending_subscription_test_sd_msg_sender ${VSOMEIP_NAME}-sd) + +# Add build dependencies and link libraries to executables. +set(executables + pending_subscription_test_service + pending_subscription_test_sd_msg_sender +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_subscribe + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh SUBSCRIBE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_alternating_subscribe_unsubscribe + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh SUBSCRIBE_UNSUBSCRIBE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_unsubscribe + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh UNSUBSCRIBE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_alternating_subscribe_unsubscribe_nack + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh SUBSCRIBE_UNSUBSCRIBE_NACK + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_alternating_subscribe_unsubscribe_same_port + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh SUBSCRIBE_UNSUBSCRIBE_SAME_PORT + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_subscribe_resubscribe_mixed + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh SUBSCRIBE_RESUBSCRIBE_MIXED + TIMEOUT 300 +) + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_subscribe_stopsubscribe_subscribe + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME pending_subscription_test_send_request_to_sd_port + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/pending_subscription_test_master_starter.sh REQUEST_TO_SD + TIMEOUT 180 +) diff --git a/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in b/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in index dc4b1cd3c..3aea9936f 100755 --- a/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in +++ b/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in @@ -23,7 +23,7 @@ fi TESTMODE=$1 export VSOMEIP_CONFIGURATION=pending_subscription_test_master.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! # Start the services ./pending_subscription_test_service $1 & @@ -35,7 +35,7 @@ if [ ! -z "$USE_LXC_TEST" ]; then echo "Waiting for 5s" sleep 5 echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./pending_subscription_test_sd_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $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/network_tests/pending_subscription_tests; ./pending_subscription_test_sd_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\"" & echo "remote ssh pid: $!" elif [ ! -z "$USE_DOCKER" ]; then echo "Waiting for 5s" diff --git a/test/network_tests/pending_subscription_tests/pending_subscription_test_sd_msg_sender.cpp b/test/network_tests/pending_subscription_tests/pending_subscription_test_sd_msg_sender.cpp index 47ac36261..ce05f66c3 100644 --- a/test/network_tests/pending_subscription_tests/pending_subscription_test_sd_msg_sender.cpp +++ b/test/network_tests/pending_subscription_tests/pending_subscription_test_sd_msg_sender.cpp @@ -16,7 +16,7 @@ #include -#include "../../implementation/utility/include/byteorder.hpp" +#include "../../implementation/utility/include/bithelper.hpp" #include "../../implementation/message/include/deserializer.hpp" #include "../../implementation/service_discovery/include/service_discovery.hpp" #include "../../implementation/service_discovery/include/message_impl.hpp" @@ -85,17 +85,13 @@ TEST_F(pending_subscription, send_multiple_subscriptions) std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); its_pos += its_message_size; bytes_transferred -= its_message_size; @@ -278,17 +274,13 @@ TEST_F(pending_subscription, send_alternating_subscribe_unsubscribe) std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); its_pos += its_message_size; bytes_transferred -= its_message_size; @@ -486,16 +478,13 @@ TEST_F(pending_subscription, send_multiple_unsubscriptions) #endif std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); + its_pos += its_message_size; bytes_transferred -= its_message_size; @@ -693,17 +682,13 @@ TEST_F(pending_subscription, send_alternating_subscribe_nack_unsubscribe) #endif std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); its_pos += its_message_size; bytes_transferred -= its_message_size; @@ -914,17 +899,13 @@ TEST_F(pending_subscription, send_alternating_subscribe_unsubscribe_same_port) std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); its_pos += its_message_size; bytes_transferred -= its_message_size; @@ -1125,17 +1106,12 @@ TEST_F(pending_subscription, subscribe_resubscribe_mixed) std::uint32_t its_pos = 0; while (bytes_transfered > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); its_pos += its_message_size; bytes_transfered -= its_message_size; @@ -1362,17 +1338,13 @@ TEST_F(pending_subscription, send_subscribe_stop_subscribe_subscribe) std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; #endif - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); its_pos += its_message_size; bytes_transferred -= its_message_size; @@ -1560,17 +1532,13 @@ TEST_F(pending_subscription, send_request_to_sd_port) } else { std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be(&receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); its_pos += its_message_size; bytes_transferred -= its_message_size; diff --git a/test/network_tests/regression_tests/CMakeLists.txt b/test/network_tests/regression_tests/CMakeLists.txt new file mode 100644 index 000000000..822246f14 --- /dev/null +++ b/test/network_tests/regression_tests/CMakeLists.txt @@ -0,0 +1,42 @@ +# Copyright (C) 2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(regression_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + climate_test_master.json + climate_test_master_starter.sh + climate_test_slave.json + climate_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(climate_test_service + climate_test_service.cpp +) + +# Add test executable. +add_executable(climate_test_client + climate_test_client.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + climate_test_service + climate_test_client +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME climate_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/climate_test_master_starter.sh + TIMEOUT 25 +) diff --git a/test/network_tests/regression_tests/climate_test_client.cpp b/test/network_tests/regression_tests/climate_test_client.cpp new file mode 100644 index 000000000..6674907aa --- /dev/null +++ b/test/network_tests/regression_tests/climate_test_client.cpp @@ -0,0 +1,192 @@ +// Copyright (C) 2014-2024 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 "climate_test_globals.hpp" + +class client_sample { +public: + client_sample(struct climate_test::service_info _service_info) : + app_(vsomeip::runtime::get()->create_application()), + service_info_(_service_info) { + } + + bool init() { + if (!app_->init()) { + std::cerr << "Couldn't initialize application" << std::endl; + return false; + } + + app_->register_state_handler( + std::bind(&client_sample::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler( + vsomeip::ANY_SERVICE, service_info_.instance_id, vsomeip::ANY_METHOD, + std::bind(&client_sample::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(service_info_.service_id, service_info_.instance_id, + std::bind(&client_sample::on_availability, + this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + + std::set its_groups; + its_groups.insert(service_info_.eventgroup_id); + app_->request_event( + service_info_.service_id, + service_info_.instance_id, + service_info_.event_id, + its_groups, + vsomeip::event_type_e::ET_FIELD); + app_->subscribe(service_info_.service_id, service_info_.instance_id, service_info_.eventgroup_id); + + return true; + } + + void start() { + app_->start(); + } + + void stop() { + app_->clear_all_handler(); + app_->unsubscribe(service_info_.service_id, service_info_.instance_id, service_info_.eventgroup_id); + app_->release_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id); + app_->release_service(service_info_.service_id, service_info_.instance_id); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(service_info_.service_id, service_info_.instance_id); + } + } + + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " + << (_is_available ? "available." : "NOT available.") + << std::endl; + + availability_handler_calls++; + } + + void on_message(const std::shared_ptr &_response) { + std::stringstream its_message; + its_message << "Received a notification for Event [" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_service() << "." + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_instance() << "." + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_method() << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_session() + << "] = "; + std::shared_ptr its_payload = + _response->get_payload(); + EXPECT_EQ(its_payload->get_length(), 5); + its_message << "(" << std::dec << its_payload->get_length() << ") "; + for (uint32_t i = 0; i < its_payload->get_length(); ++i) { + its_message << std::hex << std::setw(2) << std::setfill('0') + << (int) its_payload->get_data()[i] << " "; + } + + if ((its_payload->get_length() % 5) == 0) { + notifications_received++; + if (notifications_received == 2) { + // Send message to trigger second part of the test + std::shared_ptr its_set + = vsomeip::runtime::get()->create_message(); + its_set->set_message_type(vsomeip_v3::message_type_e::MT_REQUEST_NO_RETURN); + its_set->set_service(service_info_.service_id); + its_set->set_instance(service_info_.instance_id); + its_set->set_method(service_info_.get_method_id); + + const vsomeip::byte_t its_data[]{0x07}; + std::shared_ptr its_set_payload + = vsomeip::runtime::get()->create_payload(); + its_set_payload->set_data(its_data, sizeof(its_data)); + its_set->set_payload(its_set_payload); + app_->send(its_set); + std::this_thread::sleep_for(climate_test::MSG_SEND_WAIT_INTERVAL); + } + + if (notifications_received < 3) { + request_release(); + } else if (notifications_received == 4) { + // All expected notifications received, stop the client and send shutdown message to service + EXPECT_EQ(availability_handler_calls, 9); + + std::shared_ptr its_set + = vsomeip::runtime::get()->create_message(); + its_set->set_message_type(vsomeip_v3::message_type_e::MT_REQUEST_NO_RETURN); + its_set->set_service(service_info_.service_id); + its_set->set_instance(service_info_.instance_id); + its_set->set_method(service_info_.shutdown_method_id); + app_->send(its_set); + std::this_thread::sleep_for(climate_test::MSG_SEND_WAIT_INTERVAL); + stop(); + } + } + } + + void request_release() { + app_->release_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id); + app_->release_service(service_info_.service_id, service_info_.instance_id); + std::this_thread::sleep_for(climate_test::OFFER_CYCLE_INTERVAL); + app_->request_service(service_info_.service_id, service_info_.instance_id); + std::set its_groups; + its_groups.insert(service_info_.eventgroup_id); + app_->request_event( + service_info_.service_id, + service_info_.instance_id, + service_info_.event_id, + its_groups, + vsomeip::event_type_e::ET_FIELD); + app_->subscribe(service_info_.service_id, service_info_.instance_id, service_info_.eventgroup_id); + } + +private: + std::shared_ptr< vsomeip::application > app_; + struct climate_test::service_info service_info_; + uint8_t availability_handler_calls = 0; + uint8_t notifications_received = 0; +}; + +TEST(someip_subscribe_notify_test_example, stop_without_unregister) +{ + client_sample its_sample(climate_test::service); + + if (its_sample.init()) { + its_sample.start(); + } +} + + +#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/regression_tests/climate_test_globals.hpp b/test/network_tests/regression_tests/climate_test_globals.hpp new file mode 100644 index 000000000..37a754d60 --- /dev/null +++ b/test/network_tests/regression_tests/climate_test_globals.hpp @@ -0,0 +1,27 @@ +// 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_EXAMPLES_SAMPLE_IDS_HPP +#define VSOMEIP_EXAMPLES_SAMPLE_IDS_HPP + +namespace climate_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::method_t get_method_id; + vsomeip::method_t shutdown_method_id; +}; + +struct service_info service = { 0x1234, 0x5678, 0x0421, 0x8778, 0x4465, 0x0001, 0x0002}; + +constexpr std::chrono::seconds OFFER_CYCLE_INTERVAL = std::chrono::seconds(1); +constexpr std::chrono::milliseconds MSG_SEND_WAIT_INTERVAL = std::chrono::milliseconds(500); +} + +#endif // VSOMEIP_EXAMPLES_SAMPLE_IDS_HPP diff --git a/test/network_tests/regression_tests/climate_test_service.cpp b/test/network_tests/regression_tests/climate_test_service.cpp new file mode 100644 index 000000000..0c39439da --- /dev/null +++ b/test/network_tests/regression_tests/climate_test_service.cpp @@ -0,0 +1,232 @@ +// Copyright (C) 2014-2024 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 "climate_test_globals.hpp" + +class service_sample { +public: + service_sample(struct climate_test::service_info _service_info) : + app_(vsomeip::runtime::get()->create_application()), + blocked_(false), + running_(true), + is_offered_(false), + is_second_(false), + offer_thread_(std::bind(&service_sample::run, this)), + notify_thread_(std::bind(&service_sample::notify, this)), + service_info_(_service_info) { + } + + bool init() { + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + std::cerr << "Couldn't initialize application" << std::endl; + return false; + } + app_->register_state_handler( + std::bind(&service_sample::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler( + service_info_.service_id, + service_info_.instance_id, + service_info_.get_method_id, + std::bind(&service_sample::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler( + service_info_.service_id, + service_info_.instance_id, + service_info_.shutdown_method_id, + std::bind(&service_sample::on_shutdown_message, this, + std::placeholders::_1)); + + std::set its_groups; + its_groups.insert(service_info_.eventgroup_id); + app_->offer_event( + service_info_.service_id, + service_info_.instance_id, + service_info_.event_id, + its_groups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + { + std::lock_guard its_lock(payload_mutex_); + payload_ = vsomeip::runtime::get()->create_payload(); + } + + blocked_ = true; + condition_.notify_one(); + return true; + } + + void start() { + app_->start(); + } + + void stop() { + { + std::lock_guard its_lock_notify(notify_mutex_); + running_ = false; + notify_condition_.notify_one(); + } + app_->clear_all_handler(); + if (std::this_thread::get_id() != offer_thread_.get_id()) { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } + } else { + offer_thread_.detach(); + } + if (std::this_thread::get_id() != notify_thread_.get_id()) { + if (notify_thread_.joinable()) { + notify_thread_.join(); + } + } else { + notify_thread_.detach(); + } + app_->stop(); + } + + void offer() { + std::lock_guard its_lock(notify_mutex_); + app_->offer_service(service_info_.service_id, service_info_.instance_id); + is_offered_ = true; + notify_condition_.notify_one(); + } + + void stop_offer() { + std::lock_guard its_lock(notify_mutex_); + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + is_offered_ = false; + notify_condition_.notify_one(); + } + + void on_state(vsomeip::state_type_e _state) { + std::cout << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered.") << std::endl; + } + + void on_message(const std::shared_ptr &_message) { + // Triger second part of the test, offer and stop offer service + (void)_message; + stop_offer(); + std::this_thread::sleep_for(climate_test::OFFER_CYCLE_INTERVAL); + std::lock_guard its_lock(message_mutex_); + is_second_ = true; + notify_condition_.notify_one(); + } + + void on_shutdown_message(const std::shared_ptr &_message) { + // Test concluded, stop the service + (void)_message; + stop_offer(); + stop(); + } + + void run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); + std::unique_lock its_lock_message(message_mutex_); + while (running_ && !is_second_) { + notify_condition_.wait(its_lock_message); + } + + // Offer and stop offer service with 1 second interval + bool is_offer(true); + for (uint8_t i = 0; i < 3; ++i) { + if (is_offer) { + offer(); + } + else { + stop_offer(); + } + is_offer = !is_offer; + std::this_thread::sleep_for(climate_test::OFFER_CYCLE_INTERVAL); + } + } + + void notify() { + + vsomeip::byte_t its_data[]{ 0x00, 0x01, 0x02, 0x03, 0x04}; + uint32_t its_size = 5; + + while (running_) { + std::unique_lock its_lock(notify_mutex_); + while (!is_offered_ && running_) { + notify_condition_.wait(its_lock); + } + while (is_offered_ && running_) { + { + std::lock_guard its_lock(payload_mutex_); + payload_->set_data(its_data, its_size); + + VSOMEIP_INFO << "\nSERVICE SIDE -> " << "Setting event (Length=" << std::dec << its_size << ")." << std::endl; + app_->notify(service_info_.service_id, service_info_.instance_id, service_info_.event_id, payload_); + } + + notify_condition_.wait_for(its_lock, std::chrono::seconds(climate_test::OFFER_CYCLE_INTERVAL)); + } + } + } + +private: + std::shared_ptr app_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + bool running_; + + std::mutex notify_mutex_; + std::condition_variable notify_condition_; + bool is_offered_; + + std::mutex message_mutex_; + bool is_second_; + + std::mutex payload_mutex_; + std::shared_ptr payload_; + + // blocked_ / is_offered_ must be initialized before starting the threads! + std::thread offer_thread_; + std::thread notify_thread_; + + struct climate_test::service_info service_info_; +}; + + +TEST(someip_subscribe_notify_test_example, run_service) +{ + service_sample its_sample(climate_test::service); + + if (its_sample.init()) { + its_sample.start(); + } +} + + +#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/regression_tests/conf/climate_test_master.json.in b/test/network_tests/regression_tests/conf/climate_test_master.json.in new file mode 100644 index 000000000..3d1976f78 --- /dev/null +++ b/test/network_tests/regression_tests/conf/climate_test_master.json.in @@ -0,0 +1,81 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "true" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277" + }, + { + "name" : "client-sample", + "id" : "0x1344" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unreliable" : "30509", + "multicast" : + { + "address" : "224.225.226.233", + "port" : "32344" + }, + "events" : + [ + { + "event" : "0x0777", + "is_field" : "true", + "update-cycle" : 2000 + }, + { + "event" : "0x0778", + "is_field" : "true", + "update-cycle" : 0 + }, + { + "event" : "0x0779", + "is_field" : "true" + } + ], + "eventgroups" : + [ + { + "eventgroup" : "0x4455", + "events" : [ "0x777", "0x778" ] + }, + { + "eventgroup" : "0x4465", + "events" : [ "0x778", "0x779" ], + "is_multicast" : "true" + }, + { + "eventgroup" : "0x4555", + "events" : [ "0x777", "0x779" ] + } + ] + } + ], + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.244.224.245", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/regression_tests/conf/climate_test_master_starter.sh.in b/test/network_tests/regression_tests/conf/climate_test_master_starter.sh.in new file mode 100755 index 000000000..42540f445 --- /dev/null +++ b/test/network_tests/regression_tests/conf/climate_test_master_starter.sh.in @@ -0,0 +1,58 @@ +#!/bin/bash +# Copyright (C) 2015-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +# Start the services +export VSOMEIP_APPLICATION_NAME=service-sample +export VSOMEIP_CONFIGURATION=climate_test_master.json +./climate_test_service & + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting climate_test_slave_starter.sh on slave LXC with parameters" + 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/network_tests/regression_tests; ./climate_test_slave_starter.sh \"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./climate_test_slave_starter.sh" & +else + cat < + #include "restart_routing_test_client.hpp" routing_restart_test_client::routing_restart_test_client() @@ -94,6 +96,7 @@ void routing_restart_test_client::on_message(const std::shared_ptrget_service() == vsomeip_test::TEST_SERVICE_SERVICE_ID && _response->get_instance() == vsomeip_test::TEST_SERVICE_INSTANCE_ID) { + received_responses_++; if (received_responses_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS) { VSOMEIP_WARNING << std::hex << app_->get_client() @@ -104,21 +107,40 @@ void routing_restart_test_client::on_message(const std::shared_ptr its_lock(mutex_); while (!is_available_) { - condition_.wait(its_lock); + if (!condition_.wait_for(its_lock, std::chrono::milliseconds(10000), + [this] { return is_available_; })) { + VSOMEIP_WARNING << "Service not available for 10s. Quit waiting"; + its_availability_timeout = true; + break; + } + if (its_sent_requests > 0 && received_responses_ > 0 + && its_sent_requests > received_responses_) { + VSOMEIP_WARNING << "Sent/Recv messages mismatch (" << its_sent_requests << "/" + << received_responses_ + << ") : Resending non-responded requests"; + its_sent_requests = received_responses_; + } } } + if (its_availability_timeout) { + break; + } auto request = vsomeip::runtime::get()->create_request(false); request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); app_->send(request); + its_sent_requests++; + VSOMEIP_INFO << "Sent request " << its_sent_requests; std::this_thread::sleep_for(std::chrono::milliseconds(250)); } diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp b/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp index 92f0ff0a2..c8b192712 100644 --- a/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp +++ b/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp @@ -3,15 +3,14 @@ // 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 "restart_routing_test_service.hpp" routing_restart_test_service::routing_restart_test_service() : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - blocked_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&routing_restart_test_service::run, this)) { -} + app_(vsomeip::runtime::get()->create_application()), is_registered_(false), blocked_(false), + init_shutdown_(false), all_received_(false), shutdown_counter_(0), + offer_thread_(std::bind(&routing_restart_test_service::run, this)) { } bool routing_restart_test_service::init() { std::lock_guard its_lock(mutex_); @@ -84,11 +83,11 @@ void routing_restart_test_service::on_state(vsomeip::state_type_e _state) { void routing_restart_test_service::on_message(const std::shared_ptr& _request) { ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method()); - - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "]"; + received_counter_[_request->get_client()]++; + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) << std::setfill('0') + << std::hex << _request->get_client() << "/" << std::setw(4) << std::setfill('0') + << std::hex << _request->get_session() << "] : " << std::dec + << received_counter_[_request->get_client()]; // send response std::shared_ptr its_response = @@ -96,17 +95,33 @@ void routing_restart_test_service::on_message(const std::shared_ptrsend(its_response); - number_of_received_messages_++; - if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS) { - VSOMEIP_INFO << "Received all messages!"; + { + std::lock_guard its_guard(number_of_received_messages_mutex_); + number_of_received_messages_++; + if (number_of_received_messages_ + == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS) { + VSOMEIP_INFO << "Received all messages!"; + } } } void routing_restart_test_service::on_message_shutdown( const std::shared_ptr& _request) { - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - stop(); + VSOMEIP_INFO << "Shutdown Service requested by 0x" << std::setw(4) << std::setfill('0') + << std::hex << _request->get_client(); + { + std::lock_guard its_guard_counter(counter_mutex_); + shutdown_counter_++; + if (shutdown_counter_ == 1) { + std::lock_guard its_guard(shutdown_mutex_); + init_shutdown_ = true; + init_shutdown_condition_.notify_one(); + } else if (shutdown_counter_ == vsomeip_test::NUMBER_OF_CLIENTS_TO_REQUEST_SHUTDOWN) { + std::lock_guard its_guard(shutdown_mutex_); + all_received_ = true; + execute_shutdown_condition_.notify_one(); + } + } } void routing_restart_test_service::run() { @@ -114,7 +129,15 @@ void routing_restart_test_service::run() { while (!blocked_) condition_.wait(its_lock); - offer(); + offer(); + std::unique_lock its_shutdown_lock(shutdown_mutex_); + init_shutdown_condition_.wait(its_shutdown_lock, [this] { return init_shutdown_; }); + if (!execute_shutdown_condition_.wait_for(its_shutdown_lock, std::chrono::milliseconds(5000), + [this] { return all_received_; })) { + VSOMEIP_WARNING + << "Timeout reached : Not all clients requested shutdown. Stopping Service anyway"; + } + stop(); } TEST(someip_restart_routing_test, send_response_for_every_request) { diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp b/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp index 7660b8fcb..18c802561 100644 --- a/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp +++ b/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp @@ -37,8 +37,19 @@ class routing_restart_test_service { std::mutex mutex_; std::condition_variable condition_; + std::condition_variable init_shutdown_condition_; + std::condition_variable execute_shutdown_condition_; bool blocked_; + bool init_shutdown_; + bool all_received_; + std::mutex shutdown_mutex_; + std::mutex counter_mutex_; + std::uint32_t shutdown_counter_; + std::map received_counter_; + + std::mutex number_of_received_messages_mutex_; std::uint32_t number_of_received_messages_; + std::thread offer_thread_; }; diff --git a/test/network_tests/routing_tests/CMakeLists.txt b/test/network_tests/routing_tests/CMakeLists.txt new file mode 100644 index 000000000..3c9626be7 --- /dev/null +++ b/test/network_tests/routing_tests/CMakeLists.txt @@ -0,0 +1,69 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(routing_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + external_local_routing_test_client_external.json + external_local_routing_test_client_external_start.sh + external_local_routing_test_service.json + external_local_routing_test_service_start.sh + external_local_routing_test_starter.sh + local_routing_test_client.json + local_routing_test_client_start.sh + local_routing_test_service.json + local_routing_test_service_start.sh + local_routing_test_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(local_routing_test_service + local_routing_test_service.cpp +) + +# Add test executable. +add_executable(local_routing_test_client + local_routing_test_client.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + local_routing_test_service + local_routing_test_client +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME local_routing_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/local_routing_test_starter.sh +) + +if(NOT TESTS_BAT) + + # Add test executable. + add_executable(external_local_routing_test_service + external_local_routing_test_service.cpp + ) + + # Add build dependencies and link libraries to executables. + set(executables + external_local_routing_test_service + ) + targets_add_default_dependencies("${executables}") + targets_link_default_libraries("${executables}") + + # Add custom test command. + add_custom_test( + NAME external_local_routing_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/external_local_routing_test_starter.sh + ) + +endif() diff --git a/test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh b/test/network_tests/routing_tests/conf/external_local_routing_test_client_external_start.sh.in similarity index 100% rename from test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh rename to test/network_tests/routing_tests/conf/external_local_routing_test_client_external_start.sh.in diff --git a/test/network_tests/routing_tests/external_local_routing_test_service_start.sh b/test/network_tests/routing_tests/conf/external_local_routing_test_service_start.sh.in similarity index 100% rename from test/network_tests/routing_tests/external_local_routing_test_service_start.sh rename to test/network_tests/routing_tests/conf/external_local_routing_test_service_start.sh.in diff --git a/test/network_tests/routing_tests/external_local_routing_test_starter.sh b/test/network_tests/routing_tests/conf/external_local_routing_test_starter.sh.in similarity index 97% rename from test/network_tests/routing_tests/external_local_routing_test_starter.sh rename to test/network_tests/routing_tests/conf/external_local_routing_test_starter.sh.in index c67114fc4..b47d771e6 100755 --- a/test/network_tests/routing_tests/external_local_routing_test_starter.sh +++ b/test/network_tests/routing_tests/conf/external_local_routing_test_starter.sh.in @@ -78,7 +78,7 @@ if [ $CLIENT_STILL_THERE -ne 0 ] then if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external_local_routing_test_starter.sh on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_routing_test_client_external_start.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/routing_tests; ./external_local_routing_test_client_external_start.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_routing_test_client_external_start.sh" & diff --git a/test/network_tests/routing_tests/local_routing_test_client.json b/test/network_tests/routing_tests/conf/local_routing_test_client.json.in similarity index 100% rename from test/network_tests/routing_tests/local_routing_test_client.json rename to test/network_tests/routing_tests/conf/local_routing_test_client.json.in diff --git a/test/network_tests/routing_tests/local_routing_test_client_start.sh b/test/network_tests/routing_tests/conf/local_routing_test_client_start.sh.in similarity index 100% rename from test/network_tests/routing_tests/local_routing_test_client_start.sh rename to test/network_tests/routing_tests/conf/local_routing_test_client_start.sh.in diff --git a/test/network_tests/routing_tests/local_routing_test_service.json b/test/network_tests/routing_tests/conf/local_routing_test_service.json.in similarity index 100% rename from test/network_tests/routing_tests/local_routing_test_service.json rename to test/network_tests/routing_tests/conf/local_routing_test_service.json.in diff --git a/test/network_tests/routing_tests/local_routing_test_service_start.sh b/test/network_tests/routing_tests/conf/local_routing_test_service_start.sh.in similarity index 100% rename from test/network_tests/routing_tests/local_routing_test_service_start.sh rename to test/network_tests/routing_tests/conf/local_routing_test_service_start.sh.in diff --git a/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in deleted file mode 100755 index d7abe64ed..000000000 --- a/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-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/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the service does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=local_routing_test_service -if [ "$VSOMEIP_CONFIGURATION_SERVICE" != "" ] -then - export VSOMEIP_CONFIGURATION=$VSOMEIP_CONFIGURATION_SERVICE -else - export VSOMEIP_CONFIGURATION=local_routing_test_service.json -fi -./local_routing_test_service & -SERIVCE_PID=$! -sleep 1; - -check_tcp_udp_sockets_are_closed $SERIVCE_PID - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_routing_test_client -if [ "$VSOMEIP_CONFIGURATION_CLIENT" != "" ] -then - export VSOMEIP_CONFIGURATION=$VSOMEIP_CONFIGURATION_CLIENT -else - export VSOMEIP_CONFIGURATION=local_routing_test_client.json -fi -./local_routing_test_client & -CLIENT_PID=$! - -check_tcp_udp_sockets_are_closed $SERIVCE_PID -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited successfully and the service didnt't -# have any open -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in index d5b83f4b0..17c3d1e9a 100755 --- a/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in +++ b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in @@ -1,5 +1,5 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +#!/bin/sh +# Copyright (C) 2015-2023 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/. @@ -35,15 +35,14 @@ check_tcp_udp_sockets_are_closed () export VSOMEIP_CONFIGURATION=local_routing_test_service.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! -WAIT_PIDS=() # Start the service export VSOMEIP_APPLICATION_NAME=local_routing_test_service ./local_routing_test_service & SERIVCE_PID=$! -WAIT_PIDS+=($!) +WAIT_PID_ONE=$! sleep 1; check_tcp_udp_sockets_are_closed $SERIVCE_PID @@ -53,18 +52,16 @@ export VSOMEIP_APPLICATION_NAME=local_routing_test_client export VSOMEIP_CONFIGURATION=local_routing_test_client.json ./local_routing_test_client & CLIENT_PID=$! -WAIT_PIDS+=($!) +WAIT_PID_TWO=$! check_tcp_udp_sockets_are_closed $SERIVCE_PID check_tcp_udp_sockets_are_closed $CLIENT_PID # Wait until client and service are finished -for job in ${WAIT_PIDS[*]} -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done +# Fail gets incremented if either client or service exit +# with a non-zero exit code +wait $WAIT_PID_ONE || ((FAIL+=1)) +wait $WAIT_PID_TWO || ((FAIL+=1)) kill $PID_VSOMEIPD sleep 1 diff --git a/test/network_tests/routing_tests/conf/local_routing_test_starter_qnx.sh.in b/test/network_tests/routing_tests/conf/local_routing_test_starter_qnx.sh.in deleted file mode 100755 index 2f30486c6..000000000 --- a/test/network_tests/routing_tests/conf/local_routing_test_starter_qnx.sh.in +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh -# Copyright (C) 2015-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the service does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -export VSOMEIP_CONFIGURATION=local_routing_test_service.json -# start daemon -../../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -# Start the service -export VSOMEIP_APPLICATION_NAME=local_routing_test_service -./local_routing_test_service & -SERIVCE_PID=$! -WAIT_PID_ONE=$! -sleep 1; - -check_tcp_udp_sockets_are_closed $SERIVCE_PID - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_routing_test_client -export VSOMEIP_CONFIGURATION=local_routing_test_client.json -./local_routing_test_client & -CLIENT_PID=$! -WAIT_PID_TWO=$! - -check_tcp_udp_sockets_are_closed $SERIVCE_PID -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# Wait until client and service are finished -# Fail gets incremented if either client or service exit -# with a non-zero exit code -wait $WAIT_PID_ONE || ((FAIL+=1)) -wait $WAIT_PID_TWO || ((FAIL+=1)) - -kill $PID_VSOMEIPD -sleep 1 - -# Check if client and server both exited successfully and the service didnt't -# have any open -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/network_tests/routing_tests/external_local_routing_test_service.cpp b/test/network_tests/routing_tests/external_local_routing_test_service.cpp index ba4cdd0c1..c90f17b12 100644 --- a/test/network_tests/routing_tests/external_local_routing_test_service.cpp +++ b/test/network_tests/routing_tests/external_local_routing_test_service.cpp @@ -3,6 +3,8 @@ // 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 "external_local_routing_test_service.hpp" external_local_routing_test_service::external_local_routing_test_service(bool _use_static_routing) : diff --git a/test/network_tests/routing_tests/local_routing_test_client.cpp b/test/network_tests/routing_tests/local_routing_test_client.cpp index 4bde183f4..f7f83c324 100644 --- a/test/network_tests/routing_tests/local_routing_test_client.cpp +++ b/test/network_tests/routing_tests/local_routing_test_client.cpp @@ -3,6 +3,8 @@ // 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 "local_routing_test_client.hpp" local_routing_test_client::local_routing_test_client(bool _use_tcp) : diff --git a/test/network_tests/routing_tests/local_routing_test_service.cpp b/test/network_tests/routing_tests/local_routing_test_service.cpp index 2a819e215..5d659e264 100644 --- a/test/network_tests/routing_tests/local_routing_test_service.cpp +++ b/test/network_tests/routing_tests/local_routing_test_service.cpp @@ -3,6 +3,8 @@ // 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 "local_routing_test_service.hpp" local_routing_test_service::local_routing_test_service(bool _use_static_routing) : diff --git a/test/network_tests/second_address_tests/CMakeLists.txt b/test/network_tests/second_address_tests/CMakeLists.txt new file mode 100644 index 000000000..c3f678328 --- /dev/null +++ b/test/network_tests/second_address_tests/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(second_address_tests LANGUAGES CXX) + +# Configure necessary files into build folder. +set(configuration_files + second_address_test_master_client.json + second_address_test_master_service_udp.json + second_address_test_master_starter.sh + second_address_test_slave_client.json + second_address_test_slave_service_udp.json + second_address_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(second_address_test_service + second_address_test_service.cpp +) + +# Add test executable. +add_executable(second_address_test_client + second_address_test_client.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + second_address_test_service + second_address_test_client +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME second_address_test_second_ip_address_service_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/second_address_test_master_starter.sh SERVICE UDP + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME second_address_test_second_ip_address_client_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/second_address_test_master_starter.sh CLIENT UDP + TIMEOUT 180 +) diff --git a/test/network_tests/second_address_tests/second_address_test_master_starter.sh b/test/network_tests/second_address_tests/conf/second_address_test_master_starter.sh.in similarity index 93% rename from test/network_tests/second_address_tests/second_address_test_master_starter.sh rename to test/network_tests/second_address_tests/conf/second_address_test_master_starter.sh.in index 756e22e1b..66f7d5600 100755 --- a/test/network_tests/second_address_tests/second_address_test_master_starter.sh +++ b/test/network_tests/second_address_tests/conf/second_address_test_master_starter.sh.in @@ -36,7 +36,7 @@ fi rm -f /tmp/vsomeip* -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! ./$MASTER_APPLICATION $COMMUNICATIONMODE & @@ -46,7 +46,7 @@ sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting offer test on slave LXC second_address_test_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE\"" & + 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/network_tests/second_address_tests; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE" & else diff --git a/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in b/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in index 129d20905..ab2b74e89 100755 --- a/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in +++ b/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in @@ -37,7 +37,7 @@ fi rm -f /tmp/vsomeip* -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! ./$SLAVE_APPLICATION $COMMUNICATIONMODE & diff --git a/test/network_tests/second_address_tests/second_address_test_service.cpp b/test/network_tests/second_address_tests/second_address_test_service.cpp index fc9d0a281..e6346b704 100644 --- a/test/network_tests/second_address_tests/second_address_test_service.cpp +++ b/test/network_tests/second_address_tests/second_address_test_service.cpp @@ -5,10 +5,11 @@ #include #include +#include #include +#include #include #include -#include #include #include diff --git a/test/network_tests/security_tests/CMakeLists.txt b/test/network_tests/security_tests/CMakeLists.txt new file mode 100644 index 000000000..fe3446291 --- /dev/null +++ b/test/network_tests/security_tests/CMakeLists.txt @@ -0,0 +1,61 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(security_tests LANGUAGES CXX) + +if(TEST_SECURITY) + + # Configure necessary files into the build folder. + set(configuration_files + security_test_config_client_external_allow.json + security_test_config_client_external_deny.json + security_test_config_service_external_allow.json + security_test_config_service_external_deny.json + security_test_external_master_start.sh + security_test_external_slave_start.sh + security_test_local_config.json + security_test_local_start.sh + ) + configure_files("${configuration_files}") + + # Add test executable. + add_executable(security_test_service + security_test_service.cpp + ) + + # Add test executable. + add_executable(security_test_client + security_test_client.cpp + ) + + # Add build dependencies and link libraries to executables. + set(executables + security_test_service + security_test_client + ) + targets_add_default_dependencies("${executables}") + targets_link_default_libraries("${executables}") + + # Add custom test command. + add_custom_test( + NAME security_test + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/security_test_local_start.sh + ) + + # Add custom test command. + add_custom_test( + NAME security_test_external_allow + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/security_test_external_master_start.sh security_test_config_client_external_allow.json --allow + ) + + # Add custom test command. + add_custom_test( + NAME security_test_external_deny + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/security_test_external_master_start.sh security_test_config_client_external_deny.json --deny + ) + +endif() diff --git a/test/network_tests/security_tests/security_test_external_master_start.sh b/test/network_tests/security_tests/conf/security_test_external_master_start.sh.in similarity index 94% rename from test/network_tests/security_tests/security_test_external_master_start.sh rename to test/network_tests/security_tests/conf/security_test_external_master_start.sh.in index fae63a7a6..1082bee3e 100755 --- a/test/network_tests/security_tests/security_test_external_master_start.sh +++ b/test/network_tests/security_tests/conf/security_test_external_master_start.sh.in @@ -26,7 +26,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=$1 export VSOMEIP_APPLICATION_NAME=routingmanagerd # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! export VSOMEIP_CONFIGURATION=$1 @@ -37,7 +37,7 @@ PID_CLIENT=$! if [ ! -z "$USE_LXC_TEST" ]; then echo "starting external security test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./security_test_external_slave_start.sh $SERVICE_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/network_tests/security_tests; ./security_test_external_slave_start.sh $SERVICE_JSON_FILE $2\"" & elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./security_test_external_slave_start.sh $SERVICE_JSON_FILE $2" & else diff --git a/test/network_tests/security_tests/security_test_external_slave_start.sh b/test/network_tests/security_tests/conf/security_test_external_slave_start.sh.in similarity index 96% rename from test/network_tests/security_tests/security_test_external_slave_start.sh rename to test/network_tests/security_tests/conf/security_test_external_slave_start.sh.in index 3c324d59f..cff571410 100755 --- a/test/network_tests/security_tests/security_test_external_slave_start.sh +++ b/test/network_tests/security_tests/conf/security_test_external_slave_start.sh.in @@ -25,7 +25,7 @@ FAIL=0 export VSOMEIP_CONFIGURATION=$1 export VSOMEIP_APPLICATION_NAME=routingmanagerd # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! export VSOMEIP_CONFIGURATION=$1 diff --git a/test/network_tests/security_tests/security_test_local_start.sh b/test/network_tests/security_tests/conf/security_test_local_start.sh.in similarity index 92% rename from test/network_tests/security_tests/security_test_local_start.sh rename to test/network_tests/security_tests/conf/security_test_local_start.sh.in index 421788e88..d8ba23347 100755 --- a/test/network_tests/security_tests/security_test_local_start.sh +++ b/test/network_tests/security_tests/conf/security_test_local_start.sh.in @@ -8,7 +8,7 @@ export VSOMEIP_CONFIGURATION=security_test_local_config.json export VSOMEIP_APPLICATION_NAME=routingmanagerd # start daemon -../../examples/routingmanagerd/routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! sleep 1 diff --git a/test/network_tests/security_tests/security_test_client.cpp b/test/network_tests/security_tests/security_test_client.cpp index 2890e74bf..9c3c3dd63 100644 --- a/test/network_tests/security_tests/security_test_client.cpp +++ b/test/network_tests/security_tests/security_test_client.cpp @@ -3,6 +3,8 @@ // 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 "security_test_client.hpp" static bool is_remote_test = false; diff --git a/test/network_tests/security_tests/security_test_service.cpp b/test/network_tests/security_tests/security_test_service.cpp index fdfb48bee..7843504b8 100644 --- a/test/network_tests/security_tests/security_test_service.cpp +++ b/test/network_tests/security_tests/security_test_service.cpp @@ -3,6 +3,8 @@ // 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 "security_test_service.hpp" static bool is_remote_test = false; diff --git a/test/network_tests/someip_test_globals.hpp b/test/network_tests/someip_test_globals.hpp index 4f1a363b5..adaf6849f 100644 --- a/test/network_tests/someip_test_globals.hpp +++ b/test/network_tests/someip_test_globals.hpp @@ -23,6 +23,9 @@ constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID = 0x1234; constexpr vsomeip::instance_t TEST_SERVICE_INSTANCE_ID = 0x5678; constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID = 0x8421; constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID_SHUTDOWN = 0x7777; +constexpr vsomeip::method_t TEST_SERVICE_DETACH_METHOD_ID_LOOP_LONG = 0x8887; +constexpr vsomeip::method_t TEST_SERVICE_DETACH_METHOD_ID_LOOP_SHORT = 0x8888; +constexpr vsomeip::method_t TEST_SERVICE_DETACH_METHOD_ID = 0x8889; constexpr vsomeip::client_t TEST_SERVICE_CLIENT_ID = 0x1277; // Client local @@ -45,6 +48,7 @@ constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS = 32; constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS = 32; +constexpr std::uint32_t NUMBER_OF_CLIENTS_TO_REQUEST_SHUTDOWN = 4; } #endif /* SOMEIP_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/someip_tp_tests/CMakeLists.txt b/test/network_tests/someip_tp_tests/CMakeLists.txt new file mode 100644 index 000000000..53d72f7ee --- /dev/null +++ b/test/network_tests/someip_tp_tests/CMakeLists.txt @@ -0,0 +1,109 @@ +# Copyright (C) 2023 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(someip_tp_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + someip_tp_test_master.json + someip_tp_test_master_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(someip_tp_test_service + someip_tp_test_service.cpp +) + +# Add test executable. +set(service_discovery_sources + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/configuration_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/entry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/eventgroupentry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ip_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ipv4_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/ipv6_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/load_balancing_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/message_element_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/message_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/protection_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/selective_option_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/serviceentry_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/service_discovery/src/unknown_option_impl.cpp +) +set(message_sources + ${CMAKE_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${CMAKE_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${CMAKE_SOURCE_DIR}/implementation/message/src/payload_impl.cpp +) +set(endpoint_sources + ${CMAKE_SOURCE_DIR}/implementation/endpoints/src/tp.cpp + ${CMAKE_SOURCE_DIR}/implementation/endpoints/src/tp_reassembler.cpp + ${CMAKE_SOURCE_DIR}/implementation/endpoints/src/tp_message.cpp +) +add_executable(someip_tp_test_msg_sender + someip_tp_test_msg_sender.cpp + ${service_discovery_sources} + ${message_sources} + ${endpoint_sources} +) + +# Link vsomeip-sd to test executable. +target_link_libraries(someip_tp_test_msg_sender + ${VSOMEIP_NAME}-sd +) + +# Add build dependencies and link libraries to executables. +set(executables + someip_tp_test_service + someip_tp_test_msg_sender +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME someip_tp_test_in_sequence + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/someip_tp_test_master_starter.sh IN_SEQUENCE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME someip_tp_test_mixed + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/someip_tp_test_master_starter.sh MIXED + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME someip_tp_test_incomplete + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/someip_tp_test_master_starter.sh INCOMPLETE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME someip_tp_test_duplicate + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/someip_tp_test_master_starter.sh DUPLICATE + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME someip_tp_test_overlap + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/someip_tp_test_master_starter.sh OVERLAP + TIMEOUT 180 +) + +# Add custom test command. +add_custom_test( + NAME someip_tp_test_overlap_front_back + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/someip_tp_test_master_starter.sh OVERLAP_FRONT_BACK + TIMEOUT 180 +) diff --git a/test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in index 6d20e54d0..b3f9ee436 100644 --- a/test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in +++ b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in @@ -25,7 +25,6 @@ { "service":"0x6767", "instance":"0x1", - "unicast" : "@TEST_IP_SLAVE@", "unreliable":"40001", "someip-tp" : { "client-to-service": [ "0x6767", "0x8001" ] diff --git a/test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in index 0064899ec..46e3ced4e 100755 --- a/test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in +++ b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in @@ -17,7 +17,7 @@ fi TESTMODE=$1 export VSOMEIP_CONFIGURATION=someip_tp_test_master.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! # Start the services ./someip_tp_test_service $1 & @@ -28,7 +28,7 @@ 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/network_tests; ./someip_tp_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $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/network_tests/someip_tp_tests; ./someip_tp_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\"" & echo "remote ssh pid: $!" elif [ ! -z "$USE_DOCKER" ]; then echo "Waiting for 5s" diff --git a/test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp b/test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp index 3f79ce6ff..f097f43c2 100644 --- a/test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp +++ b/test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp @@ -14,7 +14,7 @@ #include #include -#if defined(__linux__) || defined(ANDROID) +#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) #include #endif @@ -24,7 +24,7 @@ #include -#include "../../implementation/utility/include/byteorder.hpp" +#include "../../implementation/utility/include/bithelper.hpp" #include "../../implementation/message/include/deserializer.hpp" #include "../../implementation/message/include/serializer.hpp" #include "../../implementation/service_discovery/include/service_discovery.hpp" @@ -271,11 +271,7 @@ class someip_tp : public ::testing::TestWithParam { _seg->insert(_seg->begin() + VSOMEIP_TP_PAYLOAD_POS, _amount, 0xff); // decrease offset by amount - const vsomeip::tp::tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 1], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 2], - (*_seg)[VSOMEIP_TP_HEADER_POS_MAX]); + const vsomeip::tp::tp_header_t its_tp_header = vsomeip::bithelper::read_uint32_be(&(*_seg)[VSOMEIP_TP_HEADER_POS_MIN]); std::uint32_t its_offset = vsomeip::tp::tp::get_offset(its_tp_header); its_offset -= _amount; const vsomeip::tp::tp_header_t its_new_tp_header = @@ -311,11 +307,7 @@ class someip_tp : public ::testing::TestWithParam { } _seg->erase(_seg->begin() + VSOMEIP_TP_PAYLOAD_POS, _seg->begin() + VSOMEIP_TP_PAYLOAD_POS + _amount); // increase offset by amount - const vsomeip::tp::tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 1], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 2], - (*_seg)[VSOMEIP_TP_HEADER_POS_MAX]); + const vsomeip::tp::tp_header_t its_tp_header = vsomeip::bithelper::read_uint32_be(&(*_seg)[VSOMEIP_TP_HEADER_POS_MIN]); std::uint32_t its_offset = vsomeip::tp::tp::get_offset(its_tp_header); its_offset += _amount; const vsomeip::tp::tp_header_t its_new_tp_header = @@ -422,10 +414,9 @@ TEST_P(someip_tp, send_in_mode) return; } else { vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[VSOMEIP_METHOD_POS_MIN]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { vsomeip::sd::message_impl sd_msg; EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); @@ -540,18 +531,15 @@ TEST_P(someip_tp, send_in_mode) std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be( + &receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + std::cout << __LINE__ << ": received response " << its_message_size << std::endl; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); vsomeip::message_impl msg; EXPECT_TRUE(msg.deserialize(&its_deserializer)); @@ -857,9 +845,7 @@ TEST_P(someip_tp, send_in_mode) EXPECT_EQ(someip_tp_test::number_of_fragments, fragments_event_from_master_.size()); // create complete message from event vsomeip::message_buffer_t its_event = create_full_message(fragments_event_from_master_); - vsomeip::session_t its_event_session = - VSOMEIP_BYTES_TO_WORD(its_event[VSOMEIP_SESSION_POS_MIN], - its_event[VSOMEIP_SESSION_POS_MAX]); + vsomeip::session_t its_event_session = vsomeip::bithelper::read_uint16_be(&its_event[VSOMEIP_SESSION_POS_MIN]); std::vector its_cmp_event_fragments; create_fragments(someip_tp_test::number_of_fragments, @@ -1095,12 +1081,9 @@ TEST_P(someip_tp, send_in_mode) someip_tp_test::number_of_fragments * someip_tp_test::max_segment_size, its_request.size()); } - const vsomeip::client_t its_request_client = - VSOMEIP_BYTES_TO_WORD(its_request[VSOMEIP_CLIENT_POS_MIN], - its_request[VSOMEIP_CLIENT_POS_MAX]); - const vsomeip::session_t its_request_session = - VSOMEIP_BYTES_TO_WORD(its_request[VSOMEIP_SESSION_POS_MIN], - its_request[VSOMEIP_SESSION_POS_MAX]); + const vsomeip::client_t its_request_client = vsomeip::bithelper::read_uint16_be(&its_request[VSOMEIP_CLIENT_POS_MIN]); + const vsomeip::session_t its_request_session = vsomeip::bithelper::read_uint16_be(&its_request[VSOMEIP_SESSION_POS_MIN]); + create_fragments(someip_tp_test::number_of_fragments, someip_tp_test::service_slave.service_id, someip_tp_test::service_slave.instance_id, @@ -1296,18 +1279,16 @@ TEST_P(someip_tp, send_in_mode) remote_client_request_port = its_remote_endpoint.port(); std::uint32_t its_pos = 0; while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + const std::uint32_t its_message_size = vsomeip::bithelper::read_uint32_be( + &receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN]) + + VSOMEIP_SOMEIP_HEADER_SIZE; + std::cout << __LINE__ << ": received request from master " << its_message_size << std::endl; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN]); + vsomeip::method_t its_method = vsomeip::bithelper::read_uint16_be(&receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN]); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); EXPECT_EQ(someip_tp_test::service_slave.service_id, its_service); EXPECT_EQ(someip_tp_test::service_slave.method_id, its_method); vsomeip::message_impl msg; diff --git a/test/network_tests/subscribe_notify_one_tests/CMakeLists.txt b/test/network_tests/subscribe_notify_one_tests/CMakeLists.txt new file mode 100644 index 000000000..e929118b4 --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/CMakeLists.txt @@ -0,0 +1,51 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(subscribe_notify_one_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + subscribe_notify_one_test_diff_client_ids_diff_ports_master.json + subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json + subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json + subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json + subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json + subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json + subscribe_notify_one_test_master_starter.sh + subscribe_notify_one_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(subscribe_notify_one_test_service + subscribe_notify_one_test_service.cpp +) + +# Add build dependencies and link libraries to executables. +targets_add_default_dependencies(subscribe_notify_one_test_service) +targets_link_default_libraries(subscribe_notify_one_test_service) + +# Add custom test command. +add_custom_test( + NAME subscribe_notify_one_test_diff_client_ids_diff_ports_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/subscribe_notify_one_test_master_starter.sh + UDP subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json +) + +# Add custom test command. +add_custom_test( + NAME subscribe_notify_one_test_diff_client_ids_diff_ports_tcp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/subscribe_notify_one_test_master_starter.sh + TCP subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json +) + +# Add custom test command. +add_custom_test( + NAME subscribe_notify_one_test_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/subscribe_notify_one_test_master_starter.sh + TCP_AND_UDP subscribe_notify_one_test_diff_client_ids_diff_ports_master.json +) diff --git a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_master_starter.sh.in similarity index 95% rename from test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_master_starter.sh.in index 8569a10b9..ab573ba42 100755 --- a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh +++ b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_master_starter.sh.in @@ -42,7 +42,7 @@ sleep 3 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/network_tests; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $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/network_tests/subscribe_notify_one_tests; ./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 $RELIABILITY_TYPE $CLIENT_JSON_FILE" & diff --git a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_slave_starter.sh.in similarity index 100% rename from test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh rename to test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_slave_starter.sh.in diff --git a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter_qnx.sh b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter_qnx.sh deleted file mode 100755 index d24cae19d..000000000 --- a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter_qnx.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# Copyright (C) 2015-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 2 ] -then - 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 -RELIABILITY_TYPE=$1 -MASTER_JSON_FILE=$2 -CLIENT_JSON_FILE="" - -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 $RELIABILITY_TYPE & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_two -export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./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 $RELIABILITY_TYPE & - -sleep 3 - -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/network_tests; ./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 $RELIABILITY_TYPE $CLIENT_JSON_FILE" & -else - cat < its_lock(mutex_); wait_until_registered_ = false; - condition_.notify_one(); } + condition_.notify_one(); } void on_availability(vsomeip::service_t _service, @@ -155,8 +155,8 @@ class subscribe_notify_test_service : public vsomeip_utilities::base_logger { return v.second;})) { std::lock_guard its_lock(mutex_); wait_until_other_services_available_ = false; - condition_.notify_one(); } + condition_.notify_one(); } } @@ -202,9 +202,9 @@ class subscribe_notify_test_service : public vsomeip_utilities::base_logger { // notify the notify thread to start sending out notifications std::lock_guard its_lock(notify_mutex_); wait_for_notify_ = false; - notify_condition_.notify_one(); notified = true; } + notify_condition_.notify_one(); return true; } @@ -241,8 +241,8 @@ class subscribe_notify_test_service : public vsomeip_utilities::base_logger { if(all_notifications_received()) { std::lock_guard its_lock(stop_mutex_); wait_for_stop_ = false; - stop_condition_.notify_one(); } + stop_condition_.notify_one(); } } @@ -389,8 +389,8 @@ class subscribe_notify_test_service : public vsomeip_utilities::base_logger { { std::lock_guard its_lock(mutex_); wait_until_notified_from_other_services_ = false; - condition_.notify_one(); } + condition_.notify_one(); stop_offer(); diff --git a/test/network_tests/suspend_resume_tests/CMakeLists.txt b/test/network_tests/suspend_resume_tests/CMakeLists.txt new file mode 100644 index 000000000..91d1d79e5 --- /dev/null +++ b/test/network_tests/suspend_resume_tests/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2023-2024 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/. + +cmake_minimum_required(VERSION 3.4...3.22) + +project(suspend_resume_tests LANGUAGES CXX) + +# Configure necessary files into the build folder. +set(configuration_files + suspend_resume_test_client.json + suspend_resume_test_master_starter.sh + suspend_resume_test_service.json + suspend_resume_test_slave_starter.sh +) +configure_files("${configuration_files}") + +# Add test executable. +add_executable(suspend_resume_test_service + suspend_resume_test_service.cpp +) + +# Add test executable. +add_executable(suspend_resume_test_client + suspend_resume_test_client.cpp +) + +# Add build dependencies and link libraries to executables. +set(executables + suspend_resume_test_service + suspend_resume_test_client +) +targets_add_default_dependencies("${executables}") +targets_link_default_libraries("${executables}") + +# Add custom test command. +add_custom_test( + NAME suspend_resume_test_initial + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/suspend_resume_test_master_starter.sh SERVICE +) diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_master_starter.sh.in similarity index 87% rename from test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh rename to test/network_tests/suspend_resume_tests/conf/suspend_resume_test_master_starter.sh.in index 44b1b7485..cc1c51c37 100755 --- a/test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh +++ b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_master_starter.sh.in @@ -17,18 +17,21 @@ export VSOMEIP_APPLICATION_NAME=suspend_resume_test_service export VSOMEIP_CONFIGURATION=suspend_resume_test_service.json # start daemon -../../examples/routingmanagerd/./routingmanagerd & +echo -e "[TEST-sh]: Starting RoutingManager" +../../../examples/routingmanagerd/routingmanagerd & PID_VSOMEIPD=$! # start the service +echo -e "\n\n[TEST-sh]: Started RoutingManager with PID=$PID_VSOMEIPD" ./suspend_resume_test_service $PID_VSOMEIPD & PID_SERVICE=$! +echo -e "\n\n[TEST-sh]: Started Service with PID=$PID_SERVICE \n\n" sleep 1 if [ ! -z "$USE_LXC_TEST" ]; then echo "starting suspend_resume_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/network_tests; ./suspend_resume_test_slave_starter.sh\"" & + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests/suspend_resume_tests; ./suspend_resume_test_slave_starter.sh\"" & echo "remote ssh job id: $!" elif [ ! -z "$USE_DOCKER" ]; then docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./suspend_resume_test_slave_starter.sh" & diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_slave_starter.sh b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_slave_starter.sh.in similarity index 100% rename from test/network_tests/suspend_resume_tests/suspend_resume_test_slave_starter.sh rename to test/network_tests/suspend_resume_tests/conf/suspend_resume_test_slave_starter.sh.in diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp index 552ddea5e..092a01f8d 100644 --- a/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp @@ -39,6 +39,7 @@ class suspend_resume_test_client : public vsomeip_utilities::base_logger { VSOMEIP_DEBUG << "Started."; std::unique_lock its_lock(mutex_); auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + VSOMEIP_DEBUG << "[TEST-cli] App Started: r=" << static_cast(r); EXPECT_EQ(r, std::cv_status::no_timeout); } @@ -49,23 +50,28 @@ class suspend_resume_test_client : public vsomeip_utilities::base_logger { std::unique_lock its_lock(mutex_); if (!has_received_) { auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + VSOMEIP_DEBUG << "[TEST-cli] First Receive Validation: r=" << static_cast(r); EXPECT_EQ(r, std::cv_status::no_timeout); + } else { + VSOMEIP_DEBUG << "[TEST-cli] Jumped received validation"; } } + VSOMEIP_DEBUG << "[TEST-cli] Sending suspend/resume: "; send_suspend(); bool was_successful; { VSOMEIP_DEBUG << "Triggered suspend/resume."; - // Wait for service to become availaber after suspend/resume. std::unique_lock its_lock(mutex_); auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + VSOMEIP_DEBUG << "[TEST-cli] Service Available after susp/resume: r=" << static_cast(r); EXPECT_EQ(r, std::cv_status::no_timeout); // Wait for initial event after suspend/resume. r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + VSOMEIP_DEBUG << "[TEST-cli] After susp/resume event validation: r=" << static_cast(r); EXPECT_EQ(r, std::cv_status::no_timeout); was_successful = (r == std::cv_status::no_timeout); @@ -141,11 +147,13 @@ class suspend_resume_test_client : public vsomeip_utilities::base_logger { VSOMEIP_DEBUG << __func__ << ": Test service is " << (_is_available ? "available." : "NOT available."); - if (_is_available) + if (_is_available) { + VSOMEIP_DEBUG << "[TEST-cli] On availability will trigger cv"; cv_.notify_one(); - else if (is_available) + } else if (is_available) { + VSOMEIP_DEBUG << "[TEST-cli] On availability=false, clearing has_received"; has_received_ = false; - + } is_available = _is_available; } } @@ -159,21 +167,23 @@ class suspend_resume_test_client : public vsomeip_utilities::base_logger { VSOMEIP_DEBUG << __func__ << ": Received event."; if (!has_received_) { has_received_ = true; + VSOMEIP_DEBUG << "[TEST-cli] HasReceived Changed, triggering cv"; cv_.notify_one(); } } } void toggle() { - + VSOMEIP_DEBUG << "[TEST-cli] Toggle Start"; app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); std::this_thread::sleep_for(std::chrono::seconds(3)); + VSOMEIP_DEBUG << "[TEST-cli] Toggle Middle"; app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); std::this_thread::sleep_for(std::chrono::seconds(2)); app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); - + VSOMEIP_DEBUG << "[TEST-cli] Toggle End"; } @@ -235,6 +245,7 @@ TEST(suspend_resume_test, fast) #if defined(__linux__) || defined(ANDROID) || defined(__QNX__) int main(int argc, char** argv) { + VSOMEIP_DEBUG << "[TEST-cli] Starting Client"; ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_service.cpp b/test/network_tests/suspend_resume_tests/suspend_resume_test_service.cpp index 6f099ce7c..68a1c829c 100644 --- a/test/network_tests/suspend_resume_tests/suspend_resume_test_service.cpp +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_service.cpp @@ -3,10 +3,11 @@ // 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 @@ -130,7 +131,7 @@ class suspend_resume_test_service : public vsomeip_utilities::base_logger { // handler void on_state(vsomeip::state_type_e _state) { - VSOMEIP_DEBUG << __func__ << ": state=" + VSOMEIP_DEBUG << __func__ << "[TEST-srv]: state=" << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : "NOT registered."); @@ -141,7 +142,7 @@ class suspend_resume_test_service : public vsomeip_utilities::base_logger { void on_message(const std::shared_ptr &_message) { - VSOMEIP_DEBUG << __func__ << ": Received " + VSOMEIP_DEBUG << __func__ << "[TEST-srv]: Received " << std::hex << std::setw(4) << std::setfill('0') << _message->get_service() << std::hex << std::setw(4) << std::setfill('0') @@ -179,7 +180,7 @@ class suspend_resume_test_service : public vsomeip_utilities::base_logger { (void)_uid; (void)_gid; - VSOMEIP_DEBUG << __func__ << ": is_subscribe=" << std::boolalpha << _is_subscribe; + VSOMEIP_DEBUG << __func__ << "[TEST-srv]: is_subscribe=" << std::boolalpha << _is_subscribe; if (!_is_subscribe) std::this_thread::sleep_for(std::chrono::milliseconds(2000)); return true; diff --git a/test/unit_tests/CMakeLists.txt b/test/unit_tests/CMakeLists.txt index 662867240..2dfca14b6 100644 --- a/test/unit_tests/CMakeLists.txt +++ b/test/unit_tests/CMakeLists.txt @@ -1,32 +1,16 @@ -# Copyright (C) 2015-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2015-2024 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/. -project ("unit_tests_bin" LANGUAGES CXX) +project("unit_tests_bin" LANGUAGES CXX) -file (GLOB SRCS main.cpp **/*.cpp) - -set(THREADS_PREFER_PTHREAD_FLAG ON) - -find_package(Threads REQUIRED) -find_package(Boost 1.55 COMPONENTS filesystem system REQUIRED) - -# ---------------------------------------------------------------------------- -# Executable and libraries to link -# ---------------------------------------------------------------------------- -add_executable (${PROJECT_NAME} ${SRCS} ) -target_link_libraries ( - ${PROJECT_NAME} - vsomeip3 - vsomeip3-cfg - Threads::Threads - ${Boost_LIBRARIES} - ${DL_LIBRARY} - gtest - vsomeip_utilities -) -enable_testing() -add_test(NAME ${PROJECT_NAME} COMMAND $ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - -add_dependencies(build_unit_tests ${PROJECT_NAME}) +add_subdirectory(message_payload_impl_tests) +add_subdirectory(message_serializer_tests) +add_subdirectory(message_deserializer_tests) +add_subdirectory(protocol_tests) +add_subdirectory(routing_manager_tests) +add_subdirectory(security_policy_manager_impl_tests) +add_subdirectory(security_policy_tests) +add_subdirectory(security_tests) +add_subdirectory(utility_utility_tests) diff --git a/test/unit_tests/main.cpp b/test/unit_tests/main.cpp index 3f704af2b..00ed93a65 100644 --- a/test/unit_tests/main.cpp +++ b/test/unit_tests/main.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2024 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/. @@ -8,9 +8,5 @@ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); - // Test execution - int ret = RUN_ALL_TESTS(); - - // Exit - return ret; -} \ No newline at end of file + return RUN_ALL_TESTS(); +} diff --git a/test/unit_tests/message_deserializer_tests/CMakeLists.txt b/test/unit_tests/message_deserializer_tests/CMakeLists.txt new file mode 100644 index 000000000..caebfe9da --- /dev/null +++ b/test/unit_tests/message_deserializer_tests/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_message_deserializer_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + Threads::Threads + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + vsomeip_utilities +) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/message_deserializer_tests/ut_deserialize.cpp b/test/unit_tests/message_deserializer_tests/ut_deserialize.cpp new file mode 100644 index 000000000..c33d0b408 --- /dev/null +++ b/test/unit_tests/message_deserializer_tests/ut_deserialize.cpp @@ -0,0 +1,530 @@ +// Copyright (C) 2024 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 "../../../implementation/message/include/deserializer.hpp" +#include "../../../implementation/utility/include/bithelper.hpp" + +namespace { + constexpr std::uint32_t buffer_shrink_threshold = 1; + constexpr std::uint8_t array_size = 4; + const vsomeip_v3::byte_t byte1 = 1; + const vsomeip_v3::byte_t byte2 = 2; + const vsomeip_v3::byte_t byte3 = 3; + const vsomeip_v3::byte_t byte4 = 4; + const bool omit_last_byte = true; + const bool dont_omit_last_byte = false; +} + +TEST(deserialize_test, deserialize_get_available) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Testing the correct array size is returned. + ASSERT_EQ(its_deserializer->get_available(), array_size); + ASSERT_EQ(its_deserializer->get_available(), its_deserializer->get_remaining()); +} + +TEST(deserialize_test, deserialize_set_get_remaining) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Testing the correct remaining length is returned after every step. + vsomeip_v3::byte_t deserialized_byte_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(its_deserializer->get_remaining(), 3); + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(its_deserializer->get_remaining(), 2); + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(its_deserializer->get_remaining(), 1); + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(its_deserializer->get_remaining(), 0); + + // Setting the remaining size to array size to test setter. + its_deserializer->set_remaining(array_size); + ASSERT_EQ(its_deserializer->get_remaining(), array_size); + ASSERT_NE(its_deserializer->get_remaining(), 0); +} + +TEST(deserialize_test, deserialize_from_uint8) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Deserialize data 1 byte (uint8_t) at a time and check against expected value. + vsomeip_v3::byte_t deserialized_byte_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(deserialized_byte_, byte1); + ASSERT_NE(deserialized_byte_, byte4); + + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(deserialized_byte_, byte2); + ASSERT_NE(deserialized_byte_, byte3); + + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(deserialized_byte_, byte3); + ASSERT_NE(deserialized_byte_, byte2); + + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(deserialized_byte_, byte4); + ASSERT_NE(deserialized_byte_, byte1); +} + +TEST(deserialize_test, deserialize_from_uint16) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + // Create arrays to use with bithelper. + std::array uint16_array_1_{byte1, byte2}; + std::array uint16_array_2_{byte3, byte4}; + + // Creating two uint16_t with the data from the byte_array. + std::uint16_t uint16_1 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_1_.data()); + std::uint16_t uint16_2 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_2_.data()); + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Deserialize 2 uint16_t from the data, and compare them with their expected values. + std::uint16_t deserialized_uint16_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_uint16_)); + ASSERT_EQ(deserialized_uint16_, uint16_1); + ASSERT_NE(deserialized_uint16_, uint16_2); + + ASSERT_TRUE(its_deserializer->deserialize(deserialized_uint16_)); + ASSERT_EQ(deserialized_uint16_, uint16_2); + ASSERT_NE(deserialized_uint16_, uint16_1); +} + +TEST(deserialize_test, deserialize_from_uint32_omit_last_byte) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + // Create arrays to pass to bithelper. + std::array uint32_3_bytes_array_{0, byte1, byte2, byte3}; + std::array uint32_full_array_{byte1, byte2, byte3, byte4}; + + // Create two uint32_t from the data, one including 3 bytes and the other with the full 4 bytes + const std::uint32_t uint32_3_bytes = vsomeip_v3::bithelper::read_uint32_be(uint32_3_bytes_array_.data()); + const std::uint32_t uint32_full = vsomeip_v3::bithelper::read_uint32_be(uint32_full_array_.data()); + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Deserialize a uint32_t omitting the last byte + std::uint32_t deserialized_uint32_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_uint32_, omit_last_byte)); + ASSERT_EQ(deserialized_uint32_, uint32_3_bytes); + ASSERT_NE(deserialized_uint32_, uint32_full); +} + +TEST(deserialize_test, deserialize_from_uint32_dont_omit_last_byte) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + // Create arrays to pass to bithelper. + std::array uint32_3_bytes_array_{0, byte1, byte2, byte3}; + std::array uint32_full_array_{byte1, byte2, byte3, byte4}; + + // Create two uint32_t from the data, one including 3 bytes and the other with the full 4 bytes + const std::uint32_t uint32_3_bytes = vsomeip_v3::bithelper::read_uint32_be(uint32_3_bytes_array_.data()); + const std::uint32_t uint32_full = vsomeip_v3::bithelper::read_uint32_be(uint32_full_array_.data()); + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Deserialize a full uint32_t not omitting the last byte. + std::uint32_t deserialized_uint32_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_uint32_, dont_omit_last_byte)); + ASSERT_EQ(deserialized_uint32_, uint32_full); + ASSERT_NE(deserialized_uint32_, uint32_3_bytes); +} + +TEST(deserialize_test, deserialize_from_uint8_array_pointer_and_length) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // One shot deserialization of the full data. + std::array deserialized_byte_array_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_array_.data(), deserialized_byte_array_.size())); + + // Check deserialized data for endianness and expected values. + ASSERT_EQ(deserialized_byte_array_.at(0), byte1); + ASSERT_EQ(deserialized_byte_array_.at(1), byte2); + ASSERT_EQ(deserialized_byte_array_.at(2), byte3); + ASSERT_EQ(deserialized_byte_array_.at(3), byte4); + ASSERT_NE(deserialized_byte_array_.at(0), byte4); + ASSERT_NE(deserialized_byte_array_.at(1), byte3); + ASSERT_NE(deserialized_byte_array_.at(2), byte2); + ASSERT_NE(deserialized_byte_array_.at(3), byte1); + + // Attempt a second try with a step by step deserialization. + std::unique_ptr its_deserializer2( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Check deserialized data for endianness and expected values. + ASSERT_TRUE(its_deserializer2->deserialize(deserialized_byte_array_.data(), 2)); + ASSERT_EQ(deserialized_byte_array_.at(0), byte1); + ASSERT_EQ(deserialized_byte_array_.at(1), byte2); + ASSERT_NE(deserialized_byte_array_.at(0), byte2); + ASSERT_NE(deserialized_byte_array_.at(1), byte1); + + // Check deserialized data against expected and old values. + ASSERT_TRUE(its_deserializer2->deserialize(deserialized_byte_array_.data(), 2)); + ASSERT_EQ(deserialized_byte_array_.at(0), byte3); + ASSERT_EQ(deserialized_byte_array_.at(1), byte4); + ASSERT_NE(deserialized_byte_array_.at(0), byte1); + ASSERT_NE(deserialized_byte_array_.at(1), byte2); +} + +TEST(deserialize_test, deserialize_from_string_pointer_and_length) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // One shot deserialization of the full data. + std::string deserialized_string_ = "0000"; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_string_, array_size)); + + // Check deserialized data for endianness and expected values. + ASSERT_EQ(deserialized_string_[0], byte1); + ASSERT_EQ(deserialized_string_[1], byte2); + ASSERT_EQ(deserialized_string_[2], byte3); + ASSERT_EQ(deserialized_string_[3], byte4); + ASSERT_NE(deserialized_string_[0], byte4); + ASSERT_NE(deserialized_string_[1], byte3); + ASSERT_NE(deserialized_string_[2], byte2); + ASSERT_NE(deserialized_string_[3], byte1); + + // Attempt a second try with a step by step deserialization. + std::unique_ptr its_deserializer2( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + ASSERT_TRUE(its_deserializer2->deserialize(deserialized_string_, 2)); + + // Check deserialized data for endianness and expected values. + ASSERT_EQ(deserialized_string_[0], byte1); + ASSERT_EQ(deserialized_string_[1], byte2); + ASSERT_NE(deserialized_string_[0], byte2); + ASSERT_NE(deserialized_string_[1], byte1); + + ASSERT_TRUE(its_deserializer2->deserialize(deserialized_string_, 2)); + + // Check deserialized data against expected and old values. + ASSERT_EQ(deserialized_string_[0], byte3); + ASSERT_EQ(deserialized_string_[1], byte4); + ASSERT_NE(deserialized_string_[0], byte1); + ASSERT_NE(deserialized_string_[1], byte2); + +} + +TEST(deserialize_test, deserialize_from_uint8_t_vector) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // One shot deserialization of the full data. Creating a vector with size 4 + std::vector deserialized_vector_(4); + + ASSERT_TRUE(its_deserializer->deserialize(deserialized_vector_)); + + // Check deserialized data for endianness and expected values. + ASSERT_EQ(deserialized_vector_.at(0), byte1); + ASSERT_EQ(deserialized_vector_.at(1), byte2); + ASSERT_EQ(deserialized_vector_.at(2), byte3); + ASSERT_EQ(deserialized_vector_.at(3), byte4); + ASSERT_NE(deserialized_vector_.at(0), byte4); + ASSERT_NE(deserialized_vector_.at(1), byte3); + ASSERT_NE(deserialized_vector_.at(2), byte2); + ASSERT_NE(deserialized_vector_.at(3), byte1); + + // Attempt a second try with a step by step deserialization. + std::unique_ptr its_deserializer2( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Creating a size 2 vector + std::vector deserialized_vector2_(2); + + ASSERT_TRUE(its_deserializer2->deserialize(deserialized_vector2_)); + + // Check deserialized data for endianness and expected values. + ASSERT_EQ(deserialized_vector2_.at(0), byte1); + ASSERT_EQ(deserialized_vector2_.at(1), byte2); + ASSERT_NE(deserialized_vector2_.at(0), byte2); + ASSERT_NE(deserialized_vector2_.at(1), byte1); + + ASSERT_TRUE(its_deserializer2->deserialize(deserialized_vector2_)); + + // Check deserialized data against expected and old values. + ASSERT_EQ(deserialized_vector2_.at(0), byte3); + ASSERT_EQ(deserialized_vector2_.at(1), byte4); + ASSERT_NE(deserialized_vector2_.at(0), byte1); + ASSERT_NE(deserialized_vector2_.at(1), byte2); +} + +TEST(deserialize_test, look_ahead_for_uint8) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // look_ahead data 1 byte (uint8_t) at a time and check against expected value. + vsomeip_v3::byte_t look_ahead_byte_; + ASSERT_TRUE(its_deserializer->look_ahead(0, look_ahead_byte_)); + ASSERT_EQ(look_ahead_byte_, byte1); + ASSERT_NE(look_ahead_byte_, byte4); + + ASSERT_TRUE(its_deserializer->look_ahead(1, look_ahead_byte_)); + ASSERT_EQ(look_ahead_byte_, byte2); + ASSERT_NE(look_ahead_byte_, byte3); + + ASSERT_TRUE(its_deserializer->look_ahead(2, look_ahead_byte_)); + ASSERT_EQ(look_ahead_byte_, byte3); + ASSERT_NE(look_ahead_byte_, byte2); + + ASSERT_TRUE(its_deserializer->look_ahead(3, look_ahead_byte_)); + ASSERT_EQ(look_ahead_byte_, byte4); + ASSERT_NE(look_ahead_byte_, byte1); +} + +TEST(deserialize_test, look_ahead_for_uint16) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + // Creating the three possible uint16_t with the data from the byte_array + + // Create arrays to use with bithelper. + std::array uint16_array_1_{byte1, byte2}; + std::array uint16_array_2_{byte2, byte3}; + std::array uint16_array_3_{byte3, byte4}; + + // Creating two uint16_t with the data from the byte_array. + std::uint16_t uint16_1 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_1_.data()); + std::uint16_t uint16_2 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_2_.data()); + std::uint16_t uint16_3 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_3_.data()); + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Look_ahead uint16_t from incrementing indices and compare them with their expected values. + std::uint16_t look_ahead_uint16_; + ASSERT_TRUE(its_deserializer->look_ahead(0, look_ahead_uint16_)); + ASSERT_EQ(look_ahead_uint16_, uint16_1); + ASSERT_NE(look_ahead_uint16_, uint16_2); + + ASSERT_TRUE(its_deserializer->look_ahead(1, look_ahead_uint16_)); + ASSERT_EQ(look_ahead_uint16_, uint16_2); + ASSERT_NE(look_ahead_uint16_, uint16_1); + + ASSERT_TRUE(its_deserializer->look_ahead(2, look_ahead_uint16_)); + ASSERT_EQ(look_ahead_uint16_, uint16_3); + ASSERT_NE(look_ahead_uint16_, uint16_1); +} + +TEST(deserialize_test, look_ahead_for_uint32) { + // Extend array size + std::array byte_array_{byte1, byte2, byte3, byte4, byte1}; + + // Create arrays to pass to bithelper. + std::array uint32_1_bytes_array_{byte1, byte2, byte3, byte4}; + std::array uint32_2_bytes_array_{byte2, byte3, byte4, byte1}; + + // Creating the uint32_t with the data from the byte_array + const std::uint32_t uint32_1 = vsomeip_v3::bithelper::read_uint32_be(uint32_1_bytes_array_.data()); + const std::uint32_t uint32_2 = vsomeip_v3::bithelper::read_uint32_be(uint32_2_bytes_array_.data()); + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Look_ahead uint32_t from incrementing indices and compare them with their expected values. + std::uint32_t look_ahead_uint32_; + ASSERT_TRUE(its_deserializer->look_ahead(0, look_ahead_uint32_)); + ASSERT_EQ(look_ahead_uint32_, uint32_1); + ASSERT_NE(look_ahead_uint32_, uint32_2); + + ASSERT_TRUE(its_deserializer->look_ahead(1, look_ahead_uint32_)); + ASSERT_EQ(look_ahead_uint32_, uint32_2); + ASSERT_NE(look_ahead_uint32_, uint32_1); +} + +TEST(deserialize_test, deserialize_message) { + // Extend array size to the size of a message without options + // the 8 is the length of the header needs to be atleast 8 to offset the header length + // the last bytes are all 0 to reflect uint32_t length + std::array byte_array_{ + byte1, byte2, byte3, byte4, 0, + 0, 0, 8, byte4, byte1, + byte1, byte2, byte3, byte4, byte1, + byte1, byte2, byte3, byte4, byte1, + 0, 0, 0, 0, 0}; + + // Deserialize expected to pass. + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + auto deserialized_message = its_deserializer->deserialize_message(); + ASSERT_NE(deserialized_message, nullptr); + + std::array byte_array2_{byte1, byte2, byte3, byte4}; + std::unique_ptr its_deserializer2( + new vsomeip_v3::deserializer(byte_array2_.data(), byte_array2_.size(), buffer_shrink_threshold)); + + auto deserialized_message2 = its_deserializer2->deserialize_message(); + + // Desereialize expected to fail. + ASSERT_EQ(deserialized_message2, nullptr); +} + +TEST(deserialize_test, set_data_from_uint8_array_pointer_and_length) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Reversing the byte_array_ + std::array reverse_byte_array_{byte4, byte3, byte2, byte1}; + + // Test Method + its_deserializer->set_data(reverse_byte_array_.data(), reverse_byte_array_.size()); + + // One shot deserialization of the full data. + std::array deserialized_byte_array_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_array_.data(), deserialized_byte_array_.size())); + + // Check deserialized data expected values. + ASSERT_EQ(deserialized_byte_array_.at(0), byte4); + ASSERT_EQ(deserialized_byte_array_.at(1), byte3); + ASSERT_EQ(deserialized_byte_array_.at(2), byte2); + ASSERT_EQ(deserialized_byte_array_.at(3), byte1); + + // Attempt a second try with null array expect data to get cleared and remaining to be 0 + std::unique_ptr its_deserializer2( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + its_deserializer2->set_data(nullptr, array_size); + + // Remaining should have been set to 0 and the data cleared. + ASSERT_EQ(its_deserializer2->get_remaining(), 0); + + // Check deserialize failure. + ASSERT_FALSE(its_deserializer2->deserialize(deserialized_byte_array_.data(), deserialized_byte_array_.size())); +} + +TEST(deserialize_test, set_data_from_uint8_vector) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // One shot deserialization of the full data. Creating a vector with size 4 + std::vector uint8_vector_{byte4, byte3, byte2, byte1, byte4}; + + // Test Method + its_deserializer->set_data(uint8_vector_); + + // Remaining size should be array_size + 1 + ASSERT_EQ(its_deserializer->get_remaining(), array_size + 1); + + // One shot deserialization of the full data. + std::array deserialized_byte_array_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_array_.data(), deserialized_byte_array_.size())); + + // Check deserialized data expected values. + ASSERT_EQ(deserialized_byte_array_.at(0), byte4); + ASSERT_EQ(deserialized_byte_array_.at(1), byte3); + ASSERT_EQ(deserialized_byte_array_.at(2), byte2); + ASSERT_EQ(deserialized_byte_array_.at(3), byte1); + ASSERT_EQ(deserialized_byte_array_.at(4), byte4); +} + +TEST(deserialize_test, append_data_from_uint8_array_pointer_and_length) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Reversing the byte_array_ + std::array reverse_byte_array_{byte4, byte3, byte2, byte1}; + + // Test Method + its_deserializer->append_data(reverse_byte_array_.data(), reverse_byte_array_.size()); + + // Test remaining is twice the array length after appending + ASSERT_EQ(its_deserializer->get_remaining(), array_size * 2); + + // One shot deserialization of the full data. + std::array deserialized_byte_array_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_array_.data(), deserialized_byte_array_.size())); + + // Check deserialized data expected values. + ASSERT_EQ(deserialized_byte_array_.at(0), deserialized_byte_array_.at(7)); + ASSERT_EQ(deserialized_byte_array_.at(1), deserialized_byte_array_.at(6)); + ASSERT_EQ(deserialized_byte_array_.at(2), deserialized_byte_array_.at(5)); + ASSERT_EQ(deserialized_byte_array_.at(3), deserialized_byte_array_.at(4)); +} + +TEST(deserialize_test, drop_data) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Test Method. + its_deserializer->drop_data(1); + + // Deserialize 1 byte expect to get byte2 since we dropped byte1. + vsomeip_v3::byte_t deserialized_byte_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(deserialized_byte_, byte2); + ASSERT_NE(deserialized_byte_, byte1); + + // Test Method. + its_deserializer->drop_data(1); + + // Deserialize 1 byte expect to get byte4 since we dropped byte3. + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + ASSERT_EQ(deserialized_byte_, byte4); + ASSERT_NE(deserialized_byte_, byte3); + + // New deserializer to jump 3 spots instead of just 1 + std::unique_ptr its_deserializer2( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Test Method. + its_deserializer2->drop_data(3); + + // Deserialize 1 byte expect to get byte4 since we dropped byte1 - byte3. + ASSERT_TRUE(its_deserializer2->deserialize(deserialized_byte_)); + ASSERT_EQ(deserialized_byte_, byte4); + ASSERT_NE(deserialized_byte_, byte1); +} + +TEST(deserialize_test, reset) { + std::array byte_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_deserializer( + new vsomeip_v3::deserializer(byte_array_.data(), byte_array_.size(), buffer_shrink_threshold)); + + // Deserialize 1 byte expect to get byte2 since we dropped byte1. + vsomeip_v3::byte_t deserialized_byte_; + ASSERT_TRUE(its_deserializer->deserialize(deserialized_byte_)); + + // Expect remaining size to be 1 less than array size, since we read 1 byte. + ASSERT_EQ(its_deserializer->get_remaining(), array_size - 1); + + // Test Method. + its_deserializer->reset(); + + // Expect the size to be 0 since the data vector is now empty. + ASSERT_EQ(its_deserializer->get_remaining(), 0); +} diff --git a/test/unit_tests/message_payload_impl_tests/CMakeLists.txt b/test/unit_tests/message_payload_impl_tests/CMakeLists.txt new file mode 100644 index 000000000..aeea25cb2 --- /dev/null +++ b/test/unit_tests/message_payload_impl_tests/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_message_payload_impl_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + vsomeip_utilities +) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/message_payload_impl_tests/ut_payload_impl.cpp b/test/unit_tests/message_payload_impl_tests/ut_payload_impl.cpp new file mode 100644 index 000000000..fc6a14b41 --- /dev/null +++ b/test/unit_tests/message_payload_impl_tests/ut_payload_impl.cpp @@ -0,0 +1,128 @@ +// Copyright (C) 2024 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 "../../../implementation/message/include/deserializer.hpp" +#include "../../../implementation/message/include/payload_impl.hpp" +#include "../../../implementation/message/include/serializer.hpp" + +namespace { + const std::uint8_t array_size = 4; + const std::uint32_t buffer_shrink_threshold = 1; + const vsomeip_v3::byte_t byte1 = 1; + const vsomeip_v3::byte_t byte2 = 2; + const vsomeip_v3::byte_t byte3 = 3; + const vsomeip_v3::byte_t byte4 = 4; + +} + +TEST(payload_impl_test, equalequal_operator) { + // Create test data. + std::vector data_vector_{byte1, byte2, byte3, byte4}; + + vsomeip_v3::payload_impl its_payload_impl(data_vector_); + + std::vector data_vector2_{byte1, byte2, byte3, byte4}; + + vsomeip_v3::payload_impl its_similar_payload_impl(data_vector2_); + + std::vector data_vector3_{byte4, byte3, byte2, byte1}; + + vsomeip_v3::payload_impl its_different_payload_impl(data_vector3_); + + // Checks. + ASSERT_TRUE(its_payload_impl == its_similar_payload_impl); + ASSERT_FALSE(its_payload_impl == its_different_payload_impl); +} + +TEST(payload_impl_test, set_data) { + // Create test data. + std::vector data_vector_{byte1, byte2, byte3, byte4}; + + std::array data_array_{byte1, byte2, byte3, byte4}; + + vsomeip_v3::payload_impl its_payload_impl1; + vsomeip_v3::payload_impl its_payload_impl2; + vsomeip_v3::payload_impl its_payload_impl3; + + // Test methods. + its_payload_impl1.set_data(data_vector_); + its_payload_impl2.set_data(data_array_.data(), data_array_.size()); + its_payload_impl3.set_data(std::move(data_vector_)); + + // Checks. + ASSERT_TRUE(its_payload_impl1 == its_payload_impl2); + ASSERT_TRUE(its_payload_impl1 == its_payload_impl3); +} + +TEST(payload_impl_test, constructors) { + // Create test data. + std::vector data_vector_{byte1, byte2, byte3, byte4}; + + std::array data_array_{byte1, byte2, byte3, byte4}; + + // Test Overloaded constructors. + vsomeip_v3::payload_impl its_payload_impl1; + // Add data to the empty data. + its_payload_impl1.set_data(data_vector_); + + vsomeip_v3::payload_impl its_payload_impl2(data_vector_); + vsomeip_v3::payload_impl its_payload_impl3(data_array_.data(), data_array_.size()); + vsomeip_v3::payload_impl its_payload_impl4(its_payload_impl1); + + // Checks. + ASSERT_TRUE(its_payload_impl1 == its_payload_impl2); + ASSERT_TRUE(its_payload_impl1 == its_payload_impl3); + ASSERT_TRUE(its_payload_impl1 == its_payload_impl4); +} + +TEST(payload_impl_test, get_length) { + // Create test data. + std::array data_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_payload_impl(new vsomeip_v3::payload_impl(data_array_.data(), data_array_.size())); + + // Test method. + ASSERT_EQ(its_payload_impl->get_length(), array_size); +} + +TEST(payload_impl_test, serialize) { + // Create test data. + std::array data_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_payload_impl(new vsomeip_v3::payload_impl(data_array_.data(), data_array_.size())); + vsomeip_v3::serializer its_serializer(buffer_shrink_threshold); + + // Test method. + ASSERT_TRUE(its_payload_impl->serialize(&its_serializer)); + + // Checks. + ASSERT_EQ(its_payload_impl->get_data()[0], its_serializer.get_data()[0]); + ASSERT_EQ(its_payload_impl->get_data()[1], its_serializer.get_data()[1]); + ASSERT_EQ(its_payload_impl->get_data()[2], its_serializer.get_data()[2]); + ASSERT_EQ(its_payload_impl->get_data()[3], its_serializer.get_data()[3]); +} + +TEST(payload_impl_test, deserialize) { + // Create test data. + std::array data_array_{byte1, byte2, byte3, byte4}; + + std::unique_ptr its_payload_impl(new vsomeip_v3::payload_impl()); + vsomeip_v3::deserializer its_deserializer(data_array_.data(), data_array_.size(), buffer_shrink_threshold); + + // Test set_capacity at the same time. + its_payload_impl->set_capacity(array_size); + + // Test Method. + ASSERT_TRUE(its_payload_impl->deserialize(&its_deserializer)); + + // Checks. + ASSERT_EQ(its_payload_impl->get_length(), array_size); + ASSERT_EQ(its_payload_impl->get_data()[0], data_array_[0]); + ASSERT_EQ(its_payload_impl->get_data()[1], data_array_[1]); + ASSERT_EQ(its_payload_impl->get_data()[2], data_array_[2]); + ASSERT_EQ(its_payload_impl->get_data()[3], data_array_[3]); +} diff --git a/test/unit_tests/message_serializer_tests/CMakeLists.txt b/test/unit_tests/message_serializer_tests/CMakeLists.txt new file mode 100644 index 000000000..1fdb76c88 --- /dev/null +++ b/test/unit_tests/message_serializer_tests/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_message_serializer_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + vsomeip_utilities +) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/message_serializer_tests/ut_serialize.cpp b/test/unit_tests/message_serializer_tests/ut_serialize.cpp new file mode 100644 index 000000000..5fd1eea17 --- /dev/null +++ b/test/unit_tests/message_serializer_tests/ut_serialize.cpp @@ -0,0 +1,192 @@ +// Copyright (C) 2024 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 "../../../implementation/message/include/payload_impl.hpp" +#include "../../../implementation/message/include/serializer.hpp" +#include "../../../implementation/utility/include/bithelper.hpp" + +namespace { + const std::uint8_t uint8_num1= 1; + const std::uint8_t uint8_num2 = 2; + const std::uint8_t uint8_num3 = 3; + const std::uint16_t uint16_num1= 1; + const std::uint16_t uint16_num2 = 2; + const std::uint16_t uint16_num3 = 3; + const std::uint32_t uint32_num1= 1; + const std::uint32_t uint32_num2 = 2; + const std::uint32_t uint32_num3 = 3; + + bool omit_last_byte = true; + bool dont_omit_last_byte = false; +} + +TEST(serialize_test, serialize_from_serializable_pointer) { + std::vector data_vector_{uint8_num1, uint8_num2, uint8_num3, uint8_num1}; + + auto its_serializable = new vsomeip_v3::payload_impl(data_vector_); + + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + ASSERT_TRUE(its_serializer->serialize(its_serializable)); + ASSERT_EQ(its_serializer->get_size(), 4); +} + + +TEST(serialize_test, serialize_from_uint8) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + //add 1 2 3 to the data of the serializer. + ASSERT_TRUE(its_serializer->serialize(uint8_num1)); + ASSERT_TRUE(its_serializer->serialize(uint8_num2)); + ASSERT_TRUE(its_serializer->serialize(uint8_num3)); + + ASSERT_EQ(its_serializer->get_data()[0], uint8_num1); + ASSERT_EQ(its_serializer->get_data()[1], uint8_num2); + ASSERT_EQ(its_serializer->get_data()[2], uint8_num3); + + ASSERT_EQ(its_serializer->get_size(), 3); +} + +TEST(serialize_test, serialize_from_uint16) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + //add 1 2 3 to the data of the serializer. + ASSERT_TRUE(its_serializer->serialize(uint16_num1)); + ASSERT_TRUE(its_serializer->serialize(uint16_num2)); + ASSERT_TRUE(its_serializer->serialize(uint16_num3)); + + // Rebuilding the uint16_t from 2 uint8_t words. + std::array uint16_array_reconstructed_num1_{its_serializer->get_data()[0], its_serializer->get_data()[1]}; + std::array uint16_array_reconstructed_num2_{its_serializer->get_data()[2], its_serializer->get_data()[3]}; + std::array uint16_array_reconstructed_num3_{its_serializer->get_data()[4], its_serializer->get_data()[5]}; + + std::uint16_t reconstructed_num1 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_reconstructed_num1_.data()); + std::uint16_t reconstructed_num2 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_reconstructed_num2_.data()); + std::uint16_t reconstructed_num3 = vsomeip_v3::bithelper::read_uint16_be(uint16_array_reconstructed_num3_.data()); + + ASSERT_EQ(reconstructed_num1, uint16_num1); + ASSERT_EQ(reconstructed_num2, uint16_num2); + ASSERT_EQ(reconstructed_num3, uint16_num3); + + ASSERT_EQ(its_serializer->get_size(), 6); +} + +TEST(serialize_test, serialize_from_uint32_omit_last_byte) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + //add 1 2 3 to the data of the serializer. + ASSERT_TRUE(its_serializer->serialize(uint32_num1, omit_last_byte)); + ASSERT_TRUE(its_serializer->serialize(uint32_num2, omit_last_byte)); + ASSERT_TRUE(its_serializer->serialize(uint32_num3, omit_last_byte)); + + // Rebuilding the uint32_t from 3 uint8_t words, since 4th byte is omited. + // Create arrays to pass to bithelper. + std::array uint32_array_reconstructed_num1_{0, its_serializer->get_data()[0], its_serializer->get_data()[1], its_serializer->get_data()[2]}; + std::array uint32_array_reconstructed_num2_{0, its_serializer->get_data()[3], its_serializer->get_data()[4], its_serializer->get_data()[5]}; + std::array uint32_array_reconstructed_num3_{0, its_serializer->get_data()[6], its_serializer->get_data()[7], its_serializer->get_data()[8]}; + + // Create uint32_t from bytes. + const std::uint32_t reconstructed_num1 = vsomeip_v3::bithelper::read_uint32_be(uint32_array_reconstructed_num1_.data()); + const std::uint32_t reconstructed_num2 = vsomeip_v3::bithelper::read_uint32_be(uint32_array_reconstructed_num2_.data()); + const std::uint32_t reconstructed_num3 = vsomeip_v3::bithelper::read_uint32_be(uint32_array_reconstructed_num3_.data()); + + ASSERT_EQ(reconstructed_num1, uint32_num1); + ASSERT_EQ(reconstructed_num2, uint32_num2); + ASSERT_EQ(reconstructed_num3, uint32_num3); + + ASSERT_EQ(its_serializer->get_size(), 9); +} + +TEST(serialize_test, serialize_from_uint32_dont_omit_last_byte) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + //add 1 2 3 to the data of the serializer. + ASSERT_TRUE(its_serializer->serialize(uint32_num1, dont_omit_last_byte)); + ASSERT_TRUE(its_serializer->serialize(uint32_num2, dont_omit_last_byte)); + ASSERT_TRUE(its_serializer->serialize(uint32_num3, dont_omit_last_byte)); + + // Rebuilding the uint32_t from 4 uint8_t words. + // Create arrays to pass to bithelper. + std::array uint32_array_reconstructed_num1_{its_serializer->get_data()[0], its_serializer->get_data()[1], its_serializer->get_data()[2], its_serializer->get_data()[3]}; + std::array uint32_array_reconstructed_num2_{its_serializer->get_data()[4], its_serializer->get_data()[5], its_serializer->get_data()[6], its_serializer->get_data()[7]}; + std::array uint32_array_reconstructed_num3_{its_serializer->get_data()[8], its_serializer->get_data()[9], its_serializer->get_data()[10], its_serializer->get_data()[11]}; + + // Create uint32_t from bytes. + const std::uint32_t reconstructed_num1 = vsomeip_v3::bithelper::read_uint32_be(uint32_array_reconstructed_num1_.data()); + const std::uint32_t reconstructed_num2 = vsomeip_v3::bithelper::read_uint32_be(uint32_array_reconstructed_num2_.data()); + const std::uint32_t reconstructed_num3 = vsomeip_v3::bithelper::read_uint32_be(uint32_array_reconstructed_num3_.data()); + + ASSERT_EQ(reconstructed_num1, uint32_num1); + ASSERT_EQ(reconstructed_num2, uint32_num2); + ASSERT_EQ(reconstructed_num3, uint32_num3); + + ASSERT_EQ(its_serializer->get_size(), 12); +} + +TEST(serialize_test, serialize_from_uint8_array_with_length) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + std::vector data_{uint8_num1, uint8_num2, uint8_num3}; + + ASSERT_TRUE(its_serializer->serialize(data_.data(), static_cast(data_.size()))); + + ASSERT_EQ(its_serializer->get_data()[0], uint8_num1); + ASSERT_EQ(its_serializer->get_data()[1], uint8_num2); + ASSERT_EQ(its_serializer->get_data()[2], uint8_num3); + + ASSERT_EQ(its_serializer->get_size(), 3); +} + +TEST(serialize_test, serializer_get_capacity) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + ASSERT_GT(its_serializer->get_capacity(), 0); +} + +TEST(serialize_test, serializer_get_size) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + ASSERT_EQ(its_serializer->get_size(), 0); + ASSERT_TRUE(its_serializer->serialize(uint8_num1)); + ASSERT_EQ(its_serializer->get_size(), 1); + ASSERT_TRUE(its_serializer->serialize(uint8_num2)); + ASSERT_EQ(its_serializer->get_size(), 2); + ASSERT_TRUE(its_serializer->serialize(uint8_num3)); + ASSERT_EQ(its_serializer->get_size(), 3); +} + +TEST(serialize_test, serializer_reset) { + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + ASSERT_EQ(its_serializer->get_size(), 0); + ASSERT_TRUE(its_serializer->serialize(uint8_num1)); + ASSERT_TRUE(its_serializer->serialize(uint8_num2)); + ASSERT_TRUE(its_serializer->serialize(uint8_num3)); + ASSERT_EQ(its_serializer->get_size(), 3); + + its_serializer->reset(); + ASSERT_EQ(its_serializer->get_size(), 0); +} + +TEST(serialize_test, serializer_reset_shrink) { + //Not sure how this is supposed to go. + std::unique_ptr its_serializer(new vsomeip_v3::serializer(1)); + + ASSERT_TRUE(its_serializer->serialize(uint8_num1)); + ASSERT_TRUE(its_serializer->serialize(uint8_num2)); + ASSERT_TRUE(its_serializer->serialize(uint8_num3)); + ASSERT_EQ(its_serializer->get_size(), 3); + + its_serializer->reset(); + + ASSERT_TRUE(its_serializer->serialize(uint8_num1)); + ASSERT_TRUE(its_serializer->serialize(uint8_num2)); + ASSERT_TRUE(its_serializer->serialize(uint8_num3)); + ASSERT_EQ(its_serializer->get_size(), 3); + + its_serializer->reset(); + ASSERT_EQ(its_serializer->get_size(), 0); +} diff --git a/test/unit_tests/protocol_tests/CMakeLists.txt b/test/unit_tests/protocol_tests/CMakeLists.txt new file mode 100644 index 000000000..0bb739dbe --- /dev/null +++ b/test/unit_tests/protocol_tests/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (C) 2024 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/. + +project("unit_tests_protocol_tests" LANGUAGES CXX) + +file(GLOB TEST_SRCS main.cpp *.cpp) + +# We need to set the source files directly because vsomeip doesn't export the +# commands for linking. +set( + VSIP_SRCS + ../../../implementation/protocol/src/config_command.cpp + ../../../implementation/protocol/src/command.cpp +) + +add_executable( + ${PROJECT_NAME} + ${TEST_SRCS} + ${VSIP_SRCS} +) + +target_link_libraries( + ${PROJECT_NAME} + gtest +) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) + +add_test( + NAME ${PROJECT_NAME} + COMMAND ${PROJECT_NAME} +) diff --git a/test/unit_tests/protocol_tests/main.cpp b/test/unit_tests/protocol_tests/main.cpp new file mode 100644 index 000000000..531b4f656 --- /dev/null +++ b/test/unit_tests/protocol_tests/main.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2024 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 + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/unit_tests/protocol_tests/ut_config_command.cpp b/test/unit_tests/protocol_tests/ut_config_command.cpp new file mode 100644 index 000000000..392fc7b86 --- /dev/null +++ b/test/unit_tests/protocol_tests/ut_config_command.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2024 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 "../../../implementation/protocol/include/config_command.hpp" +#include "../../../implementation/protocol/include/protocol.hpp" + +namespace config_command_tests { + +// Tester Note: Expect Little-Endian representation for serialized data. +const std::vector serialized_config_command = { + 0x31, // config_command + 0x00, 0x00, // Version. + 0x01, 0x00, // Client. + 0x20, 0x00, 0x00, 0x00, // Size. + // Configurations. + 0x04, 0x00, 0x00, 0x00, // Key size. + 0x61, 0x62, 0x63, 0x64, // "abcd" + 0x04, 0x00, 0x00, 0x00, // Value size. + 0x31, 0x32, 0x33, 0x34, // "1234" + 0x04, 0x00, 0x00, 0x00, // Key size. + 0x65, 0x66, 0x67, 0x68, // "efgh" + 0x04, 0x00, 0x00, 0x00, // Value size. + 0x35, 0x36, 0x37, 0x38 // "5678" +}; + +TEST(config_command_test, accessors) { + vsomeip_v3::protocol::config_command command; + ASSERT_FALSE(command.contains("abcd")); + command.insert("abcd", "1234"); + ASSERT_TRUE(command.contains("abcd")); + ASSERT_EQ(command.at("abcd"), "1234"); +} + +TEST(config_command_test, serialize) { + vsomeip_v3::protocol::config_command command; + command.set_client(0x0001); + command.insert("abcd", "1234"); + command.insert("efgh", "5678"); + + std::vector buffer; + vsomeip_v3::protocol::error_e error; + command.serialize(buffer, error); + ASSERT_EQ(error, vsomeip_v3::protocol::error_e::ERROR_OK); + ASSERT_EQ(buffer, serialized_config_command); +} + +TEST(config_command_test, deserialize) { + vsomeip_v3::protocol::config_command command; + vsomeip_v3::protocol::error_e error; + command.deserialize(serialized_config_command, error); + ASSERT_EQ(error, vsomeip_v3::protocol::error_e::ERROR_OK); + ASSERT_EQ(command.configs().size(), 2); + EXPECT_EQ(command.configs().at("abcd"), "1234"); + EXPECT_EQ(command.configs().at("efgh"), "5678"); +} + +} // namespace config_command_tests diff --git a/test/unit_tests/routing_manager_tests/CMakeLists.txt b/test/unit_tests/routing_manager_tests/CMakeLists.txt new file mode 100644 index 000000000..b650ddbca --- /dev/null +++ b/test/unit_tests/routing_manager_tests/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_routing_manager_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp mocks/*.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + Threads::Threads + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + gmock + vsomeip_utilities +) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/routing_manager_tests/mocks/mock_routing_manager_host.hpp b/test/unit_tests/routing_manager_tests/mocks/mock_routing_manager_host.hpp new file mode 100644 index 000000000..3ff83996b --- /dev/null +++ b/test/unit_tests/routing_manager_tests/mocks/mock_routing_manager_host.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2024 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 "../../../../implementation/routing/include/routing_manager_host.hpp" + +using namespace vsomeip_v3; +class mock_routing_manager_host : public routing_manager_host { +public: + + MOCK_METHOD(client_t, get_client, (), (const, override)); + MOCK_METHOD(void, set_client, (const client_t &_client), (override)); + MOCK_METHOD(session_t, get_session, (bool _is_request), (override)); + + MOCK_METHOD(const vsomeip_sec_client_t* ,get_sec_client, (), (const, override)); + MOCK_METHOD(void, set_sec_client_port, (port_t _port), (override)); + + MOCK_METHOD(const std::string &, get_name, (), (const, override)); + MOCK_METHOD(std::shared_ptr, get_configuration, (), (const, override)); + MOCK_METHOD(boost::asio::io_context &, get_io, (), (override)); + + MOCK_METHOD(void, on_availability, (service_t _service, instance_t _instance, + availability_state_e _state, + major_version_t _major, + minor_version_t _minor), (override)); + MOCK_METHOD(void, on_state, (state_type_e _state), (override)); + MOCK_METHOD(void, on_message, (std::shared_ptr &&_message), (override)); + MOCK_METHOD(void, on_subscription, (service_t _service, instance_t _instance, + eventgroup_t _eventgroup, + client_t _client, const vsomeip_sec_client_t *_sec_client, + const std::string &_env, bool _subscribed, + const std::function &_accepted_cb), (override)); + MOCK_METHOD(void, on_subscription_status, (service_t _service, instance_t _instance, + eventgroup_t _eventgroup, event_t _event, uint16_t _error), (override)); + MOCK_METHOD(void, send, (std::shared_ptr _message), (override)); + MOCK_METHOD(void, on_offered_services_info, ( + (std::vector>& _services)), (override)); + MOCK_METHOD(bool, is_routing, (), (const, override)); + +}; diff --git a/test/unit_tests/routing_manager_tests/routing_manager_ut_setup.cpp b/test/unit_tests/routing_manager_tests/routing_manager_ut_setup.cpp new file mode 100644 index 000000000..324d99006 --- /dev/null +++ b/test/unit_tests/routing_manager_tests/routing_manager_ut_setup.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2024 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 "routing_manager_ut_setup.hpp" + +using ::testing::ReturnRef; +using ::testing::Return; + +void routing_manager_ut_setup::SetUp() { + configuration_ptr_ = + std::make_shared("routing_manager_ut_config.json"); + + EXPECT_CALL(mock_host_, get_io()).WillRepeatedly(ReturnRef(io_)); + EXPECT_CALL(mock_host_, get_name()).WillRepeatedly(ReturnRef(name_)); + EXPECT_CALL(mock_host_, get_configuration()).WillRepeatedly(Return(configuration_ptr_)); + + // Create a test routing manager impl, with mock_host for routing_manager_host. + its_manager = new vsomeip_v3::routing_manager_impl(&mock_host_); + + its_manager->init(); +} + +void routing_manager_ut_setup::TearDown() { + delete its_manager; + configuration_ptr_.reset(); +} diff --git a/test/unit_tests/routing_manager_tests/routing_manager_ut_setup.hpp b/test/unit_tests/routing_manager_tests/routing_manager_ut_setup.hpp new file mode 100644 index 000000000..a3e110e8b --- /dev/null +++ b/test/unit_tests/routing_manager_tests/routing_manager_ut_setup.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2024 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 ROUTING_MANAGER_UT_SETUP_HPP +#define ROUTING_MANAGER_UT_SETUP_HPP + +#include +#include +#include +#include + +#include + +#include "mocks/mock_routing_manager_host.hpp" + +class routing_manager_ut_setup : public testing::Test{ +protected : + mock_routing_manager_host mock_host_; + vsomeip_v3::routing_manager_impl* its_manager; + const std::string name_ = "RandomName"; + boost::asio::io_service io_; + std::shared_ptr configuration_ptr_; + void SetUp() override; + // Tears down the test fixture. + void TearDown() override; +}; + +#endif // ROUTING_MANAGER_UT_SETUP_HPP diff --git a/test/unit_tests/routing_manager_tests/ut_set_routing_state.cpp b/test/unit_tests/routing_manager_tests/ut_set_routing_state.cpp new file mode 100644 index 000000000..8426fa2b8 --- /dev/null +++ b/test/unit_tests/routing_manager_tests/ut_set_routing_state.cpp @@ -0,0 +1,142 @@ +// Copyright (C) 2024 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 "routing_manager_ut_setup.hpp" + +using ::testing::ReturnRef; +using ::testing::Return; +using ::testing::AtLeast; +using ::testing::_; + +namespace { + vsomeip_v3::service_t service_ = 0x1234; + vsomeip_v3::instance_t instance_ = 0x5678; + vsomeip_v3::service_t service2_ = 0x123; + vsomeip_v3::instance_t instance2_ = 0x567; + vsomeip_v3::major_version_t major_version_ = 1; + vsomeip_v3::minor_version_t minor_version_ = 1; + vsomeip_v3::ttl_t ttl_ = 3; + boost::asio::detail::array ip_bytes_= { 127, 0, 0, 1 }; + boost::asio::ip::address_v4 ip_address_(ip_bytes_); + boost::asio::detail::array ip_bytes_remote_= { 0xDE, 0xAD, 0xBE, 0xEF }; + boost::asio::ip::address_v4 ip_address_remote_(ip_bytes_remote_); + std::uint16_t port_reliable = 3506; + std::uint16_t port_unreliable = 3507; +} + +TEST_F(routing_manager_ut_setup, DISABLED_set_routing_state_RS_SUSPENDED) { + + // Called on mock_host_ as a result of routing_manager_impl::del_routing_info being called within the logic tree + EXPECT_CALL(mock_host_, on_availability(_,_,_,_,_)).Times(AtLeast(1)); + + // Adding a service using add_routing_info this is a local service probably need to add remotes for this test + its_manager->add_routing_info(service_, instance_, major_version_, minor_version_, + ttl_, ip_address_, port_reliable, ip_address_, port_unreliable); + + // remote for on avail to be called as part of the del_routing_info call + its_manager->add_routing_info(service2_, instance2_, major_version_, minor_version_, + ttl_, ip_address_remote_, port_reliable, ip_address_remote_, port_unreliable); + + // Check it was added + auto service_list = its_manager->get_offered_services(); + ASSERT_TRUE(service_list.size() > 0); + + // Call test method with test input. + its_manager->set_routing_state(vsomeip_v3::routing_state_e::RS_SUSPENDED); + + // Assert routing state, is equal to tested state. + ASSERT_EQ(its_manager->get_routing_state(), vsomeip_v3::routing_state_e::RS_SUSPENDED); +} + +TEST_F(routing_manager_ut_setup, DISABLED_set_routing_state_RS_RUNNING) { + + // Adding a service using add_routing_info + its_manager->add_routing_info(service_, instance_, major_version_, minor_version_, + ttl_, ip_address_, port_reliable, ip_address_, port_unreliable); + + // Check it was added + auto service_list = its_manager->get_offered_services(); + ASSERT_TRUE(service_list.size() > 0); + + // RS_RUNNING is the default value so set RS_SUSPENDED back to RS_RUNNING + // This is needed because the method exits right away if there is no state change. + its_manager->set_routing_state(vsomeip_v3::routing_state_e::RS_SUSPENDED); + its_manager->set_routing_state(vsomeip_v3::routing_state_e::RS_RUNNING); + + // Assert routing state, is equal to tested state. + ASSERT_EQ(its_manager->get_routing_state(), vsomeip_v3::routing_state_e::RS_RUNNING); + + for (const auto &its_service : its_manager->get_offered_services()) { + for (const auto &its_instance : its_service.second) { + ASSERT_EQ(its_instance.second->get_ttl(), DEFAULT_TTL); + ASSERT_FALSE(its_instance.second->is_in_mainphase()); + } + } +} + +TEST_F(routing_manager_ut_setup, DISABLED_set_routing_state_RS_RESUMED) { + + // Adding a service using add_routing_info + its_manager->add_routing_info(service_, instance_, major_version_, minor_version_, + ttl_, ip_address_, port_reliable, ip_address_, port_unreliable); + + // Check it was added + auto service_list = its_manager->get_offered_services(); + ASSERT_TRUE(service_list.size() > 0); + + its_manager->set_routing_state(vsomeip_v3::routing_state_e::RS_RESUMED); + + // Assert routing state, is equal to tested state. + ASSERT_EQ(its_manager->get_routing_state(), vsomeip_v3::routing_state_e::RS_RESUMED); + + for (const auto &its_service : its_manager->get_offered_services()) { + for (const auto &its_instance : its_service.second) { + ASSERT_EQ(its_instance.second->get_ttl(), DEFAULT_TTL); + ASSERT_FALSE(its_instance.second->is_in_mainphase()); + } + } +} + +TEST_F(routing_manager_ut_setup, DISABLED_set_routing_state_RS_SHUTDOWN) { + + // Call test method with test input. + its_manager->set_routing_state(vsomeip_v3::routing_state_e::RS_SHUTDOWN); + + // Assert routing state, is equal to tested state. + ASSERT_EQ(its_manager->get_routing_state(), vsomeip_v3::routing_state_e::RS_SHUTDOWN); +} + +TEST_F(routing_manager_ut_setup, DISABLED_set_routing_state_RS_DIAGNOSIS) { + + // Adding a service using add_routing_info + its_manager->add_routing_info(service_, instance_, major_version_, minor_version_, + ttl_, ip_address_, port_reliable, ip_address_, port_unreliable); + + // Check it was added + auto service_list = its_manager->get_offered_services(); + ASSERT_TRUE(service_list.size() > 0); + + // Call test method with test input. + its_manager->set_routing_state(vsomeip_v3::routing_state_e::RS_DIAGNOSIS); + + // Assert routing state, is equal to tested state. + ASSERT_EQ(its_manager->get_routing_state(), vsomeip_v3::routing_state_e::RS_DIAGNOSIS); + + // Check ttl was set to 0 done in discovery_->stop_offer_service + for (const auto &its_service : its_manager->get_offered_services()) { + for (const auto &its_instance : its_service.second) { + ASSERT_EQ(its_instance.second->get_ttl(), 0); + } + } +} + +TEST_F(routing_manager_ut_setup, DISABLED_set_routing_state_RS_UNKNOWN) { + + // RS_RUNNING is the default value so set RS_UNKOWN + its_manager->set_routing_state(vsomeip_v3::routing_state_e::RS_UNKNOWN); + + // Assert routing state, is equal to tested state. + ASSERT_EQ(its_manager->get_routing_state(), vsomeip_v3::routing_state_e::RS_UNKNOWN); +} diff --git a/test/unit_tests/security_policy_manager_impl_tests/CMakeLists.txt b/test/unit_tests/security_policy_manager_impl_tests/CMakeLists.txt new file mode 100644 index 000000000..9c864e80d --- /dev/null +++ b/test/unit_tests/security_policy_manager_impl_tests/CMakeLists.txt @@ -0,0 +1,38 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_policy_manager_impl_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + vsomeip_utilities +) + +# configure macro.hpp for correct path +set(UNIT_TEST_BIN_DIR ${CMAKE_SOURCE_DIR}/build/test/unit_tests) + +configure_file( + "${CMAKE_SOURCE_DIR}/test/unit_tests/security_policy_manager_impl_tests/policy_manager_impl_unit_test_macro.hpp.in" + "${CMAKE_SOURCE_DIR}/test/unit_tests/security_policy_manager_impl_tests/policy_manager_impl_unit_test_macro.hpp" +) + +file(MAKE_DIRECTORY ${UNIT_TEST_BIN_DIR}/security_policy_manager_impl_tests/0_0) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/security_policy_manager_impl_tests/policy_manager_impl_unit_test_macro.hpp.in b/test/unit_tests/security_policy_manager_impl_tests/policy_manager_impl_unit_test_macro.hpp.in new file mode 100644 index 000000000..60f548055 --- /dev/null +++ b/test/unit_tests/security_policy_manager_impl_tests/policy_manager_impl_unit_test_macro.hpp.in @@ -0,0 +1,10 @@ +// Copyright (C) 2024 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 policy_manager_impl_unit_test +#define policy_manager_impl_unit_test + +#define UNIT_TEST_BUILD_DIR_PATH "@UNIT_TEST_BIN_DIR@" +#endif diff --git a/test/unit_tests/security_policy_manager_impl_tests/ut_policy_manager_impl.cpp b/test/unit_tests/security_policy_manager_impl_tests/ut_policy_manager_impl.cpp new file mode 100644 index 000000000..0647977f5 --- /dev/null +++ b/test/unit_tests/security_policy_manager_impl_tests/ut_policy_manager_impl.cpp @@ -0,0 +1,1372 @@ +// Copyright (C) 2024 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/. +#ifdef _WIN32 +#include +#endif + +#include +#include + +#include + +#include "../../../implementation/configuration/include/configuration_element.hpp" +#include "../../../implementation/security/include/policy.hpp" +#include "../../../implementation/security/include/policy_manager_impl.hpp" +#include "../../../implementation/utility/include/bithelper.hpp" +#include "../../../implementation/utility/include/utility.hpp" + +#include "policy_manager_impl_unit_test_macro.hpp" + +namespace { + // Lazy load. + bool lazy_load = true; + bool not_lazy_load = false; + + // Client uint16_t + const vsomeip_v3::client_t client_number = 0x1000; + const vsomeip_v3::service_t service_number = 0x1337; + const vsomeip_v3::service_t offer_service_number = 0x1001; + const vsomeip_v3::instance_t instance_number = 0x0101; + const vsomeip_v3::instance_t offer_instance_number = 0x7080; + const vsomeip_v3::method_t method_number = 0x0202; + + // Arbitrary array size, will depends on the policy itself. + const std::uint32_t array_size = 82; + + // Credentials. + const vsomeip_v3::byte_t uid_byte1 = 0x01; + const vsomeip_v3::byte_t uid_byte2 = 0x02; + const vsomeip_v3::byte_t uid_byte3 = 0x03; + const vsomeip_v3::byte_t uid_byte4 = 0x04; + const vsomeip_v3::byte_t gid_byte1 = 0x05; + const vsomeip_v3::byte_t gid_byte2 = 0x06; + const vsomeip_v3::byte_t gid_byte3 = 0x07; + const vsomeip_v3::byte_t gid_byte4 = 0x08; + + // Policy requests length, with respective service number(s). + const vsomeip_v3::byte_t request_length_byte1 = 0x00; + const vsomeip_v3::byte_t request_length_byte2 = 0x00; + const vsomeip_v3::byte_t request_length_byte3 = 0x00; + const vsomeip_v3::byte_t request_length_byte4 = 38; // Decimal to simplify. + const vsomeip_v3::byte_t request_service_byte1 = 0x13; + const vsomeip_v3::byte_t request_service_byte2 = 0x37; + + // Policy offers length, with respective service number(s). + const vsomeip_v3::byte_t offer_length_byte1 = 0x00; + const vsomeip_v3::byte_t offer_length_byte2 = 0x00; + const vsomeip_v3::byte_t offer_length_byte3 = 0x00; + const vsomeip_v3::byte_t offer_length_byte4 = 28; // Decimal to simplify. + const vsomeip_v3::byte_t offer_service_byte1 = 0x10; + const vsomeip_v3::byte_t offer_service_byte2 = 0x01; + + // Length deserialized by deserialize_ids. + const vsomeip_v3::byte_t id_array_length_byte1 = 0x00; + const vsomeip_v3::byte_t id_array_length_byte2 = 0x00; + const vsomeip_v3::byte_t id_array_length_byte3 = 0x00; + const vsomeip_v3::byte_t id_array_length_byte4 = 32; // Decimal to simplify. + + // Length deserialized by requests' first call to deserialize_id_item_list. + const vsomeip_v3::byte_t request_instance_idlist_byte1 = 0x00; + const vsomeip_v3::byte_t request_instance_idlist_byte2 = 0x00; + const vsomeip_v3::byte_t request_instance_idlist_byte3 = 0x00; + const vsomeip_v3::byte_t request_instance_idlist_byte4 = 12; + + // Length deserialized by offers' call to deserialize_id_item_list. + const vsomeip_v3::byte_t offer_instance_idlist_byte1 = 0x00; + const vsomeip_v3::byte_t offer_instance_idlist_byte2 = 0x00; + const vsomeip_v3::byte_t offer_instance_idlist_byte3 = 0x00; + const vsomeip_v3::byte_t offer_instance_idlist_byte4 = 22; // Decimal to simplify. + + // Length deserialized by deserialize_id_item for instances. (Represent either 2*uint16_t = 4 bytes, or uint16_t = 2 bytes) + const vsomeip_v3::byte_t instance_id_length_byte1 = 0x00; + const vsomeip_v3::byte_t instance_id_length_byte2 = 0x00; + const vsomeip_v3::byte_t instance_id_length_byte3 = 0x00; + const vsomeip_v3::byte_t instance_id_length_byte4 = 0x04; + + // Message type parsed in deserialize_id_item should be either 1 or 2. + const vsomeip_v3::byte_t instance_id_type_byte1 = 0x00; + const vsomeip_v3::byte_t instance_id_type_byte2 = 0x00; + const vsomeip_v3::byte_t instance_id_type_byte3 = 0x00; + const vsomeip_v3::byte_t instance_id_type_byte4 = 0x02; + + // Low and High of the instance interval, if type 1 only low is necessary. + const vsomeip_v3::byte_t instance_id_low_byte1 = 0x01; + const vsomeip_v3::byte_t instance_id_low_byte2 = 0x01; + const vsomeip_v3::byte_t instance_id_high_byte1 = 0x10; + const vsomeip_v3::byte_t instance_id_high_byte2 = 0x10; + + // Length deserialized by requests' second call to deserialize_id_item_list. + const vsomeip_v3::byte_t request_method_idlist_byte1 = 0x00; + const vsomeip_v3::byte_t request_method_idlist_byte2 = 0x00; + const vsomeip_v3::byte_t request_method_idlist_byte3 = 0x00; + const vsomeip_v3::byte_t request_method_idlist_byte4 = 12; // Decimal to simplify. + + // Length deserialized by deserialize_id_item for Methods. + const vsomeip_v3::byte_t method_id_length_byte1 = 0x00; + const vsomeip_v3::byte_t method_id_length_byte2 = 0x00; + const vsomeip_v3::byte_t method_id_length_byte3 = 0x00; + const vsomeip_v3::byte_t method_id_length_byte4 = 0x04; + + // Message type parsed in deserialize_id_item should be either 1 or 2. + const vsomeip_v3::byte_t method_id_type_byte1 = 0x00; + const vsomeip_v3::byte_t method_id_type_byte2 = 0x00; + const vsomeip_v3::byte_t method_id_type_byte3 = 0x00; + const vsomeip_v3::byte_t method_id_type_byte4 = 0x02; + + // Low and High of the instance interval, for message type 2. + const vsomeip_v3::byte_t method_id_low_byte1 = 0x02; + const vsomeip_v3::byte_t method_id_low_byte2 = 0x02; + const vsomeip_v3::byte_t method_id_high_byte1 = 0x20; + const vsomeip_v3::byte_t method_id_high_byte2 = 0x20; + + // Length deserialized by deserialize_id_item for second instance. (represent either 2*uint16_t = 4, or uint16 = 2) + const vsomeip_v3::byte_t instance2_id_length_byte1 = 0x00; + const vsomeip_v3::byte_t instance2_id_length_byte2 = 0x00; + const vsomeip_v3::byte_t instance2_id_length_byte3 = 0x00; + const vsomeip_v3::byte_t instance2_id_length_byte4 = 0x02; + + // Message type parsed in deserialize_id_item. + const vsomeip_v3::byte_t instance2_id_type_byte1 = 0x00; + const vsomeip_v3::byte_t instance2_id_type_byte2 = 0x00; + const vsomeip_v3::byte_t instance2_id_type_byte3 = 0x00; + const vsomeip_v3::byte_t instance2_id_type_byte4 = 0x01; + + // Message type 1 only includes low bound. + const vsomeip_v3::byte_t instance2_id_low_byte1 = 0x70; + const vsomeip_v3::byte_t instance2_id_low_byte2 = 0x80; + + // Create arrays to pass to bithelper. + std::array uint32_array_uid_{uid_byte1, uid_byte2, uid_byte3, uid_byte4}; + std::array uint32_array_gid_{gid_byte1, gid_byte2, gid_byte3, gid_byte4}; + + // Create uint32_t from bytes. + const std::uint32_t uid = vsomeip_v3::bithelper::read_uint32_be(uint32_array_uid_.data()); + const std::uint32_t gid = vsomeip_v3::bithelper::read_uint32_be(uint32_array_gid_.data()); + +} + +TEST(security_policy_manager_test, load) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // is_audit returns !check_credentials_ which is by default false, so is_audit should return true. + ASSERT_TRUE(its_policy_manager->is_audit()); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_security; + boost::property_tree::ptree tree_check_credentials; + tree_check_credentials.put_value("true"); + tree_security.add_child("check_credentials", tree_check_credentials); + tree.add_child("security", tree_security); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Test Method. Load policy element, which should set check_credentials to true. + its_policy_manager->load(its_element, lazy_load); + + // Check that is_audit now returns false. Since check_credentials should now be true if the load worked. + ASSERT_FALSE(its_policy_manager->is_audit()); +} + +TEST(security_policy_manager_test, check_credentials) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Default test structure, case will fall through the logic checks to the end of the test method. + vsomeip_sec_client_t its_client_struct_default; + + its_client_struct_default.user = 0; + its_client_struct_default.group = 0; + its_client_struct_default.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct_default.host = 0; + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + // Test Method, policy not enabled, expect call to return true. + ASSERT_TRUE(its_policy_manager->check_credentials(client_number, &its_client_struct)); + + // Create policy to be able to test the method further. + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Add policy to the manager. + its_policy_manager->update_security_policy(uid, gid, its_policy); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_security; + boost::property_tree::ptree tree_check_credentials; + tree_check_credentials.put_value("true"); + tree_security.add_child("check_credentials", tree_check_credentials); + tree.add_child("security", tree_security); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Load policy element, which should set check_credentials to true. Needed to differentiate returns test cases (sets the default test to false). + its_policy_manager->load(its_element, lazy_load); + + // Test Method, client null expect call to return true. + ASSERT_TRUE(its_policy_manager->check_credentials(client_number, nullptr)); + + // Set port to be different from 0 + its_client_struct.port = 1; + + // Test Method, port != 0, expect call to return true. + ASSERT_TRUE(its_policy_manager->check_credentials(client_number, &its_client_struct)); + + // reset port to 0 + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + + // Test Method, expect call to return true. + ASSERT_TRUE(its_policy_manager->check_credentials(client_number, &its_client_struct)); + + // Test Method, expect call to default through and return !check_credentials. Since we set it to true we expect false. + ASSERT_FALSE(its_policy_manager->check_credentials(0, &its_client_struct_default)); +} + +TEST(security_policy_manager_test, check_routing_credentials) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Default test structure, case will fall through the logic checks to the end of the test method. + vsomeip_sec_client_t its_client_struct_default; + + its_client_struct_default.user = 0; + its_client_struct_default.group = 0; + its_client_struct_default.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct_default.host = 0; + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Add policy to the manager. + its_policy_manager->update_security_policy(uid, gid, its_policy); + + // Create a policy element setting check_credentials to true. And check_routing_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_security; + boost::property_tree::ptree tree_check_credentials; + boost::property_tree::ptree tree_check_routing_credentials; + boost::property_tree::ptree tree_check_routing_credentials_uid; + boost::property_tree::ptree tree_check_routing_credentials_gid; + + tree_check_credentials.put_value("true"); + tree_security.add_child("check_credentials", tree_check_credentials); + tree.add_child("security", tree_security); + + tree_check_routing_credentials_uid.put_value("0x01020304"); + tree_check_routing_credentials_gid.put_value("0x05060708"); + tree_check_routing_credentials.add_child("uid", tree_check_routing_credentials_uid); + tree_check_routing_credentials.add_child("gid", tree_check_routing_credentials_gid); + tree.add_child("routing-credentials", tree_check_routing_credentials); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Test Method, expect call to return true. This method, defaults even with nullptr, no null checks. + ASSERT_TRUE(its_policy_manager->check_routing_credentials(nullptr)); + + // Load policy element not lazy load, to call load_routing_credentials which should set check_routing_credentials_ to true. + its_policy_manager->load(its_element, not_lazy_load); + + // Test Method, expect call to default through and return !check_routing_credentials. Since we set it to true we expect false. + ASSERT_FALSE(its_policy_manager->check_routing_credentials(&its_client_struct_default)); + + // Test Method, expect call to return true. + ASSERT_TRUE(its_policy_manager->check_routing_credentials(&its_client_struct)); +} + +TEST(security_policy_manager_test, set_routing_credentials) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Default test structure, case will fall through the logic checks to the end of the test method. + vsomeip_sec_client_t its_client_struct_default; + + its_client_struct_default.user = 0; + its_client_struct_default.group = 0; + its_client_struct_default.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct_default.host = 0; + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + const std::string routing_name = "random"; + // Test method + its_policy_manager->set_routing_credentials(uid, gid, routing_name); + + // Test Method, expect call to default through and return !check_routing_credentials. Since it is false by default, we expect true. + ASSERT_TRUE(its_policy_manager->check_routing_credentials(&its_client_struct_default)); + + // Test Method, expect call to return true. + ASSERT_TRUE(its_policy_manager->check_routing_credentials(&its_client_struct)); +} + +TEST(security_policy_manager_test, is_client_allowed) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Default test structure, case will fall through the logic checks to the end of the test method. + vsomeip_sec_client_t its_client_struct_default; + + its_client_struct_default.user = 0; + its_client_struct_default.group = 0; + its_client_struct_default.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct_default.host = 0; + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + // Test Method. Policy not enabled + ASSERT_TRUE(its_policy_manager->is_client_allowed(&its_client_struct, service_number, instance_number, method_number, true)); + + // Enable policy. + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Add policy to the manager. + its_policy_manager->update_security_policy(uid, gid, its_policy); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_security; + boost::property_tree::ptree tree_check_credentials; + tree_check_credentials.put_value("true"); + tree_security.add_child("check_credentials", tree_check_credentials); + tree.add_child("security", tree_security); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Load policy element, which should set check_credentials to true. Needed to differentiate returns test cases (sets the default test to false). + its_policy_manager->load(its_element, lazy_load); + + // Set port to a number different than 0 + its_client_struct.port = 1; + // Test Method. Expect to receive true since the port is not 0 + ASSERT_TRUE(its_policy_manager->is_client_allowed(&its_client_struct, service_number, instance_number, method_number, true)); + //reset port to 0. + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + + // Test Method. client is null. Expect !check_credentials. + ASSERT_FALSE(its_policy_manager->is_client_allowed(nullptr, service_number, instance_number, method_number, true)); + + // Test Method. Expect true, is matching is true, and client is added to cache. + ASSERT_TRUE(its_policy_manager->is_client_allowed(&its_client_struct, service_number, instance_number, method_number, true)); + + // Test Method. Expect true, case in cache. + ASSERT_TRUE(its_policy_manager->is_client_allowed(&its_client_struct, service_number, instance_number, method_number, true)); + + // Allow what false. + its_policy->allow_what_= false; + its_policy_manager->update_security_policy(uid, gid, its_policy); + + // Test Method expect true from return where allow what is false. + ASSERT_TRUE(its_policy_manager->is_client_allowed(&its_client_struct, service_number, instance_number, 1, false)); + + // Test method, expect !check_credentials which we set to true, so expect false. + ASSERT_FALSE(its_policy_manager->is_client_allowed(&its_client_struct_default, service_number, instance_number, method_number, true)); +} + + +TEST(security_policy_manager_test, is_offer_allowed) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Default test structure, case will fall through the logic checks to the end of the test method. + vsomeip_sec_client_t its_client_struct_default; + + its_client_struct_default.user = 0; + its_client_struct_default.group = 0; + its_client_struct_default.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct_default.host = 0; + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + // Test Method. Policy not enabled + ASSERT_TRUE(its_policy_manager->is_offer_allowed(&its_client_struct, offer_service_number, offer_instance_number)); + + // Enable policy. + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Add policy to the manager. + its_policy_manager->update_security_policy(uid, gid, its_policy); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_security; + boost::property_tree::ptree tree_check_credentials; + tree_check_credentials.put_value("true"); + tree_security.add_child("check_credentials", tree_check_credentials); + tree.add_child("security", tree_security); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Load policy element, which should set check_credentials to true. Needed to differentiate returns test cases (sets the default test to false). + its_policy_manager->load(its_element, lazy_load); + + // Set port to a number different than 0 + its_client_struct.port = 1; + // Test Method. Expect to receive true since the port is not 0 + ASSERT_TRUE(its_policy_manager->is_offer_allowed(&its_client_struct, offer_service_number, offer_instance_number)); + //reset port to 0. + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + + // Test Method. client is null. Expect !check_credentials. + ASSERT_FALSE(its_policy_manager->is_offer_allowed(nullptr, offer_service_number, offer_instance_number)); + + // Test Method. Expect true, is matching is true, and client is added to cache. + ASSERT_TRUE(its_policy_manager->is_offer_allowed(&its_client_struct, offer_service_number, offer_instance_number)); + + // Test method, expect !check_credentials which we set to true, so expect false. + ASSERT_FALSE(its_policy_manager->is_offer_allowed(&its_client_struct_default, offer_service_number, offer_instance_number)); +} + +TEST(security_policy_manager_test, store_sec_client_to_client_mapping_and_get_sec_client_to_clients_mapping) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + std::set client_set; + + // Test method, expect false since sec client is null. + ASSERT_FALSE(its_policy_manager->get_sec_client_to_clients_mapping(nullptr, client_set)); + + // Set client structure port to different than 0. + its_client_struct.port = 1; + // Test method expect false since port != 0. + ASSERT_FALSE(its_policy_manager->get_sec_client_to_clients_mapping(&its_client_struct, client_set)); + // reset port to 0 + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + + // Test method, correct call but expect false since we have yet to add a client to the mapping. + ASSERT_FALSE(its_policy_manager->get_sec_client_to_clients_mapping(&its_client_struct, client_set)); + + // Test method, add a client to the client mapping. + its_policy_manager->store_sec_client_to_client_mapping(&its_client_struct, client_number); + + // Test method, expect true since the client was added to the mapping. + ASSERT_TRUE(its_policy_manager->get_sec_client_to_clients_mapping(&its_client_struct, client_set)); +} + +TEST(security_policy_manager_test, store_client_to_sec_client_mapping) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + + // Test method, expect false since sec client is null. + ASSERT_FALSE(its_policy_manager->store_client_to_sec_client_mapping(client_number, nullptr)); + + // Set client structure port to different than 0. + its_client_struct.port = 1; + // Test method expect false since port != 0. + ASSERT_FALSE(its_policy_manager->store_client_to_sec_client_mapping(client_number, &its_client_struct)); + // reset port to 0 + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + + // Test method, expect true as we are adding a client. + ASSERT_TRUE(its_policy_manager->store_client_to_sec_client_mapping(client_number, &its_client_struct)); +} + +TEST(security_policy_manager_test, get_client_to_sec_client_mapping) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + // Test method, expect false since we have yet to store a client. + ASSERT_FALSE(its_policy_manager->get_client_to_sec_client_mapping(client_number, its_client_struct)); + + // store a client to client mapping. + ASSERT_TRUE(its_policy_manager->store_client_to_sec_client_mapping(client_number, &its_client_struct)); + + // Test method, expect true since we stored the client previously. + ASSERT_TRUE(its_policy_manager->get_client_to_sec_client_mapping(client_number, its_client_struct)); +} + +TEST(security_policy_manager_test, remove_client_to_sec_client_mapping) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + // Test method, expect false since we have yet to store a client. + ASSERT_FALSE(its_policy_manager->remove_client_to_sec_client_mapping(client_number)); + + // store a client to client mapping. + ASSERT_TRUE(its_policy_manager->store_client_to_sec_client_mapping(client_number, &its_client_struct)); + its_policy_manager->store_sec_client_to_client_mapping(&its_client_struct, client_number); + + // Test method, expect true since we stored the client previously. + ASSERT_TRUE(its_policy_manager->remove_client_to_sec_client_mapping(client_number)); +} + +TEST(security_policy_manager_test, parse_policy) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + std::uint32_t deserialized_uid, deserialized_gid; + + // Test method. + #ifndef __QNX__ + ASSERT_TRUE(its_policy_manager->parse_policy(data_ptr_, data_size_, deserialized_uid, deserialized_gid, its_policy)); + #endif + + ASSERT_EQ(uid, deserialized_uid); + ASSERT_EQ(gid, deserialized_gid); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_too_short[4]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4 + }; + + const vsomeip_v3::byte_t *data_ptr2_ = byte_array_too_short; + std::uint32_t data_size2_ = 4; + + // Test Method, expect false. + #ifndef __QNX__ + ASSERT_FALSE(its_policy_manager->parse_policy(data_ptr2_, data_size2_, deserialized_uid, deserialized_gid, its_policy)); + #endif +} + +TEST(security_policy_manager_test, parse_uid_gid) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + std::uint32_t deserialized_uid, deserialized_gid; + + // Test method. + #ifndef __QNX__ + ASSERT_TRUE(its_policy_manager->parse_uid_gid(data_ptr_, data_size_, deserialized_uid, deserialized_gid)); + #endif + + ASSERT_EQ(uid, deserialized_uid); + ASSERT_EQ(gid, deserialized_gid); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_too_short[4]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4 + }; + + const vsomeip_v3::byte_t *data_ptr2_ = byte_array_too_short; + std::uint32_t data_size2_ = 4; + + // Test Method, expect false. + #ifndef __QNX__ + ASSERT_FALSE(its_policy_manager->parse_uid_gid(data_ptr2_, data_size2_, deserialized_uid, deserialized_gid)); + #endif +} + +TEST(security_policy_manager_test, remove_security_policy) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Test method. Expect false since no policy was added. + ASSERT_FALSE(its_policy_manager->remove_security_policy(uid, gid)); + + // Add a policy. + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Add policy to the manager. + its_policy_manager->update_security_policy(uid, gid, its_policy); + + // Test method. Expect true since we added a policy. + ASSERT_TRUE(its_policy_manager->remove_security_policy(uid, gid)); +} + +TEST(security_policy_manager_test, add_security_credentials) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Add a policy. + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Test method. Add security credentials. + its_policy_manager->add_security_credentials(uid, gid, its_policy, client_number); + + // Expect true since we added the security credentials policy above. + ASSERT_TRUE(its_policy_manager->remove_security_policy(uid, gid)); +} + +TEST(security_policy_manager_test, get_requester_policies) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Add a policy. + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + std::shared_ptr its_policy2(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + request_service_byte1, request_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + std::set> its_policy_set= {}; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Test set is empty. + ASSERT_TRUE(its_policy_set.empty()); + + // Test method. + its_policy_manager->get_requester_policies(its_policy, its_policy_set); + + // Since the policy was not added to the manager, expect set to be empty still. + ASSERT_TRUE(its_policy_set.empty()); + + // Add policy to manager. + its_policy_manager->update_security_policy(uid, gid, its_policy); + + // Test method. + its_policy_manager->get_requester_policies(its_policy, its_policy_set); + + // Expect true because of the continue in the for loops if its_policy is equal to the policy in the manager. + ASSERT_TRUE(its_policy_set.empty()); + + // reseting data. + data_ptr_ = byte_array_; + data_size_ = array_size; + + // Set up new policy2. + ASSERT_TRUE(its_policy2->deserialize(data_ptr_, data_size_)); + its_policy_manager->update_security_policy(uid, gid, its_policy2); + + // Test method. + its_policy_manager->get_requester_policies(its_policy2, its_policy_set); + + // Expect the set to now be populated. + ASSERT_FALSE(its_policy_set.empty()); +} + +TEST(security_policy_manager_test, get_clients) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Test Structure. + vsomeip_sec_client_t its_client_struct; + + its_client_struct.user = uid; + its_client_struct.group = gid; + its_client_struct.port = VSOMEIP_SEC_PORT_UNUSED; + its_client_struct.host = 0; + + // Add a policy. + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + std::unordered_set its_client_set= {}; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Assert set is empty. + ASSERT_TRUE(its_client_set.empty()); + + // Test method. + its_policy_manager->get_clients(uid, gid, its_client_set); + + // Since no client was added, expect the set to remain empty. + ASSERT_TRUE(its_client_set.empty()); + + // Add client to manager. + ASSERT_TRUE(its_policy_manager->store_client_to_sec_client_mapping(client_number, &its_client_struct)); + + // Test method. + its_policy_manager->get_clients(uid, gid, its_client_set); + + // Expect false since we added a client to the manager. + ASSERT_FALSE(its_client_set.empty()); + ASSERT_EQ(its_client_set.size(), 1); + + // Add client to manager. + ASSERT_TRUE(its_policy_manager->store_client_to_sec_client_mapping(client_number + 1, &its_client_struct)); + + // test method. + its_policy_manager->get_clients(uid, gid, its_client_set); + + // Expect set to have 2 entries. + ASSERT_EQ(its_client_set.size(), 2); +} + +TEST(security_policy_manager_test, get_policy_extension_path) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + const std::string its_client_host = "random"; + + // Test Method. + ASSERT_EQ(its_policy_manager->get_policy_extension_path(its_client_host), ""); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_security; + boost::property_tree::ptree tree_check_credentials; + boost::property_tree::ptree tree_container_policy_extensions; + boost::property_tree::ptree tree_container_policy_extension; + boost::property_tree::ptree tree_container_policy_extensions_container; + boost::property_tree::ptree tree_container_policy_extensions_path; + tree_container_policy_extensions_container.put_value("random"); + tree_container_policy_extensions_path.put_value("/random_path/"); + tree_container_policy_extension.add_child("container", tree_container_policy_extensions_container); + tree_container_policy_extension.add_child("path", tree_container_policy_extensions_path); + tree_container_policy_extensions.add_child("extension", tree_container_policy_extension); + tree.add_child("container_policy_extensions", tree_container_policy_extensions); + tree_check_credentials.put_value("true"); + tree_security.add_child("check_credentials", tree_check_credentials); + tree.add_child("security", tree_security); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Load policy element, which should should add the container and its path to policy_extension_paths_. + its_policy_manager->load(its_element, not_lazy_load); + + // Test method + ASSERT_EQ(its_policy_manager->get_policy_extension_path(its_client_host), "/etc/random_path/"); +} + +TEST(security_policy_manager_test, is_policy_removal_allowed) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Test method. Expect true because it will return the default option !check_whitelist_ which is false. + ASSERT_TRUE(its_policy_manager->is_policy_removal_allowed(uid)); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_check_whitelists; + boost::property_tree::ptree tree_security_update_whitelist; + boost::property_tree::ptree tree_whitelists_any_interval; + + // Change check_whitelist_ to true, so we get false if we get the previous return. + tree_check_whitelists.put_value("true"); + tree_security_update_whitelist.add_child("check-whitelist", tree_check_whitelists); + + // Set any interval so we should get true if the uid is contained within the min and max. + tree_whitelists_any_interval.put_value("any"); + tree_security_update_whitelist.add_child("uids", tree_whitelists_any_interval); + tree.add_child("security-update-whitelist", tree_security_update_whitelist); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Load policy element, which should should add the container and its path to policy_extension_paths_. + its_policy_manager->load(its_element, not_lazy_load); + + // Test method. Expect true. Since we set up an interval, if uid is between 0 and max uint32_t we should get true. + ASSERT_TRUE(its_policy_manager->is_policy_removal_allowed(uid)); +} + +TEST(security_policy_manager_test, is_policy_update_allowed) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Create a policy + // Policy shared pointer to be used for test set up. + std::shared_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy + vsomeip_v3::byte_t byte_array_[array_size]{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t *data_ptr_ = byte_array_; + std::uint32_t data_size_ = array_size; + + // Filling in the policy. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Test method. Expect true because it will return the default option !check_whitelist_ which is false. + ASSERT_TRUE(its_policy_manager->is_policy_update_allowed(uid, its_policy)); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_check_whitelists; + boost::property_tree::ptree tree_security_update_whitelist; + boost::property_tree::ptree tree_whitelists_any_interval; + + // Change check_whitelist_ to true, so we get false if we get the previous return. + tree_check_whitelists.put_value("true"); + tree_security_update_whitelist.add_child("check-whitelist", tree_check_whitelists); + + // Set any interval for uid and services so we should get true if the uid is contained within the min and max. + tree_whitelists_any_interval.put_value("any"); + tree_security_update_whitelist.add_child("uids", tree_whitelists_any_interval); + tree_whitelists_any_interval.put_value("any"); + tree_security_update_whitelist.add_child("services", tree_whitelists_any_interval); + tree.add_child("security-update-whitelist", tree_security_update_whitelist); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Load policy element, which should should add the container and its path to policy_extension_paths_. + its_policy_manager->load(its_element, not_lazy_load); + + // Test method. Expect true because uid and service matched. + ASSERT_TRUE(its_policy_manager->is_policy_update_allowed(uid, its_policy)); +} + +TEST(security_policy_manager_test, get_security_config_folder) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Create a string stream to build the full path to the security config folder. + std::stringstream final_path; + + // Create a string to the path to the current unit test folder. + const std::string folder_path = UNIT_TEST_BUILD_DIR_PATH "/security_policy_manager_impl_tests"; + + const std::string fake_path = "fake_path"; + + // Test method, since the folder does not exist, expect a default return. + ASSERT_EQ(its_policy_manager->get_security_config_folder(fake_path), ""); + + // Complete the path, adding the uid and gid. +#ifdef _WIN32 + final_path << folder_path << "/0_0"; +#else + final_path << folder_path << "/" << getuid() << "_" << getgid(); +#endif + + // Convert stringstream to char* + const std::string tmp = final_path.str(); + const char* final_path_string = tmp.c_str(); + + boost::system::error_code ec; + // Create the directory. + boost::filesystem::create_directory(final_path_string, ec); + + // Test method. Since the folder now exists we expect to get the path returned. + ASSERT_EQ(its_policy_manager->get_security_config_folder(folder_path), final_path_string); + + // Clean up, remove directory. + boost::filesystem::remove_all(final_path_string, ec); +} + +TEST(security_policy_manager_test, is_policy_extension_loaded) { + // Test pointer. + std::unique_ptr its_policy_manager(new vsomeip_v3::policy_manager_impl()); + + // Client name. + const std::string client_name("random"); + + // Test method. No path has yet to be added. + ASSERT_EQ(its_policy_manager->is_policy_extension_loaded(client_name), + vsomeip_v3::policy_manager_impl::policy_loaded_e::POLICY_PATH_INEXISTENT); + + // Create a string stream to build the relative path to the security config folder. + std::stringstream final_path; + + // Create a secondary path which will be full path. + std::stringstream final_path2; + + // Create a string of the build path to the current test. + const std::string folder_path = "build/test/unit_tests/security_policy_manager_impl_tests"; + + // Complete the path, adding the uid and gid. +#ifdef _WIN32 + final_path << folder_path << "/0_0"; +#else + final_path << folder_path << "/" << getuid() << "_" << getgid(); +#endif + + // Add a way to move out of the /etc folder we will be forced in. + final_path2 << "../.." << UNIT_TEST_BUILD_DIR_PATH << "/security_policy_manager_impl_tests"; + + // Convert stringstream to char* + const std::string tmp = final_path.str(); + const char* final_path_string = tmp.c_str(); + const std::string tmp2 = final_path2.str(); + const char* final_path_string2 = tmp2.c_str(); + + boost::system::error_code ec; + // Create the directory. + boost::filesystem::create_directory(final_path_string, ec); + + // Create a policy element setting check_credentials to true. + const std::string element_name = "random"; + boost::property_tree::ptree tree; + boost::property_tree::ptree tree_security; + boost::property_tree::ptree tree_check_credentials; + boost::property_tree::ptree tree_container_policy_extensions; + boost::property_tree::ptree tree_container_policy_extension; + boost::property_tree::ptree tree_container_policy_extensions_container; + boost::property_tree::ptree tree_container_policy_extensions_path; + tree_container_policy_extensions_container.put_value("random"); + tree_container_policy_extensions_path.put_value(final_path_string2); + tree_container_policy_extension.add_child("container", tree_container_policy_extensions_container); + tree_container_policy_extension.add_child("path", tree_container_policy_extensions_path); + tree_container_policy_extensions.add_child("extension", tree_container_policy_extension); + tree.add_child("container_policy_extensions", tree_container_policy_extensions); + tree_check_credentials.put_value("true"); + tree_security.add_child("check_credentials", tree_check_credentials); + tree.add_child("security", tree_security); + + const boost::property_tree::ptree tree_ptr = tree; + vsomeip_v3::configuration_element its_element(element_name, tree_ptr); + + // Need to load a policy extension. + its_policy_manager->load(its_element, not_lazy_load); + + // Test method. Expect an inexistent return because the set_is_plocity_extension_loaded method hasn't be called. + ASSERT_EQ(its_policy_manager->is_policy_extension_loaded(client_name), + vsomeip_v3::policy_manager_impl::policy_loaded_e::POLICY_PATH_INEXISTENT); + + // Associated test method. True for loaded. + its_policy_manager->set_is_policy_extension_loaded(client_name, true); + + // Test method. Expect an outcome different from the last since we called the method. + ASSERT_NE(its_policy_manager->is_policy_extension_loaded(client_name), + vsomeip_v3::policy_manager_impl::policy_loaded_e::POLICY_PATH_INEXISTENT); + + // Test method. Since we used true for loaded in the set method we expect found and loaded return. + ASSERT_EQ(its_policy_manager->is_policy_extension_loaded(client_name), + vsomeip_v3::policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_LOADED); + + // Associated test method. False for loaded. + its_policy_manager->set_is_policy_extension_loaded(client_name, false); + + // Test method. We now expect found but not loaded return. + ASSERT_EQ(its_policy_manager->is_policy_extension_loaded(client_name), + vsomeip_v3::policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_NOT_LOADED); + + // Clean up, remove directory. + boost::filesystem::remove_all(final_path_string, ec); +} diff --git a/test/unit_tests/security_policy_tests/CMakeLists.txt b/test/unit_tests/security_policy_tests/CMakeLists.txt new file mode 100644 index 000000000..a989a39eb --- /dev/null +++ b/test/unit_tests/security_policy_tests/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_policy_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + vsomeip_utilities +) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/security_policy_tests/ut_policy.cpp b/test/unit_tests/security_policy_tests/ut_policy.cpp new file mode 100644 index 000000000..eb63bd0ba --- /dev/null +++ b/test/unit_tests/security_policy_tests/ut_policy.cpp @@ -0,0 +1,404 @@ +// Copyright (C) 2023 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 "../../../implementation/utility/include/bithelper.hpp" +#include "../../../implementation/security/include/policy.hpp" + +namespace { + // Arbitrary array size, will depends on the policy itself. + const std::uint32_t array_size = 82; + + // Credentials. + const vsomeip_v3::byte_t uid_byte1 = 0x01; + const vsomeip_v3::byte_t uid_byte2 = 0x02; + const vsomeip_v3::byte_t uid_byte3 = 0x03; + const vsomeip_v3::byte_t uid_byte4 = 0x04; + const vsomeip_v3::byte_t gid_byte1 = 0x05; + const vsomeip_v3::byte_t gid_byte2 = 0x06; + const vsomeip_v3::byte_t gid_byte3 = 0x07; + const vsomeip_v3::byte_t gid_byte4 = 0x08; + + // Policy requests length, with respective service number(s). + const vsomeip_v3::byte_t request_length_byte1 = 0x00; + const vsomeip_v3::byte_t request_length_byte2 = 0x00; + const vsomeip_v3::byte_t request_length_byte3 = 0x00; + const vsomeip_v3::byte_t request_length_byte4 = 38; // Decimal to simplify. + const vsomeip_v3::byte_t request_service_byte1 = 0x13; + const vsomeip_v3::byte_t request_service_byte2 = 0x37; + + // Policy offers length, with respective service number(s). + const vsomeip_v3::byte_t offer_length_byte1 = 0x00; + const vsomeip_v3::byte_t offer_length_byte2 = 0x00; + const vsomeip_v3::byte_t offer_length_byte3 = 0x00; + const vsomeip_v3::byte_t offer_length_byte4 = 28; // Decimal to simplify. + const vsomeip_v3::byte_t offer_service_byte1 = 0x10; + const vsomeip_v3::byte_t offer_service_byte2 = 0x01; + + // Length deserialized by deserialize_ids. + const vsomeip_v3::byte_t id_array_length_byte1 = 0x00; + const vsomeip_v3::byte_t id_array_length_byte2 = 0x00; + const vsomeip_v3::byte_t id_array_length_byte3 = 0x00; + const vsomeip_v3::byte_t id_array_length_byte4 = 32; // Decimal to simplify. + + // Length deserialized by requests' first call to deserialize_id_item_list. + const vsomeip_v3::byte_t request_instance_idlist_byte1 = 0x00; + const vsomeip_v3::byte_t request_instance_idlist_byte2 = 0x00; + const vsomeip_v3::byte_t request_instance_idlist_byte3 = 0x00; + const vsomeip_v3::byte_t request_instance_idlist_byte4 = 12; + + // Length deserialized by offers' call to deserialize_id_item_list. + const vsomeip_v3::byte_t offer_instance_idlist_byte1 = 0x00; + const vsomeip_v3::byte_t offer_instance_idlist_byte2 = 0x00; + const vsomeip_v3::byte_t offer_instance_idlist_byte3 = 0x00; + const vsomeip_v3::byte_t offer_instance_idlist_byte4 = 22; // Decimal to simplify. + + // Length deserialized by deserialize_id_item for instances. (Represent either 2*uint16_t = 4 bytes, or uint16_t = 2 bytes) + const vsomeip_v3::byte_t instance_id_length_byte1 = 0x00; + const vsomeip_v3::byte_t instance_id_length_byte2 = 0x00; + const vsomeip_v3::byte_t instance_id_length_byte3 = 0x00; + const vsomeip_v3::byte_t instance_id_length_byte4 = 0x04; + + // Message type parsed in deserialize_id_item should be either 1 or 2. + const vsomeip_v3::byte_t instance_id_type_byte1 = 0x00; + const vsomeip_v3::byte_t instance_id_type_byte2 = 0x00; + const vsomeip_v3::byte_t instance_id_type_byte3 = 0x00; + const vsomeip_v3::byte_t instance_id_type_byte4 = 0x02; + + // Low and High of the instance interval, if type 1 only low is necessary. + const vsomeip_v3::byte_t instance_id_low_byte1 = 0x01; + const vsomeip_v3::byte_t instance_id_low_byte2 = 0x01; + const vsomeip_v3::byte_t instance_id_high_byte1 = 0x10; + const vsomeip_v3::byte_t instance_id_high_byte2 = 0x10; + + // Length deserialized by requests' second call to deserialize_id_item_list. + const vsomeip_v3::byte_t request_method_idlist_byte1 = 0x00; + const vsomeip_v3::byte_t request_method_idlist_byte2 = 0x00; + const vsomeip_v3::byte_t request_method_idlist_byte3 = 0x00; + const vsomeip_v3::byte_t request_method_idlist_byte4 = 12; // Decimal to simplify. + + // Length deserialized by deserialize_id_item for Methods. + const vsomeip_v3::byte_t method_id_length_byte1 = 0x00; + const vsomeip_v3::byte_t method_id_length_byte2 = 0x00; + const vsomeip_v3::byte_t method_id_length_byte3 = 0x00; + const vsomeip_v3::byte_t method_id_length_byte4 = 0x04; + + // Message type parsed in deserialize_id_item should be either 1 or 2. + const vsomeip_v3::byte_t method_id_type_byte1 = 0x00; + const vsomeip_v3::byte_t method_id_type_byte2 = 0x00; + const vsomeip_v3::byte_t method_id_type_byte3 = 0x00; + const vsomeip_v3::byte_t method_id_type_byte4 = 0x02; + + // Low and High of the instance interval, for message type 2. + const vsomeip_v3::byte_t method_id_low_byte1 = 0x02; + const vsomeip_v3::byte_t method_id_low_byte2 = 0x02; + const vsomeip_v3::byte_t method_id_high_byte1 = 0x20; + const vsomeip_v3::byte_t method_id_high_byte2 = 0x20; + + // Length deserialized by deserialize_id_item for second instance. (represent either 2*uint16_t = 4, or uint16 = 2) + const vsomeip_v3::byte_t instance2_id_length_byte1 = 0x00; + const vsomeip_v3::byte_t instance2_id_length_byte2 = 0x00; + const vsomeip_v3::byte_t instance2_id_length_byte3 = 0x00; + const vsomeip_v3::byte_t instance2_id_length_byte4 = 0x02; + + // Message type parsed in deserialize_id_item. + const vsomeip_v3::byte_t instance2_id_type_byte1 = 0x00; + const vsomeip_v3::byte_t instance2_id_type_byte2 = 0x00; + const vsomeip_v3::byte_t instance2_id_type_byte3 = 0x00; + const vsomeip_v3::byte_t instance2_id_type_byte4 = 0x01; + + // Message type 1 only includes low bound. + const vsomeip_v3::byte_t instance2_id_low_byte1 = 0x70; + const vsomeip_v3::byte_t instance2_id_low_byte2 = 0x80; + + // Create arrays to pass to bithelper. + std::array uint32_array_uid_{uid_byte1, uid_byte2, uid_byte3, uid_byte4}; + std::array uint32_array_gid_{gid_byte1, gid_byte2, gid_byte3, gid_byte4}; + + // Create uint32_t from bytes. + const std::uint32_t uid = vsomeip_v3::bithelper::read_uint32_be(uint32_array_uid_.data()); + const std::uint32_t gid = vsomeip_v3::bithelper::read_uint32_be(uint32_array_gid_.data()); +} + +TEST(security_policy_test, deserialize) { + std::unique_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy with type 2 instance and methods for requests_ + // and two instances for offers one type 2 instance and one type 1 for offers_ + // type 2 receives a uint16_t for low_ and another for high_ + // for type 1 low_ = high_ and only 1 uint16_t is passed. + + std::arraybyte_array_{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t* data_ptr_ = byte_array_.data(); + std::uint32_t data_size_ = array_size; + + // Test method. + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Check credentials. + + // Check if uid and gid were deserialized correctly by private method deserialize_u32 + // Check if uid is in the credentials_ + auto deserialized_gid_set = its_policy->credentials_.lower_bound( + boost::icl::interval::closed(uid, uid)); + // Check if the associated gid is located. + ASSERT_EQ(deserialized_gid_set->second.begin()->lower(), gid); + + // Check requests + // Create uint16_t from bytes. + std::array uint16_array_request_service_{request_service_byte1, request_service_byte2}; + std::array uint16_array_request_instance_low_{instance_id_low_byte1, instance_id_low_byte2}; + std::array uint16_array_request_instance_high_{instance_id_high_byte1, instance_id_high_byte2}; + std::array uint16_array_request_method_id_low_{method_id_low_byte1, method_id_low_byte2}; + std::array uint16_array_request_method_id_high_{method_id_high_byte1, method_id_high_byte2}; + + std::uint16_t request_service = vsomeip_v3::bithelper::read_uint16_be(uint16_array_request_service_.data()); + std::uint16_t request_instance_low = vsomeip_v3::bithelper::read_uint16_be(uint16_array_request_instance_low_.data()); + std::uint16_t request_instance_high = vsomeip_v3::bithelper::read_uint16_be(uint16_array_request_instance_high_.data()); + std::uint16_t request_method_low = vsomeip_v3::bithelper::read_uint16_be(uint16_array_request_method_id_low_.data()); + std::uint16_t request_method_high = vsomeip_v3::bithelper::read_uint16_be(uint16_array_request_method_id_high_.data()); + + // Check if method high and low were deserialized correctly by private method deserialize_u16 + auto deserialized_service_set = its_policy->requests_.lower_bound( + boost::icl::interval::closed(request_service, request_service)); + + // Check if the associated instance low and high are located. + ASSERT_EQ(deserialized_service_set->second.begin()->first.lower(), request_instance_low); + ASSERT_EQ(deserialized_service_set->second.begin()->first.upper(), request_instance_high); + + auto deserialized_method_set = deserialized_service_set->second.lower_bound( + boost::icl::interval::closed(request_instance_low, request_instance_high)); + + // Check if the associated request method low and high are located. + ASSERT_EQ(deserialized_method_set->second.begin()->lower(), request_method_low); + ASSERT_EQ(deserialized_method_set->second.begin()->upper(), request_method_high); + + // Check offers + // Create uint16_t from bytes. + std::array uint16_array_offer_service_{offer_service_byte1, offer_service_byte2}; + std::array uint16_array_offer_instance_low_{instance_id_low_byte1, instance_id_low_byte2}; + std::array uint16_array_offer_instance_high_{instance_id_high_byte1, instance_id_high_byte2}; + std::array uint16_array_offer_instance2_low_{instance2_id_low_byte1, instance2_id_low_byte2}; + std::array uint16_array_offer_instance2_high_{instance2_id_low_byte1, instance2_id_low_byte2}; + + std::uint16_t offer_service = vsomeip_v3::bithelper::read_uint16_be(uint16_array_offer_service_.data()); + std::uint16_t offer_instance_low = vsomeip_v3::bithelper::read_uint16_be(uint16_array_offer_instance_low_.data()); + std::uint16_t offer_instance_high = vsomeip_v3::bithelper::read_uint16_be(uint16_array_offer_instance_high_.data()); + std::uint16_t offer_instance2_low = vsomeip_v3::bithelper::read_uint16_be(uint16_array_offer_instance2_low_.data()); + std::uint16_t offer_instance2_high = vsomeip_v3::bithelper::read_uint16_be(uint16_array_offer_instance2_high_.data()); + + // Check if method high and low were deserialized correctly by private method deserialize_u16 + auto deserialized_offer_service_set = its_policy->offers_.lower_bound( + boost::icl::interval::closed(offer_service, offer_service)); + + // Check if the associated instance low and high are located. + ASSERT_EQ(deserialized_offer_service_set->second.begin()->lower(), offer_instance_low); + ASSERT_EQ(deserialized_offer_service_set->second.begin()->upper(), offer_instance_high); + + // Get the second interval added by the type 1 instance2, create an iterator and advance it. + // Note if the second interval falls within the first one or vise versa, since we are using an interval set, it will only have 1 item. + boost::icl::interval_set::iterator it = deserialized_offer_service_set->second.begin(); + ASSERT_NE(++it, deserialized_offer_service_set->second.end()); + + // Check low and high are equal. + std::uint16_t offer_instance2_deserialized_lower = it->lower(); + std::uint16_t offer_instance2_deserialized_upper = it->upper(); + ASSERT_EQ(offer_instance2_deserialized_lower, offer_instance2_deserialized_upper); + ASSERT_EQ(offer_instance2_deserialized_lower, offer_instance2_low); + ASSERT_EQ(offer_instance2_deserialized_lower, offer_instance2_high); +} + +TEST(security_policy_test, serialize) { + std::unique_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy with type 2 instance and methods for requests_ + // Create a 54 length array. + const std::uint32_t resized_array_size = 54; + std::array byte_array_{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, 0 + // NOT SURE WHY THE SERIALIZATION IGNORES THE OFFERS. + // offer_service_byte1, offer_service_byte2, + // offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + // instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + // instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + // instance_id_low_byte1, instance_id_low_byte2, + // instance_id_high_byte1, instance_id_high_byte2, + // instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + // instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + // instance2_id_low_byte1, instance2_id_low_byte2 + }; + + // Fill policy with data. + const vsomeip_v3::byte_t* data_ptr_ = byte_array_.data(); + std::uint32_t data_size_ = array_size; + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Create a vector to receive the results of the serialization. + std::vector byte_vector; + + // Test Method. + ASSERT_TRUE(its_policy->serialize(byte_vector)); + + // Check the vector length is equal to the original array size. + // the offer part of the policy does not get serialized. + ASSERT_EQ(byte_vector.size(), resized_array_size); + + // Check bytes. + for(std::uint32_t i = 0; i < byte_vector.size(); i++) + { + ASSERT_EQ(byte_vector.at(i), byte_array_[i]); + } + +} + +TEST(security_policy_test, get_uid_gid) { + std::unique_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy with type 2 instance and methods for requests_ + // and two instances for offers one type 2 instance and one type 1 for offers_ + // type 2 receives a uint16_t for low_ and another for high_ + // for type 1 low_ = high_ and only 1 uint16_t is passed. + std::array byte_array_{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t* data_ptr_ = byte_array_.data(); + std::uint32_t data_size_ = array_size; + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Create uint32_t to receive the value from the test method. + std::uint32_t deserialized_uid; + std::uint32_t deserialized_gid; + + // Test method, and compare them to the created uid and gid. + #ifndef __QNX__ + ASSERT_TRUE(its_policy->get_uid_gid(deserialized_uid, deserialized_gid)); + #endif + ASSERT_EQ(deserialized_uid, uid); + ASSERT_EQ(deserialized_gid, gid); +} + +TEST(security_policy_test, deserialize_uid_gid) { + std::unique_ptr its_policy(new vsomeip_v3::policy()); + + // Create an array of policy with type 2 instance and methods for requests_ + // and two instances for offers one type 2 instance and one type 1 for offers_ + // type 2 receives a uint16_t for low_ and another for high_ + // for type 1 low_ = high_ and only 1 uint16_t is passed. + std::array byte_array_{ + uid_byte1, uid_byte2, uid_byte3, uid_byte4, + gid_byte1, gid_byte2, gid_byte3, gid_byte4, + request_length_byte1, request_length_byte2, request_length_byte3, request_length_byte4, + request_service_byte1, request_service_byte2, + id_array_length_byte1, id_array_length_byte2, id_array_length_byte3, id_array_length_byte4, + request_instance_idlist_byte1, request_instance_idlist_byte2, request_instance_idlist_byte3, request_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + request_method_idlist_byte1, request_method_idlist_byte2, request_method_idlist_byte3, request_method_idlist_byte4, + method_id_length_byte1, method_id_length_byte2, method_id_length_byte3, method_id_length_byte4, + method_id_type_byte1, method_id_type_byte2, method_id_type_byte3, method_id_type_byte4, + method_id_low_byte1, method_id_low_byte2, + method_id_high_byte1, method_id_high_byte2, + offer_length_byte1, offer_length_byte2, offer_length_byte3, offer_length_byte4, + offer_service_byte1, offer_service_byte2, + offer_instance_idlist_byte1, offer_instance_idlist_byte2, offer_instance_idlist_byte3, offer_instance_idlist_byte4, + instance_id_length_byte1, instance_id_length_byte2, instance_id_length_byte3, instance_id_length_byte4, + instance_id_type_byte1, instance_id_type_byte2, instance_id_type_byte3, instance_id_type_byte4, + instance_id_low_byte1, instance_id_low_byte2, + instance_id_high_byte1, instance_id_high_byte2, + instance2_id_length_byte1, instance2_id_length_byte2, instance2_id_length_byte3, instance2_id_length_byte4, + instance2_id_type_byte1, instance2_id_type_byte2, instance2_id_type_byte3, instance2_id_type_byte4, + instance2_id_low_byte1, instance2_id_low_byte2 + }; + + const vsomeip_v3::byte_t* data_ptr_ = byte_array_.data(); + std::uint32_t data_size_ = array_size; + ASSERT_TRUE(its_policy->deserialize(data_ptr_, data_size_)); + + // Create uint32_t to receive the value from the test method. + std::uint32_t deserialized_uid; + std::uint32_t deserialized_gid; + + // Resetting the pointers. + data_ptr_ = byte_array_.data(); + data_size_ = array_size; + + // Test method. + #ifndef __QNX__ + ASSERT_TRUE(its_policy->deserialize_uid_gid(data_ptr_, data_size_, deserialized_uid, deserialized_gid)); + #endif + ASSERT_EQ(deserialized_uid, uid); + ASSERT_EQ(deserialized_gid, gid); +} diff --git a/test/unit_tests/security_tests/CMakeLists.txt b/test/unit_tests/security_tests/CMakeLists.txt new file mode 100644 index 000000000..cc03debf7 --- /dev/null +++ b/test/unit_tests/security_tests/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_security_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + Threads::Threads + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + vsomeip_utilities +) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/utility_tests/ut_ByteOperation.cpp b/test/unit_tests/utility_tests/ut_ByteOperation.cpp new file mode 100644 index 000000000..5eee0d707 --- /dev/null +++ b/test/unit_tests/utility_tests/ut_ByteOperation.cpp @@ -0,0 +1,170 @@ +// Copyright (C) 2023 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 "../../../implementation/utility/include/bithelper.hpp" + +#include + +TEST(byte_operations, MACRO_VSOMEIP_BYTES_TO_WORD) +{ + uint8_t payload[8] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; + + uint16_t its_service = vsomeip_v3::bithelper::read_uint16_be(payload+VSOMEIP_SERVICE_POS_MIN); + uint16_t its_method = vsomeip_v3::bithelper::read_uint16_be(payload+VSOMEIP_METHOD_POS_MIN); + + EXPECT_EQ(its_service, 0x1112); + EXPECT_EQ(its_method, 0x1314); +} + +TEST(byte_operations, MACRO_VSOMEIP_BYTES_TO_LONG) +{ + uint8_t payload[8] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; + + uint32_t its_data = vsomeip_v3::bithelper::read_uint32_be(payload+2); + EXPECT_EQ(its_data, 0x13141516); + + uint32_t its_data2 = vsomeip_v3::bithelper::read_uint32_le(payload+2); + EXPECT_EQ(its_data2, 0x16151413); +} + +TEST(byte_operations, MACRO_VSOMEIP_BYTES_TO_LONG_LONG) +{ + uint8_t payload[8] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; + + uint64_t its_data = vsomeip_v3::bithelper::read_uint64_be(payload); + EXPECT_EQ(its_data, 0x1112131415161718); +} + +TEST(byte_operations, MACRO_VSOMEIP_WORDS_TO_LONG) { + uint16_t serviceid = 0x1111; + uint16_t methodid = 0x2222; + + const uint8_t request_message[] = {static_cast((serviceid & 0xFF00) >> 8), + static_cast( serviceid & 0x00FF), + static_cast((methodid & 0xFF00) >> 8), + static_cast( methodid & 0x00FF)}; + uint32_t header_method = vsomeip_v3::bithelper::read_uint32_be(request_message); + + EXPECT_EQ(header_method, 0x11112222); +} + +TEST(byte_operations, MACRO_VSOMEIP_WORD_BYTEx) { + uint16_t clientid = 0x1234; + uint8_t client[sizeof(clientid)] = {0}; + + vsomeip_v3::bithelper::write_uint16_be(clientid, client); + EXPECT_EQ(client[0], 0x12); + EXPECT_EQ(client[1], 0x34); + + vsomeip_v3::bithelper::write_uint16_le(clientid, client); + EXPECT_EQ(client[0], 0x34); + EXPECT_EQ(client[1], 0x12); +} + +TEST(byte_operations, MACRO_VSOMEIP_LONG_BYTEx) { + uint32_t payload = 0x12345678; + uint8_t data[sizeof(payload)] = {0}; + + vsomeip_v3::bithelper::write_uint32_be(payload, data); + EXPECT_EQ(data[0], 0x12); + EXPECT_EQ(data[1], 0x34); + EXPECT_EQ(data[2], 0x56); + EXPECT_EQ(data[3], 0x78); + + vsomeip_v3::bithelper::write_uint32_le(payload, data); + EXPECT_EQ(data[0], 0x78); + EXPECT_EQ(data[1], 0x56); + EXPECT_EQ(data[2], 0x34); + EXPECT_EQ(data[3], 0x12); +} + +TEST(byte_operations, MACRO_VSOMEIP_LONG_LONG_BYTEx) { + uint64_t payload = 0x1214161821232527; + uint8_t data[sizeof(payload)] = {0}; + + vsomeip_v3::bithelper::write_uint64_be(payload, data); + EXPECT_EQ(data[0], 0x12); + EXPECT_EQ(data[1], 0x14); + EXPECT_EQ(data[2], 0x16); + EXPECT_EQ(data[3], 0x18); + EXPECT_EQ(data[4], 0x21); + EXPECT_EQ(data[5], 0x23); + EXPECT_EQ(data[6], 0x25); + EXPECT_EQ(data[7], 0x27); + + vsomeip_v3::bithelper::write_uint64_le(payload, data); + EXPECT_EQ(data[0], 0x27); + EXPECT_EQ(data[1], 0x25); + EXPECT_EQ(data[2], 0x23); + EXPECT_EQ(data[3], 0x21); + EXPECT_EQ(data[4], 0x18); + EXPECT_EQ(data[5], 0x16); + EXPECT_EQ(data[6], 0x14); + EXPECT_EQ(data[7], 0x12); + +} + +TEST(byte_operations, MACRO_VSOMEIP_LONG_WORDx) { + uint32_t payload = 0x12345678; + uint8_t data[sizeof(payload)] = {0}; + + vsomeip_v3::bithelper::write_uint32_le(payload, data); + EXPECT_EQ(data[0], 0x78); + EXPECT_EQ(data[1], 0x56); + EXPECT_EQ(data[2], 0x34); + EXPECT_EQ(data[3], 0x12); +} + +TEST(byte_operations, TestUint16) { + uint8_t input[] = {0xab, 0xcd}; + EXPECT_EQ(0xabcd, vsomeip_v3::bithelper::read_uint16_be(input)); + + uint8_t output[sizeof(input)] = {0}; + vsomeip_v3::bithelper::write_uint16_be(0x1234, output); + EXPECT_EQ(0x12, output[0]); + EXPECT_EQ(0x34, output[1]); +} + +TEST(byte_operations, TestUint32_BigEndian) { + uint8_t input[] = {0x12, 0x34, 0x56, 0x78}; + EXPECT_EQ(0x12345678U, vsomeip_v3::bithelper::read_uint32_be(input)); + + uint8_t output[sizeof(uint32_t)] = {0}; + vsomeip_v3::bithelper::write_uint32_be(0xabcd1234, output); + EXPECT_EQ(0xab, output[0]); + EXPECT_EQ(0xcd, output[1]); + EXPECT_EQ(0x12, output[2]); + EXPECT_EQ(0x34, output[3]); +} + +TEST(byte_operations, TestUint32_LittleEndian) { + uint8_t input[] = {0x12, 0x34, 0x56, 0x78}; + EXPECT_EQ(0x78563412U, vsomeip_v3::bithelper::read_uint32_le(input)); + + uint8_t output[sizeof(uint32_t)] = {0}; + vsomeip_v3::bithelper::write_uint32_le(0xabcd1234, output); + EXPECT_EQ(0xab, output[3]); + EXPECT_EQ(0xcd, output[2]); + EXPECT_EQ(0x12, output[1]); + EXPECT_EQ(0x34, output[0]); +} + +TEST(byte_operations, TestUint64) { + uint8_t input[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef}; + EXPECT_EQ(0x1234567890ABCDEFULL, vsomeip_v3::bithelper::read_uint64_be(input)); + + uint8_t output[sizeof(input)] = {0}; + vsomeip_v3::bithelper::write_uint64_be(0x1234567890ABCDEFULL, output); + EXPECT_EQ(0x12, output[0]); + EXPECT_EQ(0x34, output[1]); + EXPECT_EQ(0x56, output[2]); + EXPECT_EQ(0x78, output[3]); + EXPECT_EQ(0x90, output[4]); + EXPECT_EQ(0xab, output[5]); + EXPECT_EQ(0xcd, output[6]); + EXPECT_EQ(0xef, output[7]); +} diff --git a/test/unit_tests/utility_utility_tests/CMakeLists.txt b/test/unit_tests/utility_utility_tests/CMakeLists.txt new file mode 100644 index 000000000..9f37c2a89 --- /dev/null +++ b/test/unit_tests/utility_utility_tests/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (C) 2015-2024 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/. + +project("unit_tests_utility_tests" LANGUAGES CXX) + +file(GLOB SRCS ../main.cpp *.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable(${PROJECT_NAME} ${SRCS}) +target_link_libraries( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest + vsomeip_utilities +) + +add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/utility_utility_tests/ut_utility.cpp b/test/unit_tests/utility_utility_tests/ut_utility.cpp new file mode 100644 index 000000000..cf0109dad --- /dev/null +++ b/test/unit_tests/utility_utility_tests/ut_utility.cpp @@ -0,0 +1,451 @@ +// Copyright (C) 2024 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 "../../../implementation/configuration/include/configuration_impl.hpp" +#include "../../../implementation/utility/include/bithelper.hpp" +#include "../../../implementation/utility/include/utility.hpp" + +using vsomeip_v3::bithelper; + +namespace { + const std::uint8_t array_size = 18; + const std::uint8_t array_size_too_short = 2; + const std::uint32_t payload_length = 2; + const vsomeip_v3::byte_t serviceID_byte1 = 0x01; + const vsomeip_v3::byte_t serviceID_byte2 = 0x02; + const vsomeip_v3::byte_t methodID_byte1 = 0x03; + const vsomeip_v3::byte_t methodID_byte2 = 0x04; + const vsomeip_v3::byte_t length_byte1 = 0x00; + const vsomeip_v3::byte_t length_byte2 = 0x00; + const vsomeip_v3::byte_t length_byte3 = 0x00; + const vsomeip_v3::byte_t length_byte4 = 0x0A; + const vsomeip_v3::byte_t clientID_byte1 = 0x00; + const vsomeip_v3::byte_t clientID_byte2 = 0x00; + const vsomeip_v3::byte_t sessionID_byte1 = 0x00; + const vsomeip_v3::byte_t sessionID_byte2 = 0x00; + const vsomeip_v3::byte_t version_byte = 0x01; + const vsomeip_v3::byte_t interface_byte = 0x02; + const vsomeip_v3::byte_t messageType_byte = 0x02; + const vsomeip_v3::byte_t returnCode_byte = 0x00; + const vsomeip_v3::byte_t payload_byte1 = 0x13; + const vsomeip_v3::byte_t payload_byte2 = 0x37; +} + +TEST(utility_test, get_message_size) { + std::unique_ptr its_utility; + + // Create an array of size 18. 4 header, 4 size, 10 payload bytes. + std::array byte_array_{ + serviceID_byte1, serviceID_byte2, + methodID_byte1, methodID_byte2, + length_byte1, length_byte2, length_byte3, length_byte4, + clientID_byte1, clientID_byte2, + sessionID_byte1, sessionID_byte2, + version_byte, + interface_byte, + messageType_byte, + returnCode_byte, + payload_byte1, payload_byte2 + }; + + // Create an array to pass to bithelper. + std::array uint32_array_{length_byte1, length_byte2, length_byte3, length_byte4}; + + // Getting size. + std::uint32_t size_ = VSOMEIP_SOMEIP_HEADER_SIZE + bithelper::read_uint32_be(uint32_array_.data()); + + // Check if function returns the uint32_t size_ we expect to receive, header + size passed by the 4 length_bytes. + ASSERT_EQ(its_utility->get_message_size(byte_array_.data(), byte_array_.size()), size_); + + // Make the 4 size bytes equal to zero. + byte_array_.at(4) = 0; + byte_array_.at(5) = 0; + byte_array_.at(6) = 0; + byte_array_.at(7) = 0; + // Check that the message size is now equal to only the someip header. + ASSERT_EQ(its_utility->get_message_size(byte_array_.data(), byte_array_.size()), VSOMEIP_SOMEIP_HEADER_SIZE); + + // Create an array shorter than the minimum someip header. + std::array byte_array_too_short{serviceID_byte1, serviceID_byte2}; + // Check that 0 is returned for the expected length of the message. + ASSERT_EQ(its_utility->get_message_size(byte_array_too_short.data(), byte_array_too_short.size()), 0); +} + +TEST(utility_test, get_payload_size) { + std::unique_ptr its_utility; + + // Anatomy of a SOMEIP message. + // Byte 1-2: Service ID, Byte 3-4: Method ID, Byte 5-8: length, + // byte 9-10: Client id, byte 11-12: session id, + // byte 13: SOME/IP version, byte 14: interface version, + // byte 15: Message type, byte 16: Return Code. + // Length are all the bytes that come after it. (byte 9+) + // Payload here is the bytes that come after all those (byte 16++). + + // Create an array of size 18. 4 header, 4 size, 10 payload bytes. + std::array byte_array_{ + serviceID_byte1, serviceID_byte2, + methodID_byte1, methodID_byte2, + length_byte1, length_byte2, length_byte3, length_byte4, + clientID_byte1, clientID_byte2, + sessionID_byte1, sessionID_byte2, + version_byte, + interface_byte, + messageType_byte, + returnCode_byte, + payload_byte1, payload_byte2 + }; + + // Check if function returns the uint32_t size_ we expect to receive, header + size passed by the 4 length_bytes. + ASSERT_EQ(its_utility->get_payload_size(byte_array_.data(), byte_array_.size()), payload_length); + + // Check if function returns 0, if length field we pass (0x0A) passed is greater than the array size - 8 + ASSERT_EQ(its_utility->get_payload_size(byte_array_.data(), byte_array_.size() - VSOMEIP_SOMEIP_HEADER_SIZE), 0); + + // Make the length smaller than 8. + byte_array_.at(4) = 0; + byte_array_.at(5) = 0; + byte_array_.at(6) = 0; + byte_array_.at(7) = 7; + // Check that the message size is now equal to only the someip header. + ASSERT_EQ(its_utility->get_payload_size(byte_array_.data(), byte_array_.size()), 0); + + // Create an array shorter than the minimum someip header. + std::array byte_array_too_short{serviceID_byte1, serviceID_byte2}; + // Check that 0 is returned for the expected length of the message. + ASSERT_EQ(its_utility->get_payload_size(byte_array_too_short.data(), byte_array_too_short.size()), 0); +} + +TEST(utility_test, is_routing_manager) { + std::unique_ptr its_utility; + + // Random network name. + const std::string network_("test_network"); + + // First caller become the routing manager. + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Subsequent callers can not be routing manager. + ASSERT_FALSE(its_utility->is_routing_manager(network_)); + + // Clean up. + its_utility->remove_lockfile(network_); + + std::unique_ptr its_utility2; + + // Weird network name. + const std::string network2_("\\\\////\0"); + + // Expect the network name to lead to failure. + ASSERT_FALSE(its_utility2->is_routing_manager(network2_)); +} + +TEST(utility_test, remove_lockfile) { + std::unique_ptr its_utility; + + // Random network name. + const std::string network_("test"); + + // Expect nothing to happen. + its_utility->remove_lockfile(network_); + + // First caller become the routing manager. + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Subsequent callers can not be routing manager. + ASSERT_FALSE(its_utility->is_routing_manager(network_)); + + its_utility->remove_lockfile(network_); + + // Since the network got erased this shoud return true once more, as new "first caller". + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Clean up. + its_utility->remove_lockfile(network_); + + // WIP not sure how to rest failure to close or remove the test.lck file. +} + +TEST(utility_test, exists) { + std::unique_ptr its_utility; + + // Random network name. + const std::string network_("exists_tests"); + + // Expect false. + ASSERT_FALSE(its_utility->exists(network_)); + + // First caller become the routing manager, creating the network creates file /tmp/exists_tests.lck + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Create a path variable. + const std::string path_("/tmp/exists_tests.lck"); + + // Expect true. + ASSERT_TRUE(its_utility->exists(path_)); + + // Clean up. + its_utility->remove_lockfile(network_); + + // Expect false since file should be erased. + ASSERT_FALSE(its_utility->exists(path_)); +} + +TEST(utility_test, is_file) { + std::unique_ptr its_utility; + + // Random network name. + const std::string network_("is_file_tests"); + const std::string file_("/tmp/is_file_tests.lck"); + const std::string directory_("/tmp/"); + + // Expect false. + ASSERT_FALSE(its_utility->is_file(network_)); + + // Expect false since file is not yet created. + ASSERT_FALSE(its_utility->is_file(file_)); + + // Expect false since we pass a directory. + ASSERT_FALSE(its_utility->is_file(directory_)); + + // First caller become the routing manager, creating the network creates file /tmp/is_file_tests.lck + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Expect true. + ASSERT_TRUE(its_utility->is_file(file_)); + + // Clean up + its_utility->remove_lockfile(network_); +} + +TEST(utility_test, is_folder) { + std::unique_ptr its_utility; + + // Random network name. + const std::string network_("is_folder_tests"); + const std::string file_("/tmp/is_folder_tests.lck"); + const std::string directory_("/tmp/"); + + // Expect false. + ASSERT_FALSE(its_utility->is_folder(network_)); + + // Expect false since file is not a folder. + ASSERT_FALSE(its_utility->is_folder(file_)); + + // First caller become the routing manager, creating the network creates file /tmp/is_folder_tests.lck + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Expect true. + ASSERT_TRUE(its_utility->is_folder(directory_)); + + // Clean up + its_utility->remove_lockfile(network_); +} + +TEST(utility_test, get_base_path) { + std::unique_ptr its_utility; + + // Random network name. + const std::string network_("is_folder_tests"); + const std::string base_path_("/tmp/is_folder_tests-"); + + // First caller become the routing manager, creating the network creates file /tmp/is_folder_tests.lck + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Assert equal + ASSERT_EQ(its_utility->get_base_path(network_), base_path_); + + // Clean up + its_utility->remove_lockfile(network_); +} + +TEST(utility_test, request_client_id) { + std::unique_ptr its_utility; + + const std::string path_("/tmp/"); + std::shared_ptr its_config = + std::make_shared(path_); + + // Client info + vsomeip_v3::client_t client_ = 0x1000; + const std::string client_name_("client"); + vsomeip_v3::client_t client2_ = VSOMEIP_CLIENT_UNSET; + const std::string client_name2_("client2"); + + // Default network name of config + const std::string network_("vsomeip"); + + // Network should not exist yet, expect client to be unset. + ASSERT_EQ(its_utility->request_client_id(its_config, client_name_, client_), VSOMEIP_CLIENT_UNSET); + + // Call is_routing_manager to create the network + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Test method expect to return the client_ id. + ASSERT_EQ(its_utility->request_client_id(its_config, client_name_, client_), client_); + + // Get from the configs the smallest and biggest client numbers that can be assigned. + // Should be 0x100 to 0x1ff + static const std::uint16_t its_diagnosis_mask = its_config->get_diagnosis_mask(); + static const std::uint16_t its_masked_diagnosis_address = static_cast( + (its_config->get_diagnosis_address() << 8) & its_diagnosis_mask); + static const std::uint16_t its_client_mask = static_cast(~its_diagnosis_mask); + static const std::uint16_t its_biggest_client = its_masked_diagnosis_address | its_client_mask; + static const std::uint16_t its_smallest_client = its_masked_diagnosis_address; + + std::uint16_t client_id = its_utility->request_client_id(its_config, client_name2_, client2_); + + // Expect first call with unset id to be the smallest client allowed +1. + ASSERT_EQ(client_id, its_smallest_client+1); + + // Cycle through all numbers available. + while(client_id < its_biggest_client) + { + client_id = its_utility->request_client_id(its_config, client_name2_, client2_); + ASSERT_GE(client_id, its_smallest_client); + ASSERT_LE(client_id, its_biggest_client); + } + + // Expect the client id to be the biggest client client number allowed. + ASSERT_EQ(client_id, its_biggest_client); + + // Expect unset since all numbers have been used. + ASSERT_EQ(its_utility->request_client_id(its_config, client_name2_, client2_), VSOMEIP_CLIENT_UNSET); + + // Clean up + its_utility->remove_lockfile(network_); +} + +TEST(utility_test, get_used_client_ids) { + std::unique_ptr its_utility; + + const std::string path_("/tmp/"); + std::shared_ptr its_config = + std::make_shared(path_); + + // Client info + vsomeip_v3::client_t client_ = 0x1000; + vsomeip_v3::client_t client1_ = 0x1001; + vsomeip_v3::client_t client2_ = 0x1002; + vsomeip_v3::client_t client3_ = 0x1003; + vsomeip_v3::client_t client4_ = 0x1004; + const std::string client_name_("client"); + + // Default network name of config + const std::string network_("vsomeip"); + + // Call is_routing_manager to create the network + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Call request client id to emplace a client. + ASSERT_EQ(its_utility->request_client_id(its_config, client_name_, client_), client_); + + // Test method expect to return the client_ id. + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 1); + + its_utility->request_client_id(its_config, client_name_, client1_); + its_utility->request_client_id(its_config, client_name_, client2_); + its_utility->request_client_id(its_config, client_name_, client3_); + its_utility->request_client_id(its_config, client_name_, client4_); + + // Test method expect to return the client_ id. + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 5); + ASSERT_EQ(its_utility->get_used_client_ids(network_).count(VSOMEIP_CLIENT_UNSET), 0); + + // Clean up + its_utility->remove_lockfile(network_); +} + +TEST(utility_test, release_client_id) { + std::unique_ptr its_utility; + + const std::string path_("/tmp/"); + std::shared_ptr its_config = + std::make_shared(path_); + + // Client info + vsomeip_v3::client_t client_ = 0x1000; + vsomeip_v3::client_t client1_ = 0x1001; + vsomeip_v3::client_t client2_ = 0x1002; + vsomeip_v3::client_t client3_ = 0x1003; + vsomeip_v3::client_t client4_ = 0x1004; + const std::string client_name_("client"); + + // Default network name of config + const std::string network_("vsomeip"); + + // Call is_routing_manager to create the network + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Call request client id to emplace a clients. + its_utility->request_client_id(its_config, client_name_, client_); + its_utility->request_client_id(its_config, client_name_, client1_); + its_utility->request_client_id(its_config, client_name_, client2_); + its_utility->request_client_id(its_config, client_name_, client3_); + its_utility->request_client_id(its_config, client_name_, client4_); + + // Expect to get size 5 + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 5); + + // Test Method. + its_utility->release_client_id(network_, client_); + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 4); + + its_utility->release_client_id(network_, client1_); + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 3); + + its_utility->release_client_id(network_, client2_); + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 2); + + its_utility->release_client_id(network_, client3_); + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 1); + + its_utility->release_client_id(network_, client4_); + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 0); + + // Clean up + its_utility->remove_lockfile(network_); +} + +TEST(utility_test, reset_client_ids) { + std::unique_ptr its_utility; + + const std::string path_("/tmp/"); + std::shared_ptr its_config = + std::make_shared(path_); + + // Client info + vsomeip_v3::client_t client_ = 0x1000; + vsomeip_v3::client_t client1_ = 0x1001; + vsomeip_v3::client_t client2_ = 0x1002; + vsomeip_v3::client_t client3_ = 0x1003; + vsomeip_v3::client_t client4_ = 0x1004; + const std::string client_name_("client"); + + // Default network name of config + const std::string network_("vsomeip"); + + // Call is_routing_manager to create the network + ASSERT_TRUE(its_utility->is_routing_manager(network_)); + + // Call request client id to emplace a clients. + its_utility->request_client_id(its_config, client_name_, client_); + its_utility->request_client_id(its_config, client_name_, client1_); + its_utility->request_client_id(its_config, client_name_, client2_); + its_utility->request_client_id(its_config, client_name_, client3_); + its_utility->request_client_id(its_config, client_name_, client4_); + + // Expect to get size 5 + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 5); + + // Test Method. + its_utility->reset_client_ids(network_); + ASSERT_EQ(its_utility->get_used_client_ids(network_).size(), 0); + + // Clean up + its_utility->remove_lockfile(network_); +} diff --git a/tools/CMakeLists.txt b/tools/vsomeip_ctrl/CMakeLists.txt similarity index 100% rename from tools/CMakeLists.txt rename to tools/vsomeip_ctrl/CMakeLists.txt diff --git a/tools/vsomeip_ctrl.cpp b/tools/vsomeip_ctrl/vsomeip_ctrl.cpp similarity index 95% rename from tools/vsomeip_ctrl.cpp rename to tools/vsomeip_ctrl/vsomeip_ctrl.cpp index 3e74a8322..9051fdc2c 100644 --- a/tools/vsomeip_ctrl.cpp +++ b/tools/vsomeip_ctrl/vsomeip_ctrl.cpp @@ -7,7 +7,7 @@ #include #include "../implementation/service_discovery/include/constants.hpp" -#include "../implementation/utility/include/byteorder.hpp" +#include "../implementation/utility/include/bithelper.hpp" #include #include @@ -45,16 +45,12 @@ class vsomeip_sender { "is 16 Bytes, exiting."; exit(EXIT_FAILURE); } - service_id_ = VSOMEIP_BYTES_TO_WORD(user_message_[VSOMEIP_SERVICE_POS_MIN], - user_message_[VSOMEIP_SERVICE_POS_MAX]); - method_id_ = VSOMEIP_BYTES_TO_WORD(user_message_[VSOMEIP_METHOD_POS_MIN], - user_message_[VSOMEIP_METHOD_POS_MAX]); - length_ = VSOMEIP_BYTES_TO_LONG(user_message_[VSOMEIP_LENGTH_POS_MIN], - user_message_[VSOMEIP_LENGTH_POS_MIN+1], - user_message_[VSOMEIP_LENGTH_POS_MIN+2], - user_message_[VSOMEIP_LENGTH_POS_MAX]); - client_id_ = VSOMEIP_BYTES_TO_WORD(user_message_[VSOMEIP_CLIENT_POS_MIN], - user_message_[VSOMEIP_CLIENT_POS_MAX]); + + service_id_ = vsomeip::bithelper::read_uint16_be(&user_message_[VSOMEIP_SERVICE_POS_MIN]); + method_id_ = vsomeip::bithelper::read_uint16_be(&user_message_[VSOMEIP_METHOD_POS_MIN]); + length_ = vsomeip::bithelper::read_uint32_be(&user_message_[VSOMEIP_LENGTH_POS_MIN]); + client_id_ = vsomeip::bithelper::read_uint16_be(&user_message_[VSOMEIP_CLIENT_POS_MIN]); + interface_version_ = user_message_[VSOMEIP_INTERFACE_VERSION_POS]; message_type_ = static_cast(user_message_[VSOMEIP_MESSAGE_TYPE_POS]); return_code_ = static_cast(user_message_[VSOMEIP_RETURN_CODE_POS]); @@ -421,7 +417,8 @@ int main(int argc, char** argv) { exit(EXIT_FAILURE); } } - instance = VSOMEIP_BYTES_TO_WORD(high, low); + uint8_t its_instance[2] = {high, low}; + instance = vsomeip::bithelper::read_uint16_be(its_instance); } } diff --git a/tools/wireshark_plugin/README.md b/tools/wireshark_plugin/README.md new file mode 100644 index 000000000..f3623de94 --- /dev/null +++ b/tools/wireshark_plugin/README.md @@ -0,0 +1,13 @@ +# vsomeip-dissector +Wireshark dissector for vSomeip internal communication via TCP + +## How To Use + +1. Place `vsomeip-dissector.lua` file in `~/.config/wireshark/plugins/vsomeip/vsomeip-dissector.lua` + (create `plugins` directory if it doesn't exist) +2. In wireshark go to `Analyze` > `Reload Lua Plugins` +3. In wireshark go to `Analyze` > `Enable Protocols` and search for `vsomeip` and enable it + +## Referances + +vSomeip Protocol definitions: documentation/vsomeipProtocol.md \ No newline at end of file diff --git a/tools/wireshark_plugin/vsomeip-dissector.lua b/tools/wireshark_plugin/vsomeip-dissector.lua new file mode 100644 index 000000000..7c49d32d3 --- /dev/null +++ b/tools/wireshark_plugin/vsomeip-dissector.lua @@ -0,0 +1,426 @@ +--[[ + Wireshark Lua vsomeip protocol dissector + vsomeip-dissector.lua V0.0.1 +--]] + +protocol_name = 'vsomeip' + +vsomeip_protocol = Proto(protocol_name, protocol_name:upper() .. ' Protocol') +vsomeip_command = ProtoField.uint8(protocol_name .. '.command' , "Command", base.HEX) +vsomeip_version = ProtoField.uint16(protocol_name .. '.version' , "Version", base.DEC) +vsomeip_client = ProtoField.uint16(protocol_name .. '.client' , "Client", base.HEX) +vsomeip_size = ProtoField.uint32(protocol_name .. '.size' , "Size", base.DEC) + +vsomeip_name = ProtoField.string(protocol_name .. '.name' , "Name") + +vsomeip_instance = ProtoField.uint16(protocol_name .. '.instance' , "Instance", base.HEX) +vsomeip_reliable = ProtoField.uint8(protocol_name .. '.reliable' , "Reliable", base.DEC) +vsomeip_crc = ProtoField.bytes(protocol_name .. '.crc' , "CRC", base_HEX) +vsomeip_dstClient = ProtoField.uint16(protocol_name .. '.dstClient' , "Dst Client", base.HEX) +vsomeip_payload = ProtoField.bytes(protocol_name .. '.payload' , "Payload", base_HEX) + +vsomeip_service = ProtoField.uint16(protocol_name .. '.service' , "Service", base.HEX) +vsomeip_eventgroup = ProtoField.uint16(protocol_name .. '.eventgroup' , "Eventgroup", base.HEX) +vsomeip_subscriber = ProtoField.uint16(protocol_name .. '.subscriber' , "Subscriber", base.HEX) +vsomeip_notifier = ProtoField.uint16(protocol_name .. '.notifier' , "Notifier", base.HEX) +vsomeip_event = ProtoField.uint16(protocol_name .. '.event' , "Event", base.HEX) +vsomeip_id = ProtoField.uint16(protocol_name .. '.id' , "ID", base.HEX) + +vsomeip_provided = ProtoField.uint8(protocol_name .. '.provided' , "Provided", base.DEC) + +vsomeip_major = ProtoField.uint8(protocol_name .. '.major' , "Major", base.HEX) +vsomeip_minor = ProtoField.uint32(protocol_name .. '.minor' , "Minor", base.HEX) + +vsomeip_offer_type = ProtoField.uint8(protocol_name .. '.offer_type' , "OfferType", base.DEC) + +vsomeip_pending_offer_id = ProtoField.uint32(protocol_name .. '.pending_offer_id' , "PendingOfferId", base.HEX) + +vsomeip_update_id = ProtoField.uint32(protocol_name .. '.update_id' , "UpdateId", base.HEX) +vsomeip_uid = ProtoField.uint32(protocol_name .. '.uid' , "UID", base.HEX) +vsomeip_gid = ProtoField.uint32(protocol_name .. '.gid' , "GID", base.HEX) +vsomeip_policy_count = ProtoField.uint32(protocol_name .. '.policy_count' , "PoliciesCount", base.HEX) +vsomeip_policy = ProtoField.bytes(protocol_name .. '.policy' , "Policy", base_HEX) + +-- TODO Parse filter in VSOMEIP_SUBSCRIBE +vsomeip_filter = ProtoField.bytes(protocol_name .. '.filter' , "Filter", base_HEX) + +-- TODO make this a subtree to list all entries in VSOMEIP_ROUTING_INFO +vsomeip_entries = ProtoField.bytes(protocol_name .. '.entries' , "Entries", base_HEX) + +-- TODO make this a subtree to list all offered_services in VSOMEIP_OFFERED_SERVICES_RESPONSE +vsomeip_offered_services = ProtoField.bytes(protocol_name .. '.offered_services' , "OfferedServices", base_HEX) + +-- TODO make this a subtree to list all configurations in VSOMEIP_CONFIG +vsomeip_configurations = ProtoField.bytes(protocol_name .. '.configurations' , "Configurations", base_HEX) + +-- TODO make this a subtree to list all configurations in VSOMEIP_UPDATE_SECURITY_CREDENTIALS +vsomeip_credentials = ProtoField.bytes(protocol_name .. '.credentials' , "Credentials", base_HEX) + +-- TODO make this a subtree to list all configurations in VSOMEIP_DISTRIBUTE_SECURITY_POLICIES +vsomeip_policies = ProtoField.bytes(protocol_name .. '.policies' , "Policies", base_HEX) + +vsomeip_protocol.fields = { + vsomeip_command, vsomeip_version, + vsomeip_client, vsomeip_size, + vsomeip_name, + vsomeip_instance, vsomeip_reliable, vsomeip_crc, vsomeip_dstClient, vsomeip_payload, + vsomeip_service, vsomeip_eventgroup, vsomeip_subscriber, vsomeip_notifier, vsomeip_event, vsomeip_id, + vsomeip_provided, + vsomeip_major, vsomeip_minor, + vsomeip_filter, + vsomeip_entries +} + +function vsomeip_protocol.dissector(buffer, pinfo, tree) + local length = buffer:len() + + if length < 9 then + return + end + local vsip_start = buffer(0, 4):uint() + local vsip_end = buffer(length - 4, 4):uint() + -- Is this a vsomeip packet ? vsip packets start with 0x67376D07 and end with 0x076D3767 + if vsip_start ~= 0x67376D07 or vsip_end ~= 0x076D3767 then + return + end + + pinfo.cols.protocol = "vSomeip" + + -- Command + local command_number = buffer(4, 1) + local command_name = get_command_name(command_number:uint()) + + local subtree = tree:add(vsomeip_protocol, buffer(), "vSomeip (" .. length .. " bytes) " .. command_name) + subtree:add_le(vsomeip_command, command_number):append_text(" (" .. command_name .. ")") + pinfo.cols.info = command_name + + if command_name == "VSOMEIP_APPLICATION_LOST" + or command_name == "VSOMEIP_ID_RESPONSE" + or command_name == "VSOMEIP_ID_REQUEST" + or command_name == "VSOMEIP_UNKOWN" + or length < 11 then + return + end + + -- Version + local command_version = buffer(5, 2) + subtree:add_le(vsomeip_version, command_version) + + local buffer_cursor = 7 + if command_name ~= "VSOMEIP_SUSPEND" then + -- Client + local command_client = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + -- Size + local command_size = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + subtree:add_le(vsomeip_client, command_client) + subtree:add_le(vsomeip_size, command_size) + pinfo.cols.info:append(" (" ..command_client(1,1)..command_client(0,1).. ")") + else + -- Size + local command_size = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + subtree:add_le(vsomeip_size, command_size) + end + + -- More Complex commands here (buffer_cursor starts after size) + if command_name == "VSOMEIP_SEND" or command_name == "VSOMEIP_NOTIFY" or command_name == "VSOMEIP_NOTIFY_ONE" then + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_reliable = buffer(buffer_cursor, 1) + local command_reliable_name = get_reliability(command_reliable:uint()) + buffer_cursor = buffer_cursor + 1 + local command_crc = buffer(buffer_cursor, 1) + buffer_cursor = buffer_cursor + 1 + local command_dstClient = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_payload = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add_le(vsomeip_instance, command_instance) + subtree:add(vsomeip_reliable, command_reliable):append_text(" (" .. command_reliable_name .. ")") + subtree:add(vsomeip_crc, command_crc) + subtree:add_le(vsomeip_dstClient, command_dstClient) + subtree:add(vsomeip_payload, command_payload) + + pinfo.cols.info:append(" --"..command_reliable_name.."--> (" ..command_dstClient(1,1)..command_dstClient(0,1).. ")") + elseif command_name == "VSOMEIP_ASSIGN_CLIENT" then + local command_name = buffer(buffer_cursor, length - buffer_cursor - 4) + subtree:add(vsomeip_name, command_name) + + pinfo.cols.info:append(" "..command_name) + + elseif command_name == "VSOMEIP_ROUTING_INFO" then + local command_entries = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add(vsomeip_entries, command_entries) + + elseif command_name == "VSOMEIP_OFFER_SERVICE" or command_name == "VSOMEIP_STOP_OFFER_SERVICE" then + local command_service = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_major = buffer(buffer_cursor, 1) + buffer_cursor = buffer_cursor + 1 + local command_minor = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + + subtree:add_le(vsomeip_service, command_service) + subtree:add_le(vsomeip_instance, command_instance) + subtree:add_le(vsomeip_major, command_major) + subtree:add_le(vsomeip_minor, command_minor) + + pinfo.cols.info:append(" [" .. command_service(1,1)..command_service(0,1) ..".".. command_instance(1,1)..command_instance(0,1) .. "]") + + elseif command_name == "VSOMEIP_SUBSCRIBE" then + local command_service = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_eventgroup = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_major = buffer(buffer_cursor, 1) + buffer_cursor = buffer_cursor + 1 + local command_event = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_id = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + + subtree:add_le(vsomeip_service, command_service) + subtree:add_le(vsomeip_instance, command_instance) + subtree:add_le(vsomeip_eventgroup, command_eventgroup) + subtree:add(vsomeip_major, command_major) + subtree:add_le(vsomeip_event, command_event) + subtree:add_le(vsomeip_id, command_id) + if (length - buffer_cursor - 4) > 0 then + local command_filter = buffer(buffer_cursor, length - buffer_cursor - 4) + subtree:add(vsomeip_filter, command_filter) + end + + pinfo.cols.info:append(" [" .. command_service(1,1)..command_service(0,1) ..".".. command_instance(1,1)..command_instance(0,1) + .. "." .. command_eventgroup(1,1)..command_eventgroup(0,1) .. "." .. command_event(1,1)..command_event(0,1) .. "]") + + elseif command_name == "VSOMEIP_UNSUBSCRIBE" or command_name == "VSOMEIP_EXPIRE" then + local command_service = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_eventgroup = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_event = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_id = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + + subtree:add_le(vsomeip_service, command_service) + subtree:add_le(vsomeip_instance, command_instance) + subtree:add_le(vsomeip_eventgroup, command_eventgroup) + subtree:add_le(vsomeip_event, command_event) + subtree:add_le(vsomeip_id, command_id) + + pinfo.cols.info:append(" [" .. command_service(1,1)..command_service(0,1) ..".".. command_instance(1,1)..command_instance(0,1) + .. "." .. command_eventgroup(1,1)..command_eventgroup(0,1) .. "." .. command_event(1,1)..command_event(0,1) .. "]") + + elseif command_name == "VSOMEIP_RELEASE_SERVICE" then + local command_service = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + + subtree:add_le(vsomeip_service, command_service) + subtree:add_le(vsomeip_instance, command_instance) + + pinfo.cols.info:append(" [" .. command_service(1,1)..command_service(0,1) ..".".. command_instance(1,1)..command_instance(0,1) .. "]") + + elseif command_name == "VSOMEIP_SUBSCRIBE_NACK" or command_name == "VSOMEIP_SUBSCRIBE_ACK" then + local command_service = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_eventgroup = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_subscriber = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_event = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_id = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + + subtree:add_le(vsomeip_service, command_service) + subtree:add_le(vsomeip_instance, command_instance) + subtree:add_le(vsomeip_eventgroup, command_eventgroup) + subtree:add_le(vsomeip_subscriber, command_subscriber) + subtree:add_le(vsomeip_event, command_event) + subtree:add_le(vsomeip_id, command_id) + + pinfo.cols.info:append(" [" .. command_service(1,1)..command_service(0,1) ..".".. command_instance(1,1)..command_instance(0,1) + .. "." .. command_eventgroup(1,1)..command_eventgroup(0,1) .. "." .. command_event(1,1)..command_event(0,1) + .. "] (" .. command_subscriber(1,1)..command_subscriber(0,1) .. ")") + elseif command_name == "VSOMEIP_REGISTER_EVENT" then + local command_entries = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add(vsomeip_entries, command_entries) + + elseif command_name == "VSOMEIP_UNREGISTER_EVENT" then + local command_service = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_notifier = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_provided = buffer(buffer_cursor, 1) + buffer_cursor = buffer_cursor + 1 + + subtree:add_le(vsomeip_service, command_service) + subtree:add_le(vsomeip_instance, command_instance) + subtree:add_le(vsomeip_notifier, command_notifier) + subtree:add(vsomeip_provided, command_provided) + + pinfo.cols.info:append(" [" .. command_service(1,1)..command_service(0,1) ..".".. command_instance(1,1)..command_instance(0,1) .. "]") + + elseif command_name == "VSOMEIP_OFFERED_SERVICES_REQUEST" then + local command_offer_type = buffer(buffer_cursor, 1) + local command_offer_type_name = get_offer_type(command_offer_type:uint()) + + subtree:add(vsomeip_offer_type, command_offer_type):append_text(" (" .. command_offer_type_name .. ")") + + pinfo.cols.info:append(" (" .. command_offer_type_name .. ")") + elseif command_name == "VSOMEIP_OFFERED_SERVICES_RESPONSE" then + local command_offered_services = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add(vsomeip_offered_services, command_offered_services) + + elseif command_name == "VSOMEIP_UNSUBSCRIBE_ACK" then + local command_service = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_instance = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_eventgroup = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + local command_id = buffer(buffer_cursor, 2) + buffer_cursor = buffer_cursor + 2 + + subtree:add_le(vsomeip_service, command_service) + subtree:add_le(vsomeip_instance, command_instance) + subtree:add_le(vsomeip_eventgroup, command_eventgroup) + subtree:add_le(vsomeip_id, command_id) + + pinfo.cols.info:append(" [" .. command_service(1,1)..command_service(0,1) ..".".. command_instance(1,1)..command_instance(0,1) + .. "." .. command_eventgroup(1,1)..command_eventgroup(0,1) .. "]") + elseif command_name == "VSOMEIP_RESEND_PROVIDED_EVENTS" then + local command_pending_offer_id = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + + subtree:add_le(vsomeip_pending_offer_id, command_pending_offer_id) + + elseif command_name == "VSOMEIP_UPDATE_SECURITY_POLICY" or command_name == "VSOMEIP_UPDATE_SECURITY_POLICY_INT" then + local command_update_id = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + local command_offered_services = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add_le(vsomeip_update_id, command_update_id) + subtree:add(vsomeip_offered_services, command_offered_services) + + elseif command_name == "VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE" or command_name == "VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE" then + local command_update_id = buffer(buffer_cursor, 4) + + subtree:add_le(vsomeip_update_id, command_update_id) + elseif command_name == "VSOMEIP_REMOVE_SECURITY_POLICY" then + local command_update_id = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + local command_uid = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + local command_gid = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + + subtree:add_le(vsomeip_update_id, command_update_id) + subtree:add_le(vsomeip_uid, command_uid) + subtree:add_le(vsomeip_gid, command_gid) + + elseif command_name == "VSOMEIP_UPDATE_SECURITY_CREDENTIALS" then + local command_credentials = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add(vsomeip_credentials, command_credentials) + + elseif command_name == "VSOMEIP_DISTRIBUTE_SECURITY_POLICIES" then + local command_policy_count = buffer(buffer_cursor, 4) + buffer_cursor = buffer_cursor + 4 + local command_policies = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add_le(vsomeip_policy_count, command_policy_count) + subtree:add(vsomeip_policies, command_policies) + elseif command_name == "VSOMEIP_CONFIG" then + local command_configurations = buffer(buffer_cursor, length - buffer_cursor - 4) + + subtree:add(vsomeip_configurations, command_configurations) + end +end + +DissectorTable.get('tcp.port'):add('1-65535', vsomeip_protocol) + +function get_command_name(cmd) + local cmd_name = "VSOMEIP_UNKOWN" + + -- ¯\_(ツ)_/¯ + if cmd == 0x00 then cmd_name = "VSOMEIP_ASSIGN_CLIENT" + elseif cmd == 0x01 then cmd_name = "VSOMEIP_ASSIGN_CLIENT_ACK" + elseif cmd == 0x02 then cmd_name = "VSOMEIP_REGISTER_APPLICATION" + elseif cmd == 0x03 then cmd_name = "VSOMEIP_DEREGISTER_APPLICATION" + elseif cmd == 0x04 then cmd_name = "VSOMEIP_APPLICATION_LOST" + elseif cmd == 0x05 then cmd_name = "VSOMEIP_ROUTING_INFO" + elseif cmd == 0x06 then cmd_name = "VSOMEIP_REGISTERED_ACK" + elseif cmd == 0x07 then cmd_name = "VSOMEIP_PING" + elseif cmd == 0x08 then cmd_name = "VSOMEIP_PONG" + elseif cmd == 0x10 then cmd_name = "VSOMEIP_OFFER_SERVICE" + elseif cmd == 0x11 then cmd_name = "VSOMEIP_STOP_OFFER_SERVICE" + elseif cmd == 0x12 then cmd_name = "VSOMEIP_SUBSCRIBE" + elseif cmd == 0x13 then cmd_name = "VSOMEIP_UNSUBSCRIBE" + elseif cmd == 0x14 then cmd_name = "VSOMEIP_REQUEST_SERVICE" + elseif cmd == 0x15 then cmd_name = "VSOMEIP_RELEASE_SERVICE" + elseif cmd == 0x16 then cmd_name = "VSOMEIP_SUBSCRIBE_NACK" + elseif cmd == 0x17 then cmd_name = "VSOMEIP_SUBSCRIBE_ACK" + elseif cmd == 0x18 then cmd_name = "VSOMEIP_SEND" + elseif cmd == 0x19 then cmd_name = "VSOMEIP_NOTIFY" + elseif cmd == 0x1A then cmd_name = "VSOMEIP_NOTIFY_ONE" + elseif cmd == 0x1B then cmd_name = "VSOMEIP_REGISTER_EVENT" + elseif cmd == 0x1C then cmd_name = "VSOMEIP_UNREGISTER_EVENT" + elseif cmd == 0x1D then cmd_name = "VSOMEIP_ID_RESPONSE" + elseif cmd == 0x1E then cmd_name = "VSOMEIP_ID_REQUEST" + elseif cmd == 0x1F then cmd_name = "VSOMEIP_OFFERED_SERVICES_REQUEST" + elseif cmd == 0x20 then cmd_name = "VSOMEIP_OFFERED_SERVICES_RESPONSE" + elseif cmd == 0x21 then cmd_name = "VSOMEIP_UNSUBSCRIBE_ACK" + elseif cmd == 0x22 then cmd_name = "VSOMEIP_RESEND_PROVIDED_EVENTS" + elseif cmd == 0x23 then cmd_name = "VSOMEIP_UPDATE_SECURITY_POLICY" + elseif cmd == 0x24 then cmd_name = "VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE" + elseif cmd == 0x25 then cmd_name = "VSOMEIP_REMOVE_SECURITY_POLICY" + elseif cmd == 0x26 then cmd_name = "VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE" + elseif cmd == 0x27 then cmd_name = "VSOMEIP_UPDATE_SECURITY_CREDENTIALS" + elseif cmd == 0x28 then cmd_name = "VSOMEIP_DISTRIBUTE_SECURITY_POLICIES" + elseif cmd == 0x29 then cmd_name = "VSOMEIP_UPDATE_SECURITY_POLICY_INT" + elseif cmd == 0x2A then cmd_name = "VSOMEIP_EXPIRE" + elseif cmd == 0x30 then cmd_name = "VSOMEIP_SUSPEND" + elseif cmd == 0x31 then cmd_name = "VSOMEIP_CONFIG" + end + + return cmd_name +end + +function get_reliability(reliable) + if reliable == 0 then + return "UDP" + else + return "TCP" + end +end + +function get_offer_type(offer) + if offer == 0 then + return "LOCAL" + elseif offer == 1 then + return "REMOTE" + elseif offer == 2 then + return "ALL" + else + return "UNKOWN" + end +end diff --git a/zuul/network-tests/Dockerfile b/zuul/network-tests/Dockerfile new file mode 100644 index 000000000..99c39a9d2 --- /dev/null +++ b/zuul/network-tests/Dockerfile @@ -0,0 +1,57 @@ +FROM ubuntu:jammy +SHELL ["/bin/bash", "-xec"] +RUN export DEBIAN_FRONTEND=noninteractive;\ + apt-get update;\ + apt-get dist-upgrade --purge --yes\ + bind9-dnsutils\ + cmake\ + g++-12\ + gdb\ + googletest\ + iproute2\ + jq\ + lcov\ + libboost-{log,system,thread}-dev\ + lsof\ + net-tools\ + ninja-build\ + openssh-server\ + pkg-config\ + python3-pip\ + tcpdump\ + valgrind\ + ;\ + apt-get autoremove --purge --yes;\ + apt-get clean;\ + pip3 install gcovr + +# Pinned GCC version +ENV CC=gcc-12 +ENV CXX=g++-12 +ENV GCOV=gcov-12 + +# Build dlt-daemon +ADD dlt-daemon /home/source +RUN cmake -B /home/build -D DLT_IPC=UNIX_SOCKET -G Ninja -S /home/source;\ + cmake --build /home/build;\ + cmake --install /home/build --prefix /usr --strip; + +# /etc configurations +RUN echo 'ECUId = M' > /etc/dlt-master.conf;\ + echo 'ECUId = S' > /etc/dlt-slave.conf;\ + echo 'SendEnv *' > /etc/ssh/ssh_config.d/vsomeip.conf;\ + echo 'AcceptEnv *' > /etc/ssh/sshd_config.d/vsomeip.conf + +# SSH configurations +RUN ssh-keygen -q -b 1024 -f ~/.ssh/id_rsa -t rsa -N '';\ + install -DTm0400 ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys;\ + install -DTm0400 ~/.ssh/id_rsa /commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub + +# Hard-coded path used in the tests' scripts +RUN ln -s /home/build /vsomeip_lib + +# Place stuff in a known place +WORKDIR /home/source + +# Declare bind-mounts +VOLUME ["/home/build", "/home/logs", "/home/source"] diff --git a/zuul/network-tests/docker-compose.yaml b/zuul/network-tests/docker-compose.yaml new file mode 100644 index 000000000..43b77d9cb --- /dev/null +++ b/zuul/network-tests/docker-compose.yaml @@ -0,0 +1,52 @@ +version: '3.7' + +networks: + ci-network-tests: + attachable: false + driver: macvlan + internal: true + ipam: + config: + - subnet: 169.254.87.0/24 + gateway: 169.254.87.254 + aux_addresses: + slave_2nd: &slave-2nd 169.254.87.42 + +x-common: + &common + build: + args: + - http_proxy + - https_proxy + - no_proxy + context: ../../.. + dockerfile: vsomeip/zuul/network-tests/Dockerfile + cap_add: + - NET_ADMIN + environment: + ENABLE_COVERAGE: ${ENABLE_COVERAGE-False} # empty to inherit from parent environment (Zuul/Ansible) + GLOBAL_TIMEOUT: 240 minutes + IP_SLAVE_2ND: *slave-2nd + SANITIZER_TYPE: ${SANITIZER_TYPE-} + STRESS_LABELS: ${STRESS_LABELS-[]} + VALGRIND_TYPE: ${VALGRIND_TYPE-} + networks: + - ci-network-tests + security_opt: + - seccomp:unconfined + ulimits: + core: -1 + volumes: + - ${SOURCE_DIR:-../..}:/home/source + - ${BUILD_DIR:-../../build}:/home/build + - ${LOGS_DIR:-../../logs}:/home/logs + +services: + master: + <<: *common + depends_on: + - slave + entrypoint: setarch -R /home/source/zuul/network-tests/entrypoint-master + slave: + <<: *common + entrypoint: setarch -R /home/source/zuul/network-tests/entrypoint-slave diff --git a/zuul/network-tests/entrypoint-master b/zuul/network-tests/entrypoint-master new file mode 100755 index 000000000..df95c9658 --- /dev/null +++ b/zuul/network-tests/entrypoint-master @@ -0,0 +1,123 @@ +#!/bin/bash -eu + +source "${BASH_SOURCE[0]%/*}"/shlib/common.shlib +source "${BASH_SOURCE[0]%/*}"/shlib/results.shlib + +ip_master=$(dig +short master) +ip_slave=$(dig +short slave) + +# Stress label extraction +# 1. We convert the incoming JSON-encoded array of labels into an object by +# using regex capture to extract the key/value from the format +# " : ", with spaces around the colon being optional +# 2. The `stress_regex` is available on key "ctest-include" +# 3. The `stress_times` are extracted to a Bash array +# a) The value of key "ctest-stress" is split on "-" (format "N-M") +# b) Each split token is converted into a JSON number or defaults to 1 if +# conversion fails +# c) Resulting array is bumped with an extra 1 to ensure at least 2 elements +# d) Slice array to extract first 2 elements +stress_labels_json=$(jq 'map(capture("(?[^:\\s]+)\\s*:\\s*(?[^:\\s]+)")) | from_entries' <<< "$STRESS_LABELS") +stress_regex=$(jq -r '.["ctest-include"] // ""' <<< "$stress_labels_json") +mapfile -t stress_times < <(jq -r '.["ctest-stress"] // "1-1" | split("-") | map(try tonumber catch 1) + [1] | .[:2][]' <<< "$stress_labels_json") + +# Enable gateway mode in DLT config +echo 'GatewayMode = 1' >> /etc/dlt-master.conf +cat <<-DLT > /etc/dlt_gateway.conf + [PassiveNode1] + EcuID = S + IPaddress = $ip_slave + Timeout = 0 +DLT + +( + set -x + cmake --preset ci-network-tests \ + -D "ENABLE_${SANITIZER_TYPE}_SANITIZER=Y" \ + -D "TEST_IP_MASTER=$ip_master" \ + -D "TEST_IP_SLAVE=$ip_slave" \ + -D "VALGRIND_LOGS_DIR=/home/logs/valgrind/$VALGRIND_TYPE" \ + -D "VALGRIND_SUPPRESS_FILE=/home/source/zuul/network-tests/valgrind/$VALGRIND_TYPE.supp" \ + -D "VALGRIND_TYPE=$VALGRIND_TYPE" + cmake --build --preset ci-network-tests +) + +tests_result_file=/home/logs/tests_result.json +declare -i valgrind_errors=0 +mkdir -p /home/logs/{cores,coverage,dlt,{,failed-}junit,pcap,"valgrind/$VALGRIND_TYPE"} +gen-result-file "$tests_result_file" "/home/source/.tests-whitelist" + +for ((n = 0; n < stress_times[0]; n++)) +do + for test in $(ctest --preset ci-network-tests --show-only=json-v1 ${stress_regex:+--tests-regex "$stress_regex"} | jq -r '.tests[].name') + do + for ((m = 0; m < stress_times[1]; m++)) + do + if is-timed-out + then + break + fi + + run-both rm -f /tmp/vsomeip* + run-both dlt-daemon -c /etc/dlt-@name@.conf -d + dlt-receive -o /home/logs/dlt/"$test".dlt localhost & + tcpdump -U -i eth0 -w /home/logs/pcap/"$test".pcap & + + if ! ctest --preset ci-network-tests --output-junit /home/logs/junit/"$test".xml --tests-regex "^$test$" --test-output-size-passed 10485760 --test-output-size-failed 10485760 + then + update-result-file "$tests_result_file" "$test" 1 + cp /home/logs/{junit/"$test".xml,failed-junit/} + else + valgrind_errors=$(valgrind-errors "/home/logs/valgrind/$VALGRIND_TYPE" "$test") + if ((valgrind_errors > 0)) + then + update-result-file "$tests_result_file" "$test" "$valgrind_errors" "$VALGRIND_TYPE" + cp /home/logs/{junit/"$test".xml,failed-junit/} + else + update-result-file "$tests_result_file" "$test" + fi + fi + + kill %1 + kill -USR2 %2 || : + kill -INT %2 || : + run-both pkill -TERM dlt-daemon || : + run-both pidwait dlt-daemon || : + run-both kill -KILL -1 || : + done + done +done + +( + cd /home/logs + tar -acvf junit.tgz --transform=s/^junit/network-tests/ junit/*.xml + shopt -s nullglob + if [[ "$(echo failed-junit/*.xml)" ]] + then + tar -acvf failed-junit.tgz --transform=s/^failed-junit/network-tests/ failed-junit/*.xml + fi +) + +gen-core-backtraces /home/logs/cores + +if [ "$ENABLE_COVERAGE" != False ] +then + run-both gcovr --gcov-executable "$GCOV" --json /home/logs/coverage/@name@.json --root /home/source /home/build + run-both lcov --base-directory /home/source --capture --directory /home/build --gcov-tool "$GCOV" --output-file /home/logs/coverage/@name@.info + gcovr --add-tracefile=/home/logs/coverage/{master,slave}.json --json /home/logs/coverage.json + lcov --add-tracefile=/home/logs/coverage/{master,slave}.info --output-file /home/logs/coverage/merged.info + lcov --remove /home/logs/coverage/merged.info '/usr/*' --output-file /home/logs/coverage/filtered.info + genhtml --output-directory /home/logs/coverage/html --prefix /home/source /home/logs/coverage/filtered.info +fi + +run-slave kill 1 || : + +print-results "$tests_result_file" +if is-timed-out +then + echo 'Global timeout was reached!' + echo 'See above which test(s) were at fault.' + exit 255 +else + exit "$(jq '.exit_error' "$tests_result_file")" +fi diff --git a/zuul/network-tests/entrypoint-slave b/zuul/network-tests/entrypoint-slave new file mode 100755 index 000000000..34ba68d5f --- /dev/null +++ b/zuul/network-tests/entrypoint-slave @@ -0,0 +1,6 @@ +#!/bin/bash -eu + +source "${BASH_SOURCE[0]%/*}"/shlib/common.shlib + +mkdir -p /run/sshd +exec /sbin/sshd -D diff --git a/zuul/network-tests/shlib/common.shlib b/zuul/network-tests/shlib/common.shlib new file mode 100644 index 000000000..229cd36c0 --- /dev/null +++ b/zuul/network-tests/shlib/common.shlib @@ -0,0 +1,49 @@ +#!/usr/bin/echo non-executable-shell-library +# shellcheck shell=bash + +# Detect build timeout +function is-timed-out +{ + declare -gi stop_time + if [[ ! -v stop_time ]] + then + stop_time=$(date -d "$GLOBAL_TIMEOUT" +%s) + readonly stop_time + fi + (($(date +%s) >= stop_time)) +} + +# Run a command on the slave container +function run-slave +{ + ssh -no StrictHostKeyChecking=no slave -- "${@@Q}" +} + +# Run a command on both containers +function run-both +{ + local -A commands=( + [master]=exec + [slave]=run-slave + ) + local name + for name in master slave + do + ("${commands[$name]}" "${@//@name@/"$name"}") + done +} + +# Pretty-print a list of items +function print-list +{ + echo "$1: $(($#-1))" + shift + local elem + for elem + do + echo "- $elem" + done +} + +# Add multicast route +ip route add multicast 224.0.0.0/4 dev eth0 diff --git a/zuul/network-tests/shlib/results.shlib b/zuul/network-tests/shlib/results.shlib new file mode 100644 index 000000000..20c577c6a --- /dev/null +++ b/zuul/network-tests/shlib/results.shlib @@ -0,0 +1,83 @@ +#!/usr/bin/echo non-executable-shell-library +# shellcheck shell=bash + +function gen-result-file +{ + local result_file="$1" + local whitelist_file="$2" + whitelist=$(jq --null-input --rawfile list "$whitelist_file" '$list | split("\n") | map(select(test("^(#|$)") | not))') + jq --argjson whitelist "$whitelist" \ + -n '{executed_tests: [], failures: [], exit_error: 0, whitelist: $whitelist}'\ + > "$result_file" +} + +function update-result-file +{ + local result_file="$1" + local test_name="$2" + local errors=${3:-0} + local reason="${4:-}" + + status=$( ((errors > 0)) && echo "failed" || echo "passed" ) + data=$(jq '.executed_tests += [{name: $test_name, status: $status, reason: $reason}]'\ + --arg test_name "$test_name"\ + --arg status "$status"\ + --arg reason "$reason"\ + < "$result_file") + if ((errors > 0)) + then + test_label="$test_name" + if [[ "$reason" ]] + then + test_label+=" ($errors $reason error(s))" + fi + # Check if the test is whitelisted + if jq --arg test_name "$test_name" --exit-status '[.whitelist[] | select(. == $test_name)] | length > 0' "$result_file" + then + test_label+=" (whitelisted)" + else + data=$(jq '.exit_error += 1' <<< "$data") + fi + data=$(jq '.failures += [$test_label]' --arg test_label "$test_label" <<< "$data") + fi + echo "$data" > "$result_file" +} + +function valgrind-errors +{ + local outputs_folder="$1" + local test_name="$2" + + output_file="$outputs_folder/$test_name.out" + if [[ ! -f "$output_file" || -d "$output_file" ]] + then + echo 0 + return + fi + (grep -oP 'ERROR SUMMARY: \K\d+' "$output_file" || echo 0) | sort -n | tail -n1 +} + +function gen-core-backtraces +{ + local outputs_folder="$1" + shopt -s nullglob + for core in /tmp/core.* + do + prog=${core#/tmp/core.} + prog=${prog//!/\/} + gdb -ex 'thread apply all bt' -ex 'set pagination 0' -batch "$prog" "$core" | tee "$outputs_folder/backtrace.${prog##*/}" + cp -v "$core" "$outputs_folder/core.${prog##*/}" + done + shopt -u nullglob +} + +function print-results +{ + local result_file="$1" + executed_tests=$(jq '.executed_tests | length' "$result_file") + declare failed_tests=() + mapfile -t failed_tests < <(jq -r '.failures[]' "$result_file") + echo '[Execution summary]' + echo "Passed tests: $((executed_tests - ${#failed_tests[@]})) of $executed_tests" + print-list 'Failed tests' "${failed_tests[@]}" +} diff --git a/zuul/network-tests/valgrind/helgrind.supp b/zuul/network-tests/valgrind/helgrind.supp new file mode 100644 index 000000000..103dd676e --- /dev/null +++ b/zuul/network-tests/valgrind/helgrind.supp @@ -0,0 +1,24 @@ +{ + libdlt_unlocked + Helgrind:UnlockUnlocked + ... + obj:/usr/lib/libdlt.so.* +} +{ + libdlt_unlocked2 + Helgrind:UnlockForeign + ... + obj:/usr/lib/libdlt.so.* +} +{ + libdlt_pthAPIerror + Helgrind:PthAPIerror + ... + obj:/usr/lib/libdlt.so.* +} +{ + libdlt_misc + Helgrind:Misc + ... + obj:/usr/lib/libdlt.so.* +} diff --git a/zuul/network-tests/valgrind/memcheck.supp b/zuul/network-tests/valgrind/memcheck.supp new file mode 100644 index 000000000..b3989b427 --- /dev/null +++ b/zuul/network-tests/valgrind/memcheck.supp @@ -0,0 +1,26 @@ +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:make_if_command + fun:yyparse + fun:parse_command + fun:read_command + fun:reader_loop + fun:main +} +{ + + Memcheck:Leak + match-leak-kinds: possible + ... + fun:dlt_init +} +{ + + Memcheck:Leak + match-leak-kinds: definite + ... + fun:__libc_dlopen_mode +}