summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürgen Gehring <juergen.gehring@bmw.de>2015-07-29 00:39:43 -0700
committerJürgen Gehring <juergen.gehring@bmw.de>2015-07-29 00:39:43 -0700
commit4792b52c653ab8cdba740a141ae808226b3ed2c1 (patch)
tree47ba024655b6491de0f8e3033ec99fc35080d5f4
parenta1082eaf77850fe213e30e9abc4ea709d0499681 (diff)
downloadvSomeIP-4792b52c653ab8cdba740a141ae808226b3ed2c1.tar.gz
vSomeIP 1.3.01.3.0
-rw-r--r--.gitignore3
-rw-r--r--AUTHORS1
-rw-r--r--CMakeLists.txt178
-rw-r--r--LICENSE373
-rw-r--r--README657
-rw-r--r--config/vsomeip-magic-cookies-client.json2
-rw-r--r--config/vsomeip-tcp-client.json6
-rw-r--r--config/vsomeip-tcp-service.json2
-rw-r--r--config/vsomeip-udp-client.json53
-rw-r--r--documentation/doxygen.in1814
-rw-r--r--examples/hello_world/CMakeLists.txt25
-rw-r--r--examples/hello_world/hello_world_client.cpp134
-rw-r--r--examples/hello_world/hello_world_service.cpp105
-rw-r--r--examples/hello_world/helloworld-local.json43
-rw-r--r--examples/hello_world/readme48
-rw-r--r--examples/notify-sample.cpp363
-rw-r--r--examples/readme.txt5
-rw-r--r--examples/request-sample.cpp9
-rw-r--r--examples/response-sample.cpp247
-rw-r--r--examples/sample-ids.hpp3
-rw-r--r--examples/subscribe-sample.cpp11
-rw-r--r--implementation/configuration/include/configuration_impl.hpp198
-rw-r--r--implementation/configuration/include/event.hpp18
-rw-r--r--implementation/configuration/include/eventgroup.hpp7
-rw-r--r--implementation/configuration/include/internal.hpp60
-rw-r--r--implementation/configuration/include/internal.hpp.in61
-rw-r--r--implementation/configuration/include/service.hpp25
-rw-r--r--implementation/configuration/include/servicegroup.hpp19
-rw-r--r--implementation/configuration/src/configuration.cpp7
-rw-r--r--implementation/configuration/src/configuration_impl.cpp1199
-rw-r--r--implementation/endpoints/include/buffer.hpp11
-rw-r--r--implementation/endpoints/include/client_endpoint_impl.hpp76
-rw-r--r--implementation/endpoints/include/endpoint.hpp42
-rw-r--r--implementation/endpoints/include/endpoint_definition.hpp33
-rw-r--r--implementation/endpoints/include/endpoint_host.hpp12
-rw-r--r--implementation/endpoints/include/endpoint_impl.hpp69
-rw-r--r--implementation/endpoints/include/local_client_endpoint_impl.hpp47
-rw-r--r--implementation/endpoints/include/local_server_endpoint_impl.hpp101
-rw-r--r--implementation/endpoints/include/server_endpoint_impl.hpp69
-rw-r--r--implementation/endpoints/include/tcp_client_endpoint_impl.hpp41
-rw-r--r--implementation/endpoints/include/tcp_server_endpoint_impl.hpp98
-rw-r--r--implementation/endpoints/include/udp_client_endpoint_impl.hpp59
-rw-r--r--implementation/endpoints/include/udp_server_endpoint_impl.hpp78
-rw-r--r--implementation/endpoints/src/client_endpoint_impl.cpp223
-rw-r--r--implementation/endpoints/src/endpoint_definition.cpp36
-rw-r--r--implementation/endpoints/src/endpoint_impl.cpp177
-rw-r--r--implementation/endpoints/src/local_client_endpoint_impl.cpp174
-rw-r--r--implementation/endpoints/src/local_server_endpoint_impl.cpp311
-rw-r--r--implementation/endpoints/src/server_endpoint_impl.cpp205
-rw-r--r--implementation/endpoints/src/tcp_client_endpoint_impl.cpp232
-rw-r--r--implementation/endpoints/src/tcp_server_endpoint_impl.cpp302
-rw-r--r--implementation/endpoints/src/udp_client_endpoint_impl.cpp207
-rw-r--r--implementation/endpoints/src/udp_server_endpoint_impl.cpp300
-rw-r--r--implementation/logging/include/logger_impl.hpp43
-rw-r--r--implementation/logging/src/logger.cpp8
-rw-r--r--implementation/logging/src/logger_impl.cpp141
-rw-r--r--implementation/message/include/deserializer.hpp72
-rw-r--r--implementation/message/include/message_base_impl.hpp62
-rw-r--r--implementation/message/include/message_header_impl.hpp45
-rw-r--r--implementation/message/include/message_impl.hpp26
-rw-r--r--implementation/message/include/payload_impl.hpp34
-rw-r--r--implementation/message/include/serializer.hpp43
-rw-r--r--implementation/message/src/deserializer.cpp9
-rw-r--r--implementation/message/src/message_base_impl.cpp14
-rw-r--r--implementation/message/src/message_header_impl.cpp7
-rw-r--r--implementation/message/src/message_impl.cpp12
-rw-r--r--implementation/message/src/payload_impl.cpp3
-rw-r--r--implementation/message/src/serializer.cpp6
-rw-r--r--implementation/routing/include/event.hpp88
-rw-r--r--implementation/routing/include/eventgroupinfo.hpp53
-rw-r--r--implementation/routing/include/routing_manager.hpp71
-rw-r--r--implementation/routing/include/routing_manager_adapter.hpp10
-rw-r--r--implementation/routing/include/routing_manager_host.hpp29
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp365
-rw-r--r--implementation/routing/include/routing_manager_proxy.hpp185
-rw-r--r--implementation/routing/include/routing_manager_stub.hpp71
-rw-r--r--implementation/routing/include/routing_manager_stub_host.hpp60
-rw-r--r--implementation/routing/include/servicegroup.hpp22
-rw-r--r--implementation/routing/include/serviceinfo.hpp62
-rw-r--r--implementation/routing/include/types.hpp14
-rw-r--r--implementation/routing/src/event.cpp155
-rw-r--r--implementation/routing/src/eventgroupinfo.cpp3
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp2345
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp1043
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp85
-rw-r--r--implementation/routing/src/servicegroup.cpp11
-rw-r--r--implementation/routing/src/serviceinfo.cpp3
-rw-r--r--implementation/runtime/include/application_impl.hpp189
-rw-r--r--implementation/runtime/include/runtime_impl.hpp31
-rw-r--r--implementation/runtime/src/application_impl.cpp554
-rw-r--r--implementation/runtime/src/error.cpp16
-rw-r--r--implementation/runtime/src/runtime.cpp10
-rw-r--r--implementation/runtime/src/runtime_impl.cpp95
-rw-r--r--implementation/service_discovery/include/configuration_option_impl.hpp25
-rw-r--r--implementation/service_discovery/include/constants.hpp7
-rw-r--r--implementation/service_discovery/include/defines.hpp29
-rwxr-xr-ximplementation/service_discovery/include/deserializer.hpp16
-rwxr-xr-ximplementation/service_discovery/include/entry_impl.hpp56
-rw-r--r--implementation/service_discovery/include/enumeration_types.hpp49
-rwxr-xr-ximplementation/service_discovery/include/eventgroupentry_impl.hpp19
-rw-r--r--implementation/service_discovery/include/fsm_base.hpp19
-rw-r--r--implementation/service_discovery/include/fsm_events.hpp48
-rw-r--r--implementation/service_discovery/include/ipv4_option_impl.hpp33
-rw-r--r--implementation/service_discovery/include/ipv6_option_impl.hpp33
-rwxr-xr-ximplementation/service_discovery/include/load_balancing_option_impl.hpp25
-rwxr-xr-ximplementation/service_discovery/include/message_element_impl.hpp11
-rwxr-xr-ximplementation/service_discovery/include/message_impl.hpp61
-rw-r--r--implementation/service_discovery/include/option_impl.hpp21
-rw-r--r--implementation/service_discovery/include/primitive_types.hpp3
-rwxr-xr-ximplementation/service_discovery/include/protection_option_impl.hpp25
-rw-r--r--implementation/service_discovery/include/request.hpp23
-rw-r--r--implementation/service_discovery/include/runtime.hpp13
-rw-r--r--implementation/service_discovery/include/runtime_impl.hpp12
-rw-r--r--implementation/service_discovery/include/service_discovery.hpp37
-rw-r--r--implementation/service_discovery/include/service_discovery_fsm.hpp123
-rw-r--r--implementation/service_discovery/include/service_discovery_host.hpp66
-rw-r--r--implementation/service_discovery/include/service_discovery_impl.hpp191
-rw-r--r--implementation/service_discovery/include/serviceentry_impl.hpp17
-rw-r--r--implementation/service_discovery/include/subscription.hpp36
-rwxr-xr-ximplementation/service_discovery/src/configuration_option_impl.cpp154
-rw-r--r--implementation/service_discovery/src/deserializer.cpp27
-rwxr-xr-ximplementation/service_discovery/src/entry_impl.cpp168
-rwxr-xr-ximplementation/service_discovery/src/eventgroupentry_impl.cpp56
-rw-r--r--implementation/service_discovery/src/fsm_base.cpp25
-rw-r--r--implementation/service_discovery/src/ipv4_option_impl.cpp62
-rwxr-xr-ximplementation/service_discovery/src/ipv6_option_impl.cpp63
-rwxr-xr-ximplementation/service_discovery/src/load_balancing_option_impl.cpp56
-rwxr-xr-ximplementation/service_discovery/src/message_element_impl.cpp9
-rwxr-xr-ximplementation/service_discovery/src/message_impl.cpp466
-rwxr-xr-ximplementation/service_discovery/src/option_impl.cpp36
-rwxr-xr-ximplementation/service_discovery/src/protection_option_impl.cpp55
-rw-r--r--implementation/service_discovery/src/request.cpp19
-rw-r--r--implementation/service_discovery/src/runtime.cpp39
-rw-r--r--implementation/service_discovery/src/runtime_impl.cpp40
-rw-r--r--implementation/service_discovery/src/service_discovery_fsm.cpp230
-rw-r--r--implementation/service_discovery/src/service_discovery_impl.cpp1319
-rwxr-xr-ximplementation/service_discovery/src/serviceentry_impl.cpp44
-rw-r--r--implementation/service_discovery/src/subscription.cpp37
-rw-r--r--implementation/utility/include/byteorder.hpp7
-rw-r--r--implementation/utility/include/utility.hpp102
-rw-r--r--implementation/utility/src/utility.cpp90
-rw-r--r--interface/vsomeip/application.hpp101
-rw-r--r--interface/vsomeip/configuration.hpp116
-rw-r--r--interface/vsomeip/constants.hpp29
-rw-r--r--interface/vsomeip/defines.hpp73
-rw-r--r--interface/vsomeip/deserializable.hpp10
-rw-r--r--interface/vsomeip/enumeration_types.hpp54
-rw-r--r--interface/vsomeip/error.hpp13
-rw-r--r--interface/vsomeip/export.hpp15
-rw-r--r--interface/vsomeip/handler.hpp6
-rw-r--r--interface/vsomeip/logger.hpp38
-rw-r--r--interface/vsomeip/message.hpp13
-rw-r--r--interface/vsomeip/message_base.hpp60
-rw-r--r--interface/vsomeip/payload.hpp29
-rw-r--r--interface/vsomeip/primitive_types.hpp7
-rw-r--r--interface/vsomeip/runtime.hpp48
-rw-r--r--interface/vsomeip/serializable.hpp11
-rw-r--r--interface/vsomeip/vsomeip.hpp3
-rw-r--r--test/CMakeLists.txt536
-rw-r--r--test/configuration-test.cpp3
-rw-r--r--test/header_factory_tests/header_factory_test.cpp120
-rw-r--r--test/header_factory_tests/header_factory_test_client.cpp171
-rw-r--r--test/header_factory_tests/header_factory_test_client.hpp50
-rw-r--r--test/header_factory_tests/header_factory_test_client.json98
-rwxr-xr-xtest/header_factory_tests/header_factory_test_client_start.sh8
-rwxr-xr-xtest/header_factory_tests/header_factory_test_send_receive_starter.sh39
-rw-r--r--test/header_factory_tests/header_factory_test_service.cpp158
-rw-r--r--test/header_factory_tests/header_factory_test_service.hpp45
-rw-r--r--test/header_factory_tests/header_factory_test_service.json118
-rwxr-xr-xtest/header_factory_tests/header_factory_test_service_start.sh9
-rw-r--r--test/magic-cookies-test-client.cpp9
-rwxr-xr-xtest/magic_cookies_test_client_start.sh9
-rwxr-xr-xtest/magic_cookies_test_service_start.sh9
-rwxr-xr-xtest/magic_cookies_test_starter.sh90
-rw-r--r--test/payload_tests/external_local_payload_test_client_external.json54
-rwxr-xr-xtest/payload_tests/external_local_payload_test_client_external_start.sh13
-rwxr-xr-xtest/payload_tests/external_local_payload_test_client_external_starter.sh116
-rw-r--r--test/payload_tests/external_local_payload_test_client_local.json54
-rwxr-xr-xtest/payload_tests/external_local_payload_test_client_local_and_external_starter.sh134
-rwxr-xr-xtest/payload_tests/external_local_payload_test_client_local_start.sh9
-rwxr-xr-xtest/payload_tests/external_local_payload_test_client_local_starter.sh87
-rw-r--r--test/payload_tests/external_local_payload_test_service.json67
-rwxr-xr-xtest/payload_tests/external_local_payload_test_service_client_external_start.sh12
-rwxr-xr-xtest/payload_tests/external_local_payload_test_service_start.sh9
-rw-r--r--test/payload_tests/local_payload_test_client.json45
-rwxr-xr-xtest/payload_tests/local_payload_test_client_start.sh9
-rw-r--r--test/payload_tests/local_payload_test_service.json61
-rwxr-xr-xtest/payload_tests/local_payload_test_service_start.sh9
-rwxr-xr-xtest/payload_tests/local_payload_test_starter.sh69
-rw-r--r--test/payload_tests/payload_test_client.cpp391
-rw-r--r--test/payload_tests/payload_test_client.hpp69
-rw-r--r--test/payload_tests/payload_test_service.cpp177
-rw-r--r--test/payload_tests/payload_test_service.hpp47
-rw-r--r--test/payload_tests/stopwatch.cpp36
-rw-r--r--test/payload_tests/stopwatch.hpp58
-rw-r--r--test/readme.txt170
-rw-r--r--test/routing_tests/external_local_routing_test_client_external.json49
-rwxr-xr-xtest/routing_tests/external_local_routing_test_client_external_start.sh9
-rw-r--r--test/routing_tests/external_local_routing_test_service.cpp171
-rw-r--r--test/routing_tests/external_local_routing_test_service.hpp47
-rw-r--r--test/routing_tests/external_local_routing_test_service.json62
-rwxr-xr-xtest/routing_tests/external_local_routing_test_service_start.sh9
-rwxr-xr-xtest/routing_tests/external_local_routing_test_starter.sh109
-rw-r--r--test/routing_tests/local_routing_test_client.cpp166
-rw-r--r--test/routing_tests/local_routing_test_client.hpp49
-rw-r--r--test/routing_tests/local_routing_test_client.json45
-rwxr-xr-xtest/routing_tests/local_routing_test_client_start.sh9
-rw-r--r--test/routing_tests/local_routing_test_service.cpp154
-rw-r--r--test/routing_tests/local_routing_test_service.hpp45
-rw-r--r--test/routing_tests/local_routing_test_service.json61
-rwxr-xr-xtest/routing_tests/local_routing_test_service_start.sh9
-rwxr-xr-xtest/routing_tests/local_routing_test_starter.sh69
-rw-r--r--test/someip_test_globals.hpp38
-rw-r--r--vsomeip.xml167
-rw-r--r--vsomeipConfig.cmake.in (renamed from vSomeIPConfig.cmake.in)6
-rw-r--r--vsomeipConfigVersion.cmake.in (renamed from vSomeIPConfigVersion.cmake.in)0
216 files changed, 16491 insertions, 7353 deletions
diff --git a/.gitignore b/.gitignore
index 0783206..762ae85 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
/build*/*
+/examples/hello_world/build
/.settings
+/doc
+/implementation/configuration/include/internal.hpp
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..632e479
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Bayerische Motoren Werke Aktiengesellschaft (BMW AG) \ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec04b76..fd8a193 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,9 +1,16 @@
+# Copyright (C) 2015 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 2.8)
project (vsomeip)
-set (VSOMEIP_MAJOR_VERSION 0)
-set (VSOMEIP_MINOR_VERSION 0)
-set (VSOMEIP_PATCH_VERSION 1)
+
+set (VSOMEIP_MAJOR_VERSION 1)
+set (VSOMEIP_MINOR_VERSION 3)
+set (VSOMEIP_PATCH_VERSION 0)
set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION})
+set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentatin/doxygen.in
set (CMAKE_VERBOSE_MAKEFILE off)
###################################################################################################
@@ -18,7 +25,7 @@ set (INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header f
if (WIN32 AND NOT CYGWIN)
set (DEF_INSTALL_CMAKE_DIR CMake)
else ()
- set (DEF_INSTALL_CMAKE_DIR lib/CMake/vSomeIP)
+ set (DEF_INSTALL_CMAKE_DIR lib/cmake/vsomeip)
endif ()
set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files")
@@ -27,7 +34,7 @@ set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directo
foreach (p LIB BIN INCLUDE CMAKE)
set (var INSTALL_${p}_DIR)
if (NOT IS_ABSOLUTE "${${var}}")
- set (${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") # Add all targets to the build-tree export set
+ set (ABSOLUTE_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") # Add all targets to the build-tree export set
endif ()
endforeach ()
@@ -52,9 +59,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
set(OS_CXX_FLAGS "-pthread")
endif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
-# Compiler settings
-set (CMAKE_CXX_FLAGS "-D${OS} ${OS_CXX_FLAGS} -DUSE_VSOMEIP_STATISTICS -DBOOST_LOG_DYN_LINK -g ${OPTIMIZE} -std=c++0x ${NO_DEPRECATED} ${EXPORTSYMBOLS}")
-
include_directories(
"interface"
)
@@ -76,15 +80,28 @@ file(GLOB vsomeip_SRC
"implementation/utility/src/*.cpp"
)
+if (MSVC)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=0x0501 -DWIN32 -DUSE_VSOMEIP_STATISTICS -DCOMMONAPI_INTERNAL_COMPILATION -DBOOST_LOG_DYN_LINK /EHsc")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=0x0501 -DWIN32 -DUSE_VSOMEIP_STATISTICS -DCOMMONAPI_INTERNAL_COMPILATION -DBOOST_LOG_DYN_LINK /EHsc")
+set(USE_RT "")
+set(Boost_LIBRARIES "")
+link_directories(${Boost_LIBRARY_DIR})
+else()
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${OS} ${OS_CXX_FLAGS} -DUSE_VSOMEIP_STATISTICS -DBOOST_LOG_DYN_LINK -g ${OPTIMIZE} -std=c++0x ${NO_DEPRECATED} ${EXPORTSYMBOLS}")
+set(USE_RT "rt")
+endif()
+
add_library(vsomeip SHARED ${vsomeip_SRC})
-target_link_libraries(vsomeip ${Boost_LIBRARIES} rt ${DL_LIBRARY})
+set_target_properties (vsomeip PROPERTIES VERSION ${VSOMEIP_VERSION} SOVERSION ${VSOMEIP_MAJOR_VERSION})
+target_link_libraries(vsomeip ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY})
file(GLOB vsomeip-sd_SRC
"implementation/service_discovery/src/*.cpp"
)
add_library(vsomeip-sd SHARED ${vsomeip-sd_SRC})
-target_link_libraries(vsomeip-sd vsomeip ${Boost_LIBRARIES} rt ${DL_LIBRARY})
+set_target_properties (vsomeip-sd PROPERTIES VERSION ${VSOMEIP_VERSION} SOVERSION ${VSOMEIP_MAJOR_VERSION})
+target_link_libraries(vsomeip-sd vsomeip ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY})
# Configuration files
@@ -110,13 +127,6 @@ target_link_libraries(subscribe-sample vsomeip ${Boost_LIBRARIES} ${DL_LIBRARY})
add_executable(notify-sample examples/notify-sample.cpp ${EXAMPLE_CONFIG_FILES})
target_link_libraries(notify-sample vsomeip ${Boost_LIBRARIES} ${DL_LIBRARY})
-# Test
-add_executable(configuration-test test/configuration-test.cpp)
-target_link_libraries(configuration-test vsomeip ${Boost_LIBRARIES} ${DL_LIBRARY})
-
-add_executable(magic-cookies-test-client test/magic-cookies-test-client.cpp)
-target_link_libraries(magic-cookies-test-client vsomeip ${Boost_LIBRARIES} ${DL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
-
###################################################################################################
file (GLOB_RECURSE vsomeip_INCLUDE "interface/*.hpp")
@@ -135,6 +145,7 @@ install (
install (
TARGETS vsomeip-sd
LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT shlib
+ RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin
)
install (
@@ -147,31 +158,37 @@ install (
)
# Add all targets to the build-tree export set
-export (TARGETS vsomeip FILE "${PROJECT_BINARY_DIR}/vSomeIPTargets.cmake")
+export (TARGETS vsomeip FILE "${PROJECT_BINARY_DIR}/vsomeipTargets.cmake")
# Export the package for use from the build-tree
# (this registers the build-tree with a global CMake-registry)
-export (PACKAGE vSomeIP)
+export (PACKAGE vsomeip)
-# Create the vSomeIPConfig.cmake and vSomeIPConfigVersion files
-file (RELATIVE_PATH REL_INCLUDE_DIR "${INSTALL_CMAKE_DIR}" "${INSTALL_INCLUDE_DIR}")
+# Create the vsomeipConfig.cmake and vsomeipConfigVersion files
+file (RELATIVE_PATH REL_INCLUDE_DIR "${ABSOLUTE_INSTALL_CMAKE_DIR}" "${ABSOLUTE_INSTALL_INCLUDE_DIR}")
# ... for the build tree
set (CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/interface" "${PROJECT_BINARY_DIR}")
-configure_file (vSomeIPConfig.cmake.in "${PROJECT_BINARY_DIR}/vSomeIPConfig.cmake" @ONLY)
+configure_file (vsomeipConfig.cmake.in "${PROJECT_BINARY_DIR}/vsomeipConfig.cmake" @ONLY)
# ... for the install tree
set (CONF_INCLUDE_DIRS "\${VSOMEIP_CMAKE_DIR}/${REL_INCLUDE_DIR}")
-configure_file (vSomeIPConfig.cmake.in "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/vSomeIPConfig.cmake" @ONLY)
+configure_file (vsomeipConfig.cmake.in "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/vsomeipConfig.cmake" @ONLY)
# ... for both
-configure_file (vSomeIPConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/vSomeIPConfigVersion.cmake" @ONLY)
+configure_file (vsomeipConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/vsomeipConfigVersion.cmake" @ONLY)
-# Install the vSomeIPConfig.cmake and vSomeIPConfigVersion.cmake
+# confugure internal.hpp for correct version number
+configure_file (
+ "${PROJECT_SOURCE_DIR}/implementation/configuration/include/internal.hpp.in"
+ "${PROJECT_SOURCE_DIR}/implementation/configuration/include/internal.hpp"
+)
+
+# Install the vsomeipConfig.cmake and vsomeipConfigVersion.cmake
install (
FILES
- "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/vSomeIPConfig.cmake"
- "${PROJECT_BINARY_DIR}/vSomeIPConfigVersion.cmake"
+ "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/vsomeipConfig.cmake"
+ "${PROJECT_BINARY_DIR}/vsomeipConfigVersion.cmake"
DESTINATION "${INSTALL_CMAKE_DIR}"
COMPONENT dev
)
@@ -182,3 +199,110 @@ install (
DESTINATION "${INSTALL_CMAKE_DIR}"
COMPONENT dev
)
+
+##############################################################################
+# build documentation
+##############################################################################
+add_custom_target(doc)
+
+find_package(Doxygen)
+if (NOT DOXYGEN_FOUND)
+ message(WARNING "Doxygen is not installed. Documentation can not be built.")
+else()
+ # set configuration variables for doxygen.in
+ set(PROJECT "vsomeip")
+ set(DOCDIR documentation)
+ set(SRCDIR .)
+ set(GENERATE_HTML YES)
+ set(GENERATE_HTMLHELP NO)
+ set(GENERATE_CHI NO)
+ set(GENERATE_LATEX NO)
+ set(GENERATE_PDF NO)
+ set(GENERATE_RTF NO)
+ set(GENERATE_MAN NO)
+ set(GENERATE_XML NO)
+ set(HAVE_DOT YES)
+
+ if(HAVE_DOT)
+ # Note: the @DOT_PATH@ variable won't be used in doxygen.in as doxygen
+ # somehow manages to strip the last slash from the path and therfore no
+ # graphs are generated. Therefore dot should be available in your $PATH
+ FIND_PROGRAM(DOT_PATH dot)
+ if ("${DOT_PATH}" STREQUAL "DOT_PATH-NOTFOUND")
+ message(WARNING "dot (graphviz) is not installed. Graphs in documentation can't be generated.")
+ else()
+ message("dot found")
+ endif()
+ endif()
+
+ configure_file(documentation/doxygen.in ${PROJECT_BINARY_DIR}/Doxyfile @ONLY)
+ add_custom_target(doxygen-doc
+ COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile
+ SOURCES ${PROJECT_BINARY_DIR}/Doxyfile)
+
+ 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/README.html
+ ${PROJECT_BINARY_DIR}/../README)
+endif()
+
+##############################################################################
+# Test section
+##############################################################################
+
+##############################################################################
+# google test
+
+# check for set environment variable
+if(DEFINED ENV{GTEST_ROOT})
+ message("GTEST_ROOT is set. GTEST_ROOT = $ENV{GTEST_ROOT}")
+else()
+ message("GTEST_ROOT is not defined. For building the tests environment variable
+ GTEST_ROOT have to be defined. Tests can not be built.")
+ # early exit
+ return() # test can not be build -> make commands build_tests and check are not available
+endif()
+
+# build google test as static library (always) -> therefore deactivate BUILD_SHARED_LIBS in case it is active
+set(BUILD_SHARED_LIBS_AUTOMATIC_OFF 0)
+if ("${BUILD_SHARED_LIBS}" STREQUAL "ON")
+ set(BUILD_SHARED_LIBS OFF)
+ set(BUILD_SHARED_LIBS_AUTOMATIC_OFF 1)
+endif()
+add_subdirectory($ENV{GTEST_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/gtest EXCLUDE_FROM_ALL)
+if ("${BUILD_SHARED_LIBS_AUTOMATIC_OFF}" STREQUAL "1")
+ set(BUILD_SHARED_LIBS ON)
+ set(BUILD_SHARED_LIBS_AUTOMATIC_OFF 0)
+endif()
+
+##############################################################################
+# build tests
+
+enable_testing()
+
+add_custom_target(build_tests)
+
+set(CMAKE_CTEST_COMMAND ctest -V)
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
+
+add_dependencies(check build_tests)
+
+##############################################################################
+# add test directory
+
+add_subdirectory( test EXCLUDE_FROM_ALL )
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..14e2f77
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ 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 it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
diff --git a/README b/README
new file mode 100644
index 0000000..f77e558
--- /dev/null
+++ b/README
@@ -0,0 +1,657 @@
+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, 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++11 enabled compiler like gcc >= 4.8 is needed.
+* vsomeip uses cmake as buildsystem.
+* vsomeip uses Boost >= 1.54:
+** Ubuntu 14.04:
+*** `sudo apt-get install libboost-system1.54-dev libboost-thread1.54-dev
+ libboost-log1.54-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.54-dev libboost-thread1.54-dev
+ libboost-log1.54-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 -j8
+----
+
+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 -j8
+make install
+----
+
+Compilation of tests
+^^^^^^^^^^^^^^^^^^^^
+To compile the tests, first unzip gtest to location of your desire. Then run:
+[source, bash]
+----
+mkdir build
+cd build
+export GTEST_ROOT=$PATH_TO_GTEST/gtest-1.7.0/
+cmake ..
+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.
+
+Generating the documentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+To generate the documentation call cmake as described in <<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_FILE`: This environment variable can be used to specify
+ a configuration file to be used by the application. If this variable is not
+ defined the default configuration file `/etc/vsomeip.json` will be used.
+
+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_FILE=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.
++
+//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_).
++
+//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.
++
+** 'num_dispatchers'
++
+The number of threads that shall be used to execute the callbacks to the application.
+If 'num_dispatchers' is set to '0', the callbacks will be executed within the
+application thread. If an application wants/must do time consuming work directly
+within event, availability or message callbacks, 'num_dispatchers' should be set
+to '2' or higher.
++
+//Service groups
+* 'servicegroups (array)'
++
+Services can be grouped together into one service group. A service group
+contains the services of a specific service provider and its connection
+information.
++
+NOTE: It is also possible to define multiple service groups to address services
+from different service providers.
++
+** 'name'
++
+The name of the service group.
++
+** 'unicast'
++
+The IP address of the service provider (valid values: _local_ if the service
+provider is the local host otherwise the _valid IP address_ of the remote
+service provider).
++
+** 'delays'
++
+Contains delays related to the Service Discovery respectively to the service
+instances.
++
+NOTE: The multicast messages of the Service Discovery come with the risk of
+overflowing the net with too many messages. Therefore, the Service Discovery can
+be configured with a suitable message sending behavior.
+
+*** 'initial'
++
+NOTE: A Service instance goes through different phases. One phase is called
+Initial Wait Phase. This phase is entered when the service is fully available
+and waits for the messages of a client's Service Discovery.
+
+**** 'minimum'
++
+Specifies the minimum time during which the messages of a client's Service
+Discovery will be ignored (value in milliseconds).
+
+**** 'maximum'
++
+Specifies the maximum time during which the messages of a client's Service
+Discovery will be ignored (value in milliseconds).
+
+*** `repetition-base`
++
+NOTE: On condition that the initial delay is over, the Repetition Phase is
+entered. In this phase the services will be offered repeatedly via multicast by
+the Service Discovery of the service provider.
++
+The repetition base delay specifies the time after that the first offer will be
+started to send (value in milliseconds).
+
+*** `repetition-max`
++
+Specifies the amount of sent offers within the repetition phase.
+
+*** `cyclic-offer`
++
+NOTE: After the specific amount of repetitions, the Main Phase is entered. In
+the Main Phase the Service Discovery of the service provider starts with a
+cyclic offer of the services.
++
+The cyclic offer specifies the interval in which the services will be offered
+via multicast (value in milliseconds).
+
+*** `cyclic-request`
++
+Specifies the cyclic-request-delay. Currently unused.
+
+** `services` (array)
++
+Contains the services of the service provider.
+
+*** `service`
++
+The id of the service.
+
+*** `instance`
++
+The id of 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).
+
+*** `multicast`
++
+A service can be offered to a specific group of clients via multicast.
+
+**** `address`
++
+The specific multicast address.
+
+**** `port`
++
+The specific port.
+
+*** `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.
+
+**** `is_multicast`
++
+Specifies whether the events should be sent via multicast (valid values:
+_true_,_false_).
+
+**** `multicast`
++
+The multicast address which the events are sent to.
+
+* `routing`
++
+The name of the application that is responsible for the routing.
+
+* `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_).
+
+** `multicast`
++
+The multicast address which the messages of the Service Discovery will be sent
+to.
+
+** `port`
++
+The port of the Service Discovery.
+
+** `protocol`
++
+The protocol that is used for sending the Service Discovery messages (valid
+values: _tcp_,_udp_)
+
+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>>. 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_FILE=../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_FILE=../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.cpp[]
+----
+
+The service example results in the following program execution:
+
+:numbered!:
+
+[float]
+
+Main
+^^^^^
+
+. __main()__ (line 101-107)
++
+First the application is initialized (line 104). After the initialization is
+finished the application is started (line 105).
+
+[float]
+Initialization
+^^^^^^^^^^^^^^
+
+[start=2]
+. __init()__ (line 26-42)
++
+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()__ (line 44-49)
++
+The application will be started. This function only returns when the application
+will be stopped.
+
+[float]
+Callbacks
+^^^^^^^^^
+
+[start=4]
+. __on_event_cbk()__ (line 64-71)
++
+This function is called by the application when an event occurred.
+If the event is related to the successful registration of the
+application at the runtime then the specific service is offered.
+
+. __on_message_cbk()__ (line 73-94)
++
+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 (line 76).
+Afterwards the string 'Hello' will be concatenated with the payload of the
+client's request (line 80-82).
+After that the payload of the response is created (line 85). The payload data
+is set with the previously concatenated string (line 87).
+Finally the response is sent back to the client (line 91) and the
+application is stopped (line 93).
+
+[float]
+Stop
+^^^^
+
+[start=6]
+. __stop()__ (line 51-62)
++
+This function stops offering the service (line 54),
+unregister the message and the event handler (line 56-59) and shuts down the
+application (line 61).
+
+:numbered:
+
+Client
+~~~~~~
+[source, bash]
+----
+include::examples/hello_world/hello_world_client.cpp[]
+----
+
+The client example results in the following program execution:
+
+:numbered!:
+
+[float]
+Main
+^^^^^
+
+. __main()__ (line 130-136)
++
+First the application is initialized (line 133). After the initialization is
+finished the application is started (line 134).
+
+[float]
+Initialization
+^^^^^^^^^^^^^^
+
+[start=2]
+. __init()__ (line 27-48)
++
+The initialization contains the registration of a message handler, an event
+handler and an availability handler.
++
+The event handler declares again a callback (__on_event_cbk__) for events 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()__ (line 50-55)
++
+The application will be started. This function only returns when the application
+will be stopped.
+
+[float]
+Callbacks
+^^^^^^^^^
+
+[start=4]
+. __on_event_cbk()__ (line 57-65)
++
+This function is called by the application when an event occurred.
+If the event is related to the successful registration of the
+application at the runtime then the specific service is requested.
+
+. __on_availability_cbk()__ (line 67-94)
++
+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) (line 76-80). After that the payload of the request is
+created (line 83). The data of the payload is 'World' and will be set afterwards
+(line 84-87). Finally the request is sent to the service.
+
+. __on_message_cbk()__ (line 73-94)
++
+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' (line 98-103) then the payload of the
+response is printed (line 105-109). Finally the application is stopped.
+
+[float]
+Stop
+^^^^
+
+[start=7]
+. __stop()__ (line 114-123)
++
+This function unregister the event and the message handler (line 117-120) and
+shuts down the application (line 122).
+
+:numbered:
diff --git a/config/vsomeip-magic-cookies-client.json b/config/vsomeip-magic-cookies-client.json
index b0982ce..572fbf9 100644
--- a/config/vsomeip-magic-cookies-client.json
+++ b/config/vsomeip-magic-cookies-client.json
@@ -31,7 +31,7 @@
[
{
"name" : "remote",
- "unicast" : "192.168.56.105",
+ "unicast" : "192.168.56.101",
"services" :
[
{
diff --git a/config/vsomeip-tcp-client.json b/config/vsomeip-tcp-client.json
index 17aadbd..f7083f3 100644
--- a/config/vsomeip-tcp-client.json
+++ b/config/vsomeip-tcp-client.json
@@ -1,5 +1,5 @@
{
- "unicast" : "192.168.56.101",
+ "unicast" : "127.0.0.1",
"netmask" : "255.255.255.0",
"logging" :
{
@@ -31,7 +31,7 @@
[
{
"name" : "remote",
- "unicast" : "192.168.56.105",
+ "unicast" : "127.0.0.1",
"services" :
[
{
@@ -75,7 +75,7 @@
"routing" : "client-sample",
"service-discovery" :
{
- "enable" : "true",
+ "enable" : "false",
"multicast" : "224.244.224.245",
"port" : "30490",
"protocol" : "udp"
diff --git a/config/vsomeip-tcp-service.json b/config/vsomeip-tcp-service.json
index 3f344a6..3c38889 100644
--- a/config/vsomeip-tcp-service.json
+++ b/config/vsomeip-tcp-service.json
@@ -18,7 +18,7 @@
[
{
"name" : "default",
- "unicast" : "local",
+ "unicast" : "127.0.0.1",
"delays" :
{
"initial" :
diff --git a/config/vsomeip-udp-client.json b/config/vsomeip-udp-client.json
index fe50570..5b57e45 100644
--- a/config/vsomeip-udp-client.json
+++ b/config/vsomeip-udp-client.json
@@ -27,57 +27,6 @@
"id" : "0x1346"
}
],
- "servicegroups" :
- [
- {
- "name" : "remote",
- "unicast" : "192.168.56.104",
- "services" :
- [
- {
- "service" : "0x1234",
- "instance" : "0x5678",
- "unreliable" : "30509",
- "multicast" :
- {
- "address" : "224.225.226.233",
- "port" : "32344"
- },
- "events" :
- [
- {
- "event" : "0x0777",
- "is_field" : "true"
- },
- {
- "event" : "0x0778",
- "is_field" : "false"
- },
- {
- "event" : "0x0779",
- "is_field" : "true"
- }
- ],
- "eventgroups" :
- [
- {
- "eventgroup" : "0x4455",
- "events" : [ "0x777", "0x778" ]
- },
- {
- "eventgroup" : "0x4465",
- "events" : [ "0x778", "0x779" ],
- "is_multicast" : "true"
- },
- {
- "eventgroup" : "0x4555",
- "events" : [ "0x777", "0x779" ]
- }
- ]
- }
- ]
- }
- ],
"routing" : "client-sample",
"service-discovery" :
{
@@ -86,4 +35,4 @@
"port" : "30490",
"protocol" : "udp"
}
-} \ No newline at end of file
+}
diff --git a/documentation/doxygen.in b/documentation/doxygen.in
new file mode 100644
index 0000000..6654575
--- /dev/null
+++ b/documentation/doxygen.in
@@ -0,0 +1,1814 @@
+# Doxyfile 1.7.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "@PROJECT_NAME@-@PACKAGE_VERSION@"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/@DOCDIR@
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = @PROJECT_SOURCE_DIR@/implementation \
+ @PROJECT_SOURCE_DIR@/interface
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.for \
+ *.vhd \
+ *.vhdl
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = @GENERATE_HTML@
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# style sheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = @GENERATE_HTMLHELP@
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE = ../@PROJECT@.chm
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION = @HHC_PATH@
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = @GENERATE_CHI@
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = YES
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the
+# mathjax.org site, so you can quickly see the result without installing
+# MathJax, but it is strongly recommended to install a local copy of MathJax
+# before deployment.
+
+MATHJAX_RELPATH = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = @GENERATE_LATEX@
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = @PAPER_SIZE@
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = @GENERATE_PDF@
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = YES
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = @GENERATE_RTF@
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = YES
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = @GENERATE_MAN@
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = @GENERATE_XML@
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = @DOCDIR@/@PROJECT@.tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = @HAVE_DOT@
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = svg
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt
new file mode 100644
index 0000000..48d14a4
--- /dev/null
+++ b/examples/hello_world/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2015 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 2.8.7)
+project (vSomeIPHelloWorld)
+
+# This will get us acces to
+# VSOMEIP_INCLUDE_DIRS - include directories for vSomeIP
+# VSOMEIP_LIBRARIES - libraries to link against
+find_package(vsomeip)
+if (NOT vsomeip_FOUND)
+ message("vsomeip was not found. Please specify vsomeip_DIR")
+endif()
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
+include_directories(${VSOMEIP_INCLUDE_DIRS})
+
+add_executable (hello_world_service hello_world_service.cpp)
+target_link_libraries(hello_world_service ${VSOMEIP_LIBRARIES})
+
+add_executable (hello_world_client hello_world_client.cpp)
+target_link_libraries(hello_world_client ${VSOMEIP_LIBRARIES})
diff --git a/examples/hello_world/hello_world_client.cpp b/examples/hello_world/hello_world_client.cpp
new file mode 100644
index 0000000..1bbdf58
--- /dev/null
+++ b/examples/hello_world/hello_world_client.cpp
@@ -0,0 +1,134 @@
+// Copyright (C) 2015 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 <vsomeip/vsomeip.hpp>
+#include <iostream>
+
+static vsomeip::service_t service_id = 0x1111;
+static vsomeip::instance_t service_instance_id = 0x2222;
+static vsomeip::method_t service_method_id = 0x3333;
+
+class hello_world_client {
+public:
+ // Get the vSomeIP runtime and
+ // create a application via the runtime, we could pass the application name
+ // here otherwise the name supplied via the VSOMEIP_APPLICATION_NAME
+ // environment variable is used
+ hello_world_client() :
+ rtm_(vsomeip::runtime::get()),
+ app_(rtm_->create_application())
+ {
+ }
+
+ void init(){
+ // init the application
+ app_->init();
+
+ // register an event handler to get called back after registration at the
+ // runtime was successful
+ app_->register_event_handler(
+ std::bind(&hello_world_client::on_event_cbk, this,
+ std::placeholders::_1));
+
+ // register a callback which is called as soon as the service is available
+ app_->register_availability_handler(service_id, service_instance_id,
+ std::bind(&hello_world_client::on_availability_cbk, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3));
+
+ // register a callback for responses from the service
+ app_->register_message_handler(vsomeip::ANY_SERVICE,
+ service_instance_id, vsomeip::ANY_METHOD,
+ std::bind(&hello_world_client::on_message_cbk, this,
+ std::placeholders::_1));
+ }
+
+ void start()
+ {
+ // start the application and wait for the on_event callback to be called
+ // this method only returns when app_->stop() is called
+ app_->start();
+ }
+
+ void on_event_cbk(vsomeip::event_type_e _event)
+ {
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ // we are registered at the runtime now we can request the service
+ // and wait for the on_availability callback to be called
+ app_->request_service(service_id, service_instance_id);
+ }
+ }
+
+ void on_availability_cbk(vsomeip::service_t _service,
+ vsomeip::instance_t _instance, bool _is_available)
+ {
+ // Check if the available service is the the hello world service
+ if(service_id == _service && service_instance_id == _instance
+ && _is_available)
+ {
+ // The service is available then we send the request
+ // Create a new request
+ std::shared_ptr<vsomeip::message> rq = rtm_->create_request();
+ // Set the hello world service as target of the request
+ rq->set_service(service_id);
+ rq->set_instance(service_instance_id);
+ rq->set_method(service_method_id);
+
+ // Create a payload which will be sent to the service
+ std::shared_ptr<vsomeip::payload> pl = rtm_->create_payload();
+ std::string str("World");
+ std::vector<vsomeip::byte_t> pl_data(std::begin(str), std::end(str));
+
+ pl->set_data(pl_data);
+ rq->set_payload(pl);
+ // Send the request to the service. Response will be delivered to the
+ // registered message handler
+ std::cout << "Sending: " << str << std::endl;
+ app_->send(rq, true);
+ }
+ }
+
+ void on_message_cbk(const std::shared_ptr<vsomeip::message> &_response)
+ {
+ if(service_id == _response->get_service()
+ && service_instance_id == _response->get_instance()
+ && vsomeip::message_type_e::MT_RESPONSE
+ == _response->get_message_type()
+ && vsomeip::return_code_e::E_OK == _response->get_return_code())
+ {
+ // Get the payload and print it
+ std::shared_ptr<vsomeip::payload> pl = _response->get_payload();
+ std::string resp = std::string(
+ reinterpret_cast<const char*>(pl->get_data()), 0,
+ pl->get_length());
+ std::cout << "Received: " << resp << std::endl;
+ stop();
+ }
+ }
+
+ void stop()
+ {
+ // unregister the event handler
+ app_->unregister_event_handler();
+ // unregister the message handler
+ app_->unregister_message_handler(vsomeip::ANY_SERVICE,
+ service_instance_id, vsomeip::ANY_METHOD);
+ // shutdown the application
+ app_->stop();
+ }
+
+private:
+ std::shared_ptr<vsomeip::runtime> rtm_;
+ std::shared_ptr<vsomeip::application> app_;
+};
+
+int main(int argc, char **argv)
+{
+ hello_world_client hw_cl;
+ hw_cl.init();
+ hw_cl.start();
+ return 0;
+}
diff --git a/examples/hello_world/hello_world_service.cpp b/examples/hello_world/hello_world_service.cpp
new file mode 100644
index 0000000..3afc7e7
--- /dev/null
+++ b/examples/hello_world/hello_world_service.cpp
@@ -0,0 +1,105 @@
+// Copyright (C) 2015 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 <vsomeip/vsomeip.hpp>
+
+static vsomeip::service_t service_id = 0x1111;
+static vsomeip::instance_t service_instance_id = 0x2222;
+static vsomeip::method_t service_method_id = 0x3333;
+
+class hello_world_service {
+public:
+ // Get the vSomeIP runtime and
+ // create a application via the runtime, we could pass the application name
+ // here otherwise the name supplied via the VSOMEIP_APPLICATION_NAME
+ // environment variable is used
+ hello_world_service() :
+ rtm_(vsomeip::runtime::get()),
+ app_(rtm_->create_application())
+ {
+ }
+
+ void init()
+ {
+ // init the application
+ app_->init();
+
+ // register a message handler callback for messages sent to our service
+ app_->register_message_handler(service_id, service_instance_id,
+ service_method_id,
+ std::bind(&hello_world_service::on_message_cbk, this,
+ std::placeholders::_1));
+
+ // register an event handler to get called back after registration at the
+ // runtime was successful
+ app_->register_event_handler(
+ std::bind(&hello_world_service::on_event_cbk, this,
+ std::placeholders::_1));
+ }
+
+ void start()
+ {
+ // start the application and wait for the on_event callback to be called
+ // this method only returns when app_->stop() is called
+ app_->start();
+ }
+
+ void stop()
+ {
+ // Stop offering the service
+ app_->stop_offer_service(service_id, service_instance_id);
+ // unregister the event handler
+ app_->unregister_event_handler();
+ // unregister the message handler
+ app_->unregister_message_handler(service_id, service_instance_id,
+ service_method_id);
+ // shutdown the application
+ app_->stop();
+ }
+
+ void on_event_cbk(vsomeip::event_type_e _event)
+ {
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ // we are registered at the runtime and can offer our service
+ app_->offer_service(service_id, service_instance_id);
+ }
+ }
+
+ void on_message_cbk(const std::shared_ptr<vsomeip::message> &_request)
+ {
+ // Create a response based upon the request
+ std::shared_ptr<vsomeip::message> resp = rtm_->create_response(_request);
+
+ // Construct string to send back
+ std::string str("Hello ");
+ str.append(
+ reinterpret_cast<const char*>(_request->get_payload()->get_data()),
+ 0, _request->get_payload()->get_length());
+
+ // Create a payload which will be sent back to the client
+ std::shared_ptr<vsomeip::payload> resp_pl = rtm_->create_payload();
+ std::vector<vsomeip::byte_t> pl_data(str.begin(), str.end());
+ resp_pl->set_data(pl_data);
+ resp->set_payload(resp_pl);
+
+ // Send the response back
+ app_->send(resp, true);
+ // we're finished stop now
+ stop();
+ }
+
+private:
+ std::shared_ptr<vsomeip::runtime> rtm_;
+ std::shared_ptr<vsomeip::application> app_;
+};
+
+int main(int argc, char **argv)
+{
+ hello_world_service hw_srv;
+ hw_srv.init();
+ hw_srv.start();
+ return 0;
+}
diff --git a/examples/hello_world/helloworld-local.json b/examples/hello_world/helloworld-local.json
new file mode 100644
index 0000000..c2b4203
--- /dev/null
+++ b/examples/hello_world/helloworld-local.json
@@ -0,0 +1,43 @@
+{
+ "unicast" : "134.86.56.94",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "hello_world_service",
+ "id" : "0x4444"
+ },
+
+ {
+ "name" : "hello_world_client",
+ "id" : "0x5555"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "default",
+ "unicast" : "local",
+ "services" :
+ [
+ {
+ "service" : "0x1111",
+ "instance" : "0x2222",
+ "unreliable" : "30509"
+ }
+ ]
+ }
+ ],
+
+ "routing" : "hello_world_service",
+ "service-discovery" :
+ {
+ "enable" : "false"
+ }
+} \ No newline at end of file
diff --git a/examples/hello_world/readme b/examples/hello_world/readme
new file mode 100644
index 0000000..e2e1408
--- /dev/null
+++ b/examples/hello_world/readme
@@ -0,0 +1,48 @@
+# Copyright (C) 2014-2015 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/.
+
+Build instructions for Hello World example
+------------------------------------------
+
+mkdir build
+cd build
+cmake ..
+make
+
+Running Hello World Example
+---------------------------
+
+The Hello World Example should be run on the same host.
+The network addresses within the configuration files need to be adapted to match
+the devices addresses.
+
+To start the hello world client and service from their build-directory do:
+
+HOST1:
+VSOMEIP_CONFIGURATION_FILE=../helloworld-local.json \
+VSOMEIP_APPLICATION_NAME=hello_world_service \
+./hello_world_service
+
+HOST1:
+VSOMEIP_CONFIGURATION_FILE=../helloworld-local.json \
+VSOMEIP_APPLICATION_NAME=hello_world_client \
+./hello_world_client
+
+Expected output 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!
+
+Expected output 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
diff --git a/examples/notify-sample.cpp b/examples/notify-sample.cpp
index 484a7e8..78aadc7 100644
--- a/examples/notify-sample.cpp
+++ b/examples/notify-sample.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,189 +16,189 @@
class service_sample {
public:
- service_sample(bool _use_tcp, uint32_t _cycle) :
- app_(vsomeip::runtime::get()->create_application()), is_registered_(
- false), use_tcp_(_use_tcp), cycle_(_cycle), offer_thread_(
- std::bind(&service_sample::run, this)), notify_thread_(
- std::bind(&service_sample::notify, this)), is_offered_(
- false) {
- }
-
- void init() {
- std::lock_guard<std::mutex> its_lock(mutex_);
-
- app_->init();
- app_->register_event_handler(
- std::bind(&service_sample::on_event, this,
- std::placeholders::_1));
-
- app_->register_message_handler(
- SAMPLE_SERVICE_ID,
- SAMPLE_INSTANCE_ID,
- SAMPLE_GET_METHOD_ID,
- std::bind(&service_sample::on_get, this,
- std::placeholders::_1));
-
- app_->register_message_handler(
- SAMPLE_SERVICE_ID,
- SAMPLE_INSTANCE_ID,
- SAMPLE_SET_METHOD_ID,
- std::bind(&service_sample::on_set, this,
- std::placeholders::_1));
-
- payload_ = vsomeip::runtime::get()->create_payload();
-
- blocked_ = true;
- condition_.notify_one();
- }
-
- void start() {
- app_->start();
- }
-
- void offer() {
- std::lock_guard<std::mutex> its_lock(notify_mutex_);
- app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
- is_offered_ = true;
- notify_condition_.notify_one();
- }
-
- void stop_offer() {
- app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
- is_offered_ = false;
- }
-
- void on_event(vsomeip::event_type_e _event) {
- VSOMEIP_INFO << "Application " << app_->get_name() << " is "
- << (_event == vsomeip::event_type_e::REGISTERED ?
- "registered." : "deregistered.");
-
- if (_event == vsomeip::event_type_e::REGISTERED) {
- if (!is_registered_) {
- is_registered_ = true;
- }
- } else {
- is_registered_ = false;
- }
- }
-
- void on_get(std::shared_ptr<vsomeip::message> &_message) {
- std::shared_ptr<vsomeip::message> its_response
- = vsomeip::runtime::get()->create_response(_message);
- its_response->set_payload(payload_);
- app_->send(its_response, true, use_tcp_);
- }
-
- void on_set(std::shared_ptr<vsomeip::message> &_message) {
- payload_ = _message->get_payload();
-
- std::shared_ptr<vsomeip::message> its_response
- = vsomeip::runtime::get()->create_response(_message);
- its_response->set_payload(payload_);
- app_->send(its_response, true, use_tcp_);
- app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
- SAMPLE_EVENT_ID, payload_);
- }
-
- void run() {
- std::unique_lock<std::mutex> its_lock(mutex_);
- while (!blocked_)
- condition_.wait(its_lock);
-
- bool is_offer(true);
- while (true) {
- if (is_offer)
- offer();
- else
- stop_offer();
-
- std::this_thread::sleep_for(std::chrono::milliseconds(10000));
- is_offer = !is_offer;
- }
- }
-
- void notify() {
- std::shared_ptr<vsomeip::message> its_message
- = vsomeip::runtime::get()->create_request();
-
- its_message->set_service(SAMPLE_SERVICE_ID);
- its_message->set_instance(SAMPLE_INSTANCE_ID);
- its_message->set_method(SAMPLE_SET_METHOD_ID);
-
- vsomeip::byte_t its_data[10];
- uint32_t its_size = 1;
-
- while (true) {
- std::unique_lock<std::mutex> its_lock(notify_mutex_);
- while (!is_offered_)
- notify_condition_.wait(its_lock);
- while (is_offered_) {
- if (its_size == sizeof(its_data))
- its_size = 1;
-
- for (uint32_t i = 0; i < its_size; ++i)
- its_data[i] = static_cast<uint8_t>(i);
-
- payload_->set_data(its_data, its_size);
-
- VSOMEIP_INFO << "Setting event (Length=" << std::dec << its_size << ").";
- app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload_);
-
- its_size++;
-
- std::this_thread::sleep_for(std::chrono::milliseconds(cycle_));
- }
- }
- }
+ service_sample(bool _use_tcp, uint32_t _cycle) :
+ app_(vsomeip::runtime::get()->create_application()), is_registered_(
+ false), use_tcp_(_use_tcp), cycle_(_cycle), offer_thread_(
+ std::bind(&service_sample::run, this)), notify_thread_(
+ std::bind(&service_sample::notify, this)), is_offered_(
+ false) {
+ }
+
+ void init() {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ app_->init();
+ app_->register_event_handler(
+ std::bind(&service_sample::on_event, this,
+ std::placeholders::_1));
+
+ app_->register_message_handler(
+ SAMPLE_SERVICE_ID,
+ SAMPLE_INSTANCE_ID,
+ SAMPLE_GET_METHOD_ID,
+ std::bind(&service_sample::on_get, this,
+ std::placeholders::_1));
+
+ app_->register_message_handler(
+ SAMPLE_SERVICE_ID,
+ SAMPLE_INSTANCE_ID,
+ SAMPLE_SET_METHOD_ID,
+ std::bind(&service_sample::on_set, this,
+ std::placeholders::_1));
+
+ payload_ = vsomeip::runtime::get()->create_payload();
+
+ blocked_ = true;
+ condition_.notify_one();
+ }
+
+ void start() {
+ app_->start();
+ }
+
+ void offer() {
+ std::lock_guard<std::mutex> its_lock(notify_mutex_);
+ app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
+ is_offered_ = true;
+ notify_condition_.notify_one();
+ }
+
+ void stop_offer() {
+ app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
+ is_offered_ = false;
+ }
+
+ void on_event(vsomeip::event_type_e _event) {
+ VSOMEIP_INFO << "Application " << app_->get_name() << " is "
+ << (_event == vsomeip::event_type_e::ET_REGISTERED ?
+ "registered." : "deregistered.");
+
+ if (_event == vsomeip::event_type_e::ET_REGISTERED) {
+ if (!is_registered_) {
+ is_registered_ = true;
+ }
+ } else {
+ is_registered_ = false;
+ }
+ }
+
+ void on_get(const std::shared_ptr<vsomeip::message> &_message) {
+ std::shared_ptr<vsomeip::message> its_response
+ = vsomeip::runtime::get()->create_response(_message);
+ its_response->set_payload(payload_);
+ app_->send(its_response, true);
+ }
+
+ void on_set(const std::shared_ptr<vsomeip::message> &_message) {
+ payload_ = _message->get_payload();
+
+ std::shared_ptr<vsomeip::message> its_response
+ = vsomeip::runtime::get()->create_response(_message);
+ its_response->set_payload(payload_);
+ app_->send(its_response, true);
+ app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
+ SAMPLE_EVENT_ID, payload_);
+ }
+
+ void run() {
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ condition_.wait(its_lock);
+
+ bool is_offer(true);
+ while (true) {
+ if (is_offer)
+ offer();
+ else
+ stop_offer();
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(10000));
+ is_offer = !is_offer;
+ }
+ }
+
+ void notify() {
+ std::shared_ptr<vsomeip::message> its_message
+ = vsomeip::runtime::get()->create_request(use_tcp_);
+
+ its_message->set_service(SAMPLE_SERVICE_ID);
+ its_message->set_instance(SAMPLE_INSTANCE_ID);
+ its_message->set_method(SAMPLE_SET_METHOD_ID);
+
+ vsomeip::byte_t its_data[10];
+ uint32_t its_size = 1;
+
+ while (true) {
+ std::unique_lock<std::mutex> its_lock(notify_mutex_);
+ while (!is_offered_)
+ notify_condition_.wait(its_lock);
+ while (is_offered_) {
+ if (its_size == sizeof(its_data))
+ its_size = 1;
+
+ for (uint32_t i = 0; i < its_size; ++i)
+ its_data[i] = static_cast<uint8_t>(i);
+
+ payload_->set_data(its_data, its_size);
+
+ VSOMEIP_INFO << "Setting event (Length=" << std::dec << its_size << ").";
+ app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload_);
+
+ its_size++;
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(cycle_));
+ }
+ }
+ }
private:
- std::shared_ptr<vsomeip::application> app_;
- bool is_registered_;
- bool use_tcp_;
- uint32_t cycle_;
-
- std::thread offer_thread_;
- std::mutex mutex_;
- std::condition_variable condition_;
- bool blocked_;
-
- std::thread notify_thread_;
- std::mutex notify_mutex_;
- std::condition_variable notify_condition_;
- bool is_offered_;
-
- std::shared_ptr<vsomeip::payload> payload_;
+ std::shared_ptr<vsomeip::application> app_;
+ bool is_registered_;
+ bool use_tcp_;
+ uint32_t cycle_;
+
+ std::thread offer_thread_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool blocked_;
+
+ std::thread notify_thread_;
+ std::mutex notify_mutex_;
+ std::condition_variable notify_condition_;
+ bool is_offered_;
+
+ std::shared_ptr<vsomeip::payload> payload_;
};
int main(int argc, char **argv) {
- bool use_tcp = false;
- uint32_t cycle = 1000; // default 1s
-
- std::string tcp_enable("--tcp");
- std::string udp_enable("--udp");
- std::string cycle_arg("--cycle");
-
- for (int i = 1; i < argc; i++) {
- if (tcp_enable == argv[i]) {
- use_tcp = true;
- break;
- }
- if (udp_enable == argv[i]) {
- use_tcp = false;
- break;
- }
-
- if (cycle_arg == argv[i] && i + 1 < argc) {
- i++;
- std::stringstream converter;
- converter << argv[i];
- converter >> cycle;
- }
- }
-
- service_sample its_sample(use_tcp, cycle);
- its_sample.init();
- its_sample.start();
-
- return 0;
+ bool use_tcp = false;
+ uint32_t cycle = 1000; // default 1s
+
+ std::string tcp_enable("--tcp");
+ std::string udp_enable("--udp");
+ std::string cycle_arg("--cycle");
+
+ for (int i = 1; i < argc; i++) {
+ if (tcp_enable == argv[i]) {
+ use_tcp = true;
+ break;
+ }
+ if (udp_enable == argv[i]) {
+ use_tcp = false;
+ break;
+ }
+
+ if (cycle_arg == argv[i] && i + 1 < argc) {
+ i++;
+ std::stringstream converter;
+ converter << argv[i];
+ converter >> cycle;
+ }
+ }
+
+ service_sample its_sample(use_tcp, cycle);
+ its_sample.init();
+ its_sample.start();
+
+ return 0;
}
diff --git a/examples/readme.txt b/examples/readme.txt
index ac66d31..9b2c378 100644
--- a/examples/readme.txt
+++ b/examples/readme.txt
@@ -1,3 +1,8 @@
+# Copyright (C) 2014-2015 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/.
+
To use the example applications you need two devices on the same network. The network addresses within
the configuration files need to be adapted to match the devices addresses.
diff --git a/examples/request-sample.cpp b/examples/request-sample.cpp
index fe46f92..43969d5 100644
--- a/examples/request-sample.cpp
+++ b/examples/request-sample.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -77,7 +76,7 @@ public:
}
void on_event(vsomeip::event_type_e _event) {
- if (_event == vsomeip::event_type_e::REGISTERED) {
+ if (_event == vsomeip::event_type_e::ET_REGISTERED) {
app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
}
}
@@ -98,7 +97,7 @@ public:
}
}
- void on_message(std::shared_ptr< vsomeip::message > &_response) {
+ void on_message(const std::shared_ptr< vsomeip::message > &_response) {
VSOMEIP_INFO << "Received a response from Service ["
<< std::setw(4) << std::setfill('0') << std::hex << _response->get_service()
<< "."
@@ -127,7 +126,7 @@ public:
std::unique_lock<std::mutex> its_lock(mutex_);
while (!blocked_) condition_.wait(its_lock);
std::this_thread::sleep_for(std::chrono::milliseconds(cycle_));
- app_->send(request_, true, use_tcp_);
+ app_->send(request_, true);
VSOMEIP_INFO << "Client/Session ["
<< std::setw(4) << std::setfill('0') << std::hex << request_->get_client()
<< "/"
diff --git a/examples/response-sample.cpp b/examples/response-sample.cpp
index f782969..9d43a29 100644
--- a/examples/response-sample.cpp
+++ b/examples/response-sample.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,136 +16,126 @@
class service_sample {
public:
- service_sample(bool _use_tcp, bool _use_static_routing) :
- app_(vsomeip::runtime::get()->create_application()), is_registered_(
- false), use_tcp_(_use_tcp), use_static_routing_(
- _use_static_routing), offer_thread_(
- std::bind(&service_sample::run, this)) {
- }
-
- void init() {
- std::lock_guard<std::mutex> its_lock(mutex_);
-
- app_->init();
- app_->register_message_handler(
- SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID,
- std::bind(&service_sample::on_message, this,
- std::placeholders::_1));
-
- app_->register_event_handler(
- std::bind(&service_sample::on_event, this,
- std::placeholders::_1));
-
- VSOMEIP_INFO<< "Static routing " << (use_static_routing_ ? "ON" : "OFF");
- }
-
- void start() {
- app_->start();
- }
-
- void offer() {
- app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
- app_->offer_service(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID);
- }
-
- void stop_offer() {
- app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
- app_->stop_offer_service(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID);
- }
-
- void on_event(vsomeip::event_type_e _event) {
- VSOMEIP_INFO << "Application " << app_->get_name() << " is "
- << (_event == vsomeip::event_type_e::REGISTERED ?
- "registered." : "deregistered.");
-
- if (_event == vsomeip::event_type_e::REGISTERED) {
- if (!is_registered_) {
- is_registered_ = true;
- blocked_ = true;
- condition_.notify_one();
- }
- } else {
- is_registered_ = false;
- }
- }
-
- void on_message(std::shared_ptr<vsomeip::message> &_request) {
- 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::shared_ptr<vsomeip::message> its_response = vsomeip::runtime::get()
- ->create_response(_request);
-
- std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get()
- ->create_payload();
- std::vector<vsomeip::byte_t> its_payload_data;
- for (std::size_t i = 0; i < 120; ++i)
- its_payload_data.push_back(i % 256);
- its_payload->set_data(its_payload_data);
- its_response->set_payload(its_payload);
-
- app_->send(its_response, true, use_tcp_);
- }
-
- void run() {
- std::unique_lock<std::mutex> its_lock(mutex_);
- while (!blocked_)
- condition_.wait(its_lock);
-
- bool is_offer(true);
-
- if (use_static_routing_) {
- offer();
- while (true);
- } else {
- while (true) {
- if (is_offer)
- offer();
- else
- stop_offer();
- std::this_thread::sleep_for(std::chrono::milliseconds(10000));
- is_offer = !is_offer;
- }
- }
- }
+ service_sample(bool _use_static_routing) :
+ app_(vsomeip::runtime::get()->create_application()),
+ is_registered_(false),
+ use_static_routing_(_use_static_routing),
+ offer_thread_(std::bind(&service_sample::run, this)) {
+ }
+
+ void init() {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ app_->init();
+ app_->register_message_handler(
+ SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID,
+ std::bind(&service_sample::on_message, this,
+ std::placeholders::_1));
+
+ app_->register_event_handler(
+ std::bind(&service_sample::on_event, this,
+ std::placeholders::_1));
+
+ VSOMEIP_INFO<< "Static routing " << (use_static_routing_ ? "ON" : "OFF");
+ }
+
+ void start() {
+ app_->start();
+ }
+
+ void offer() {
+ app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
+ app_->offer_service(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID);
+ }
+
+ void stop_offer() {
+ app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
+ app_->stop_offer_service(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID);
+ }
+
+ void on_event(vsomeip::event_type_e _event) {
+ VSOMEIP_INFO << "Application " << app_->get_name() << " is "
+ << (_event == vsomeip::event_type_e::ET_REGISTERED ?
+ "registered." : "deregistered.");
+
+ if (_event == vsomeip::event_type_e::ET_REGISTERED) {
+ if (!is_registered_) {
+ is_registered_ = true;
+ blocked_ = true;
+ condition_.notify_one();
+ }
+ } else {
+ is_registered_ = false;
+ }
+ }
+
+ void on_message(const std::shared_ptr<vsomeip::message> &_request) {
+ 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::shared_ptr<vsomeip::message> its_response = vsomeip::runtime::get()
+ ->create_response(_request);
+
+ std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get()
+ ->create_payload();
+ std::vector<vsomeip::byte_t> its_payload_data;
+ for (std::size_t i = 0; i < 120; ++i)
+ its_payload_data.push_back(i % 256);
+ its_payload->set_data(its_payload_data);
+ its_response->set_payload(its_payload);
+
+ app_->send(its_response, true);
+ }
+
+ void run() {
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ condition_.wait(its_lock);
+
+ bool is_offer(true);
+
+ if (use_static_routing_) {
+ offer();
+ while (true);
+ } else {
+ while (true) {
+ if (is_offer)
+ offer();
+ else
+ stop_offer();
+ std::this_thread::sleep_for(std::chrono::milliseconds(10000));
+ is_offer = !is_offer;
+ }
+ }
+ }
private:
- std::shared_ptr<vsomeip::application> app_;
- bool is_registered_;
- bool use_tcp_;
- bool use_static_routing_;
-
- std::thread offer_thread_;
- std::mutex mutex_;
- std::condition_variable condition_;
- bool blocked_;
+ std::shared_ptr<vsomeip::application> app_;
+ bool is_registered_;
+ bool use_static_routing_;
+
+ std::thread offer_thread_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool blocked_;
};
int main(int argc, char **argv) {
- bool use_tcp(false);
- bool use_static_routing(false);
-
- std::string tcp_enable("--tcp");
- std::string udp_enable("--udp");
- std::string static_routing_enable("--static-routing");
-
- for (int i = 1; i < argc; i++) {
- if (tcp_enable == argv[i]) {
- use_tcp = true;
- }
- if (udp_enable == argv[i]) {
- use_tcp = false;
- }
- if (static_routing_enable == argv[i]) {
- use_static_routing = true;
- }
- }
-
- service_sample its_sample(use_tcp, use_static_routing);
- its_sample.init();
- its_sample.start();
-
- return 0;
+ bool use_static_routing(false);
+
+ std::string static_routing_enable("--static-routing");
+
+ for (int i = 1; i < argc; i++) {
+ if (static_routing_enable == argv[i]) {
+ use_static_routing = true;
+ }
+ }
+
+ service_sample its_sample(use_static_routing);
+ its_sample.init();
+ its_sample.start();
+
+ return 0;
}
diff --git a/examples/sample-ids.hpp b/examples/sample-ids.hpp
index f949ebd..28132a1 100644
--- a/examples/sample-ids.hpp
+++ b/examples/sample-ids.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/examples/subscribe-sample.cpp b/examples/subscribe-sample.cpp
index acf9790..3faa4d1 100644
--- a/examples/subscribe-sample.cpp
+++ b/examples/subscribe-sample.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -55,7 +54,7 @@ public:
}
}
- void on_message(std::shared_ptr<vsomeip::message> &_response) {
+ void on_message(const std::shared_ptr<vsomeip::message> &_response) {
std::stringstream its_message;
its_message << "Received a notification for Event [" << std::setw(4)
<< std::setfill('0') << std::hex << _response->get_service()
@@ -80,7 +79,8 @@ public:
its_get->set_service(SAMPLE_SERVICE_ID);
its_get->set_instance(SAMPLE_INSTANCE_ID);
its_get->set_method(SAMPLE_GET_METHOD_ID);
- app_->send(its_get, true, use_tcp_);
+ its_get->set_reliable(use_tcp_);
+ app_->send(its_get, true);
}
if ((its_payload->get_length() % 8) == 0) {
@@ -89,6 +89,7 @@ public:
its_set->set_service(SAMPLE_SERVICE_ID);
its_set->set_instance(SAMPLE_INSTANCE_ID);
its_set->set_method(SAMPLE_SET_METHOD_ID);
+ its_set->set_reliable(use_tcp_);
const vsomeip::byte_t its_data[]
= { 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
@@ -97,7 +98,7 @@ public:
= 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, true, use_tcp_);
+ app_->send(its_set, true);
}
}
}
diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp
index 15c1680..8a57633 100644
--- a/implementation/configuration/include/configuration_impl.hpp
+++ b/implementation/configuration/include/configuration_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -18,107 +17,126 @@
namespace vsomeip {
namespace cfg {
-class service;
-class servicegroup;
+struct service;
+struct servicegroup;
-class configuration_impl : public configuration {
+class configuration_impl: public configuration {
public:
- static configuration * get(const std::string &_path);
-
- configuration_impl();
- virtual ~configuration_impl();
-
- bool load(const std::string &_path);
-
- const boost::asio::ip::address & get_unicast() const;
- bool is_v4() const;
- bool is_v6() const;
-
- bool has_console_log() const;
- bool has_file_log() const;
- bool has_dlt_log() const;
- const std::string & get_logfile() const;
- boost::log::trivial::severity_level get_loglevel() const;
-
- std::string get_group(service_t _service, instance_t _instance) const;
- std::set< std::string > get_servicegroups() const;
-
- bool is_local_servicegroup(const std::string &_name) const;
- int32_t get_min_initial_delay(const std::string &_name) const;
- int32_t get_max_initial_delay(const std::string &_name) const;
- int32_t get_repetition_base_delay(const std::string &_name) const;
- uint8_t get_repetition_max(const std::string &_name) const;
- int32_t get_cyclic_offer_delay(const std::string &_name) const;
- int32_t get_cyclic_request_delay(const std::string &_name) const;
-
- std::string get_unicast(service_t _service, instance_t _instance) const;
- std::string get_multicast_address(service_t _service, instance_t _instance) const;
- uint16_t get_multicast_port(service_t _service, instance_t _instance) const;
- uint16_t get_multicast_group(service_t _service, instance_t _instance) const;
-
- uint16_t get_reliable_port(service_t _service, instance_t _instance) const;
- bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const;
- uint16_t get_unreliable_port(service_t _service, instance_t _instance) const;
-
- const std::string & get_routing_host() const;
-
- bool is_service_discovery_enabled() const;
- const std::string & get_service_discovery_multicast() const;
- uint16_t get_service_discovery_port() const;
- const std::string & get_service_discovery_protocol() const;
-
- client_t get_id(const std::string &_name) const;
-
- std::set< std::pair< service_t, instance_t > > get_remote_services() const;
-
- std::map<service_t, std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > get_eventgroups() const;
- std::map<service_t, std::map<instance_t, std::set<event_t> > > get_events() const;
- void set_event(std::shared_ptr<event> &_event) const;
+ static configuration * get(const std::string &_path);
+
+ configuration_impl();
+ virtual ~configuration_impl();
+
+ bool load(const std::string &_path);
+
+ const boost::asio::ip::address & get_unicast() const;
+ bool is_v4() const;
+ bool is_v6() const;
+
+ bool has_console_log() const;
+ bool has_file_log() const;
+ bool has_dlt_log() const;
+ const std::string & get_logfile() const;
+ boost::log::trivial::severity_level get_loglevel() const;
+
+ std::string get_group(service_t _service, instance_t _instance) const;
+ std::set<std::string> get_servicegroups() const;
+
+ bool is_local_servicegroup(const std::string &_name) const;
+ int32_t get_min_initial_delay(const std::string &_name) const;
+ int32_t get_max_initial_delay(const std::string &_name) const;
+ int32_t get_repetition_base_delay(const std::string &_name) const;
+ uint8_t get_repetition_max(const std::string &_name) const;
+ int32_t get_cyclic_offer_delay(const std::string &_name) const;
+ int32_t get_cyclic_request_delay(const std::string &_name) const;
+
+ std::string get_unicast(service_t _service, instance_t _instance) const;
+ std::string get_multicast_address(service_t _service,
+ instance_t _instance) const;
+ uint16_t get_multicast_port(service_t _service,
+ instance_t _instance) const;
+ uint16_t get_multicast_group(service_t _service,
+ instance_t _instance) const;
+
+ uint16_t get_reliable_port(service_t _service, instance_t _instance) const;
+ bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const;
+ uint16_t get_unreliable_port(service_t _service,
+ instance_t _instance) const;
+
+ const std::string & get_routing_host() const;
+
+ bool is_service_discovery_enabled() const;
+ const std::string & get_service_discovery_multicast() const;
+ uint16_t get_service_discovery_port() const;
+ const std::string & get_service_discovery_protocol() const;
+
+ client_t get_id(const std::string &_name) const;
+ std::size_t get_num_dispatchers(const std::string &_name) const;
+
+ std::set<std::pair<service_t, instance_t> > get_remote_services() const;
+
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<eventgroup_t,
+ std::set<event_t> > > > get_eventgroups() const;
+ std::map<service_t,
+ std::map<instance_t,
+ std::set<event_t> > > get_events() const;
+ void set_event(std::shared_ptr<event> &_event) const;
private:
- bool get_someip_configuration(boost::property_tree::ptree &_tree);
- bool get_logging_configuration(boost::property_tree::ptree &_tree);
- bool get_services_configuration(boost::property_tree::ptree &_tree);
- bool get_routing_configuration(boost::property_tree::ptree &_tree);
- bool get_service_discovery_configuration(boost::property_tree::ptree &_tree);
- bool get_applications_configuration(boost::property_tree::ptree &_tree);
-
- bool get_servicegroup_configuration(const boost::property_tree::ptree &_tree);
- bool get_delays_configuration(std::shared_ptr< servicegroup > &_group, const boost::property_tree::ptree &_tree);
- bool get_service_configuration(std::shared_ptr< servicegroup > &_group, const boost::property_tree::ptree &_tree);
- bool get_event_configuration(std::shared_ptr<service> &_service, const boost::property_tree::ptree &_tree);
- bool get_eventgroup_configuration(std::shared_ptr<service> &_service, const boost::property_tree::ptree &_tree);
- bool get_application_configuration(const boost::property_tree::ptree &_tree);
-
- servicegroup * find_servicegroup(const std::string &_name) const;
- service * find_service(service_t _service, instance_t _instance) const;
+ bool get_someip_configuration(boost::property_tree::ptree &_tree);
+ bool get_logging_configuration(boost::property_tree::ptree &_tree);
+ bool get_services_configuration(boost::property_tree::ptree &_tree);
+ bool get_routing_configuration(boost::property_tree::ptree &_tree);
+ bool get_service_discovery_configuration(
+ boost::property_tree::ptree &_tree);
+ bool get_applications_configuration(boost::property_tree::ptree &_tree);
+
+ bool get_servicegroup_configuration(
+ const boost::property_tree::ptree &_tree);
+ bool get_delays_configuration(std::shared_ptr<servicegroup> &_group,
+ const boost::property_tree::ptree &_tree);
+ bool get_service_configuration(std::shared_ptr<servicegroup> &_group,
+ const boost::property_tree::ptree &_tree);
+ bool get_event_configuration(std::shared_ptr<service> &_service,
+ const boost::property_tree::ptree &_tree);
+ bool get_eventgroup_configuration(std::shared_ptr<service> &_service,
+ const boost::property_tree::ptree &_tree);
+ bool get_application_configuration(
+ const boost::property_tree::ptree &_tree);
+
+ servicegroup * find_servicegroup(const std::string &_name) const;
+ service * find_service(service_t _service, instance_t _instance) const;
private:
- static std::map< std::string, configuration * > the_configurations;
- static std::mutex mutex_;
+ static std::map<std::string, configuration *> the_configurations;
+ static std::mutex mutex_;
- // Configuration data
- boost::asio::ip::address unicast_;
+ // Configuration data
+ boost::asio::ip::address unicast_;
- bool has_console_log_;
- bool has_file_log_;
- bool has_dlt_log_;
- std::string logfile_;
- boost::log::trivial::severity_level loglevel_;
+ bool has_console_log_;
+ bool has_file_log_;
+ bool has_dlt_log_;
+ std::string logfile_;
+ boost::log::trivial::severity_level loglevel_;
- std::map< std::string, std::shared_ptr< servicegroup > > servicegroups_;
- std::map< service_t, std::map< instance_t, std::shared_ptr< service > > > services_;
+ std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_;
+ std::map<service_t,
+ std::map<instance_t,
+ std::shared_ptr<service> > > services_;
- std::string routing_host_;
+ std::string routing_host_;
- bool is_service_discovery_enabled_;
- std::string service_discovery_multicast_;
- uint16_t service_discovery_port_;
- std::string service_discovery_protocol_;
+ bool is_service_discovery_enabled_;
+ std::string service_discovery_multicast_;
+ uint16_t service_discovery_port_;
+ std::string service_discovery_protocol_;
- std::map< std::string, client_t > applications_;
+ std::map<std::string, std::pair<client_t, std::size_t>> applications_;
- std::map< std::string, std::set< uint16_t > > magic_cookies_;
+ std::map<std::string, std::set<uint16_t> > magic_cookies_;
};
} // namespace cfg
diff --git a/implementation/configuration/include/event.hpp b/implementation/configuration/include/event.hpp
index 4f84623..e932289 100644
--- a/implementation/configuration/include/event.hpp
+++ b/implementation/configuration/include/event.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -18,13 +17,14 @@ namespace cfg {
struct eventgroup;
struct event {
- event(event_t _id, bool _is_field, bool _is_reliable)
- : id_(_id), is_field_(_is_field), is_reliable_(_is_reliable) {};
-
- event_t id_;
- bool is_field_;
- bool is_reliable_;
- std::vector<std::weak_ptr<eventgroup> > groups_;
+ event(event_t _id, bool _is_field, bool _is_reliable) :
+ id_(_id), is_field_(_is_field), is_reliable_(_is_reliable) {
+ }
+
+ event_t id_;
+ bool is_field_;
+ bool is_reliable_;
+ std::vector<std::weak_ptr<eventgroup> > groups_;
};
} // namespace cfg
diff --git a/implementation/configuration/include/eventgroup.hpp b/implementation/configuration/include/eventgroup.hpp
index 377c17f..27bf722 100644
--- a/implementation/configuration/include/eventgroup.hpp
+++ b/implementation/configuration/include/eventgroup.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,8 +16,8 @@ namespace cfg {
struct event;
struct eventgroup {
- eventgroup_t id_;
- std::set<std::shared_ptr<event> > events_;
+ eventgroup_t id_;
+ std::set<std::shared_ptr<event> > events_;
};
} // namespace cfg
diff --git a/implementation/configuration/include/internal.hpp b/implementation/configuration/include/internal.hpp
deleted file mode 100644
index 910cb3d..0000000
--- a/implementation/configuration/include/internal.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
-// 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_INTERNAL_HPP
-#define VSOMEIP_INTERNAL_HPP
-
-#include <cstdint>
-
-namespace vsomeip {
-
-#define VSOMEIP_SD_LIBRARY "libvsomeip-sd.so"
-#define VSOMEIP_SD_RUNTIME_SYMBOL VSOMEIP_SD_RUNTIME
-#define VSOMEIP_SD_RUNTIME_SYMBOL_STRING "VSOMEIP_SD_RUNTIME"
-
-#define VSOMEIP_ROUTING_CLIENT 0
-
-#define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100
-#define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000
-
-#define VSOMEIP_DEFAULT_WATCHDOG_CYCLE 1000
-#define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 1000
-#define VSOMEIP_DEFAULT_MAX_MISSING_PONGS 3
-
-#define VSOMEIP_INVALID_PORT 0xFFFF
-
-#define VSOMEIP_COMMAND_HEADER_SIZE 7
-
-#define VSOMEIP_COMMAND_TYPE_POS 0
-#define VSOMEIP_COMMAND_CLIENT_POS 1
-#define VSOMEIP_COMMAND_SIZE_POS_MIN 3
-#define VSOMEIP_COMMAND_SIZE_POS_MAX 5
-#define VSOMEIP_COMMAND_PAYLOAD_POS 7
-
-#define VSOMEIP_REGISTER_APPLICATION 0x00
-#define VSOMEIP_DEREGISTER_APPLICATION 0x01
-#define VSOMEIP_APPLICATION_LOST 0x02
-#define VSOMEIP_ROUTING_INFO 0x03
-
-#define VSOMEIP_PING 0x0E
-#define VSOMEIP_PONG 0x0F
-
-#define VSOMEIP_OFFER_SERVICE 0x10
-#define VSOMEIP_STOP_OFFER_SERVICE 0x11
-#define VSOMEIP_SUBSCRIBE 0x12
-#define VSOMEIP_UNSUBSCRIBE 0x13
-
-#define VSOMEIP_SEND 0x17
-#define VSOMEIP_SET 0x18
-
-#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 20
-#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 11
-#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18
-#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 13
-
-} // namespace vsomeip
-
-#endif // VSOMEIP_INTERNAL_HPP
diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in
new file mode 100644
index 0000000..4038b55
--- /dev/null
+++ b/implementation/configuration/include/internal.hpp.in
@@ -0,0 +1,61 @@
+// Copyright (C) 2014-2015 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_INTERNAL_HPP
+#define VSOMEIP_INTERNAL_HPP
+
+#include <cstdint>
+
+namespace vsomeip {
+
+#define VSOMEIP_SD_LIBRARY "libvsomeip-sd.so.@VSOMEIP_MAJOR_VERSION@"
+#define VSOMEIP_SD_RUNTIME_SYMBOL VSOMEIP_SD_RUNTIME
+#define VSOMEIP_SD_RUNTIME_SYMBOL_STRING "VSOMEIP_SD_RUNTIME"
+
+#define VSOMEIP_ROUTING_CLIENT 0
+
+#define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100
+#define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000
+
+#define VSOMEIP_DEFAULT_WATCHDOG_CYCLE 1000
+#define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 1000
+#define VSOMEIP_DEFAULT_MAX_MISSING_PONGS 3
+
+#define VSOMEIP_INVALID_PORT 0xFFFF
+
+#define VSOMEIP_COMMAND_HEADER_SIZE 7
+
+#define VSOMEIP_COMMAND_TYPE_POS 0
+#define VSOMEIP_COMMAND_CLIENT_POS 1
+#define VSOMEIP_COMMAND_SIZE_POS_MIN 3
+#define VSOMEIP_COMMAND_SIZE_POS_MAX 5
+#define VSOMEIP_COMMAND_PAYLOAD_POS 7
+
+#define VSOMEIP_REGISTER_APPLICATION 0x00
+#define VSOMEIP_DEREGISTER_APPLICATION 0x01
+#define VSOMEIP_APPLICATION_LOST 0x02
+#define VSOMEIP_ROUTING_INFO 0x03
+
+#define VSOMEIP_PING 0x0E
+#define VSOMEIP_PONG 0x0F
+
+#define VSOMEIP_OFFER_SERVICE 0x10
+#define VSOMEIP_STOP_OFFER_SERVICE 0x11
+#define VSOMEIP_SUBSCRIBE 0x12
+#define VSOMEIP_UNSUBSCRIBE 0x13
+#define VSOMEIP_REQUEST_SERVICE 0x14
+
+#define VSOMEIP_SEND 0x17
+#define VSOMEIP_SET 0x18
+
+#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 20
+#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 21
+#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 11
+#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18
+#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 13
+
+} // namespace vsomeip
+
+#endif // VSOMEIP_INTERNAL_HPP
diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp
index fd885e4..067dc41 100644
--- a/implementation/configuration/include/service.hpp
+++ b/implementation/configuration/include/service.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -18,21 +17,21 @@ struct event;
struct eventgroup;
struct service {
- service_t service_;
- instance_t instance_;
+ service_t service_;
+ instance_t instance_;
- uint16_t reliable_;
- uint16_t unreliable_;
+ uint16_t reliable_;
+ uint16_t unreliable_;
- std::string multicast_address_;
- uint16_t multicast_port_;
- eventgroup_t multicast_group_;
+ std::string multicast_address_;
+ uint16_t multicast_port_;
+ eventgroup_t multicast_group_;
- bool use_magic_cookies_;
+ bool use_magic_cookies_;
- std::shared_ptr<servicegroup> group_;
- std::map<event_t, std::shared_ptr<event> > events_;
- std::map<eventgroup_t, std::shared_ptr<eventgroup> > eventgroups_;
+ std::shared_ptr<servicegroup> group_;
+ std::map<event_t, std::shared_ptr<event> > events_;
+ std::map<eventgroup_t, std::shared_ptr<eventgroup> > eventgroups_;
};
} // namespace cfg
diff --git a/implementation/configuration/include/servicegroup.hpp b/implementation/configuration/include/servicegroup.hpp
index b1a2d81..e44d79f 100644
--- a/implementation/configuration/include/servicegroup.hpp
+++ b/implementation/configuration/include/servicegroup.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -11,15 +10,15 @@ namespace vsomeip {
namespace cfg {
struct servicegroup {
- std::string name_; // Name of the ServiceGroup
- std::string unicast_; // either "local" or an IP address
+ std::string name_; // Name of the ServiceGroup
+ std::string unicast_; // either "local" or an IP address
- uint32_t min_initial_delay_;
- uint32_t max_initial_delay_;
- uint32_t repetition_base_delay_;
- uint32_t cyclic_offer_delay_;
- uint32_t cyclic_request_delay_;
- uint8_t repetition_max_;
+ uint32_t min_initial_delay_;
+ uint32_t max_initial_delay_;
+ uint32_t repetition_base_delay_;
+ uint32_t cyclic_offer_delay_;
+ uint32_t cyclic_request_delay_;
+ uint8_t repetition_max_;
};
} // namespace cfg
diff --git a/implementation/configuration/src/configuration.cpp b/implementation/configuration/src/configuration.cpp
index b1aeefa..9a11b22 100644
--- a/implementation/configuration/src/configuration.cpp
+++ b/implementation/configuration/src/configuration.cpp
@@ -1,15 +1,14 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/. */
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include "../include/configuration_impl.hpp"
namespace vsomeip {
configuration * configuration::get(const std::string &_path) {
- return cfg::configuration_impl::get(_path);
+ return cfg::configuration_impl::get(_path);
}
} // namespace vsomeip
diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp
index 7480002..591a3dc 100644
--- a/implementation/configuration/src/configuration_impl.cpp
+++ b/implementation/configuration/src/configuration_impl.cpp
@@ -1,13 +1,14 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/. */
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <fstream>
#include <map>
#include <sstream>
+#define WIN32_LEAN_AND_MEAN
+
#include <boost/algorithm/string.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>
@@ -30,788 +31,820 @@ std::map<std::string, configuration *> configuration_impl::the_configurations;
std::mutex configuration_impl::mutex_;
configuration * configuration_impl::get(const std::string &_path) {
- configuration *its_configuration(0);
-
- bool is_freshly_loaded(false);
- {
- std::lock_guard<std::mutex> its_lock(mutex_);
-
- auto found_configuration = the_configurations.find(_path);
- if (found_configuration != the_configurations.end()) {
- its_configuration = found_configuration->second;
- } else {
- its_configuration = new configuration_impl;
- if (its_configuration->load(_path)) {
- the_configurations[_path] = its_configuration;
- is_freshly_loaded = true;
- } else {
- delete its_configuration;
- its_configuration = 0;
- }
+ configuration *its_configuration(0);
+
+ bool is_freshly_loaded(false);
+ {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ auto found_configuration = the_configurations.find(_path);
+ if (found_configuration != the_configurations.end()) {
+ its_configuration = found_configuration->second;
+ } else {
+ its_configuration = new configuration_impl;
+ if (its_configuration->load(_path)) {
+ the_configurations[_path] = its_configuration;
+ is_freshly_loaded = true;
+ } else {
+ delete its_configuration;
+ its_configuration = 0;
+ }
+ }
}
- }
- if (is_freshly_loaded)
- logger_impl::init(_path);
+ if (is_freshly_loaded)
+ logger_impl::init(_path);
- return its_configuration;
+ return its_configuration;
}
-configuration_impl::configuration_impl()
- : has_console_log_(true),
- has_file_log_(false),
- has_dlt_log_(false),
- logfile_("/tmp/vsomeip.log"),
- loglevel_(boost::log::trivial::severity_level::info),
- routing_host_("vsomeipd"),
- is_service_discovery_enabled_(false) {
+configuration_impl::configuration_impl() :
+ has_console_log_(true), has_file_log_(false), has_dlt_log_(false), logfile_(
+ "/tmp/vsomeip.log"), loglevel_(
+ boost::log::trivial::severity_level::info), routing_host_(
+ "vsomeipd"), is_service_discovery_enabled_(false) {
- unicast_ = unicast_.from_string("127.0.0.1");
+ unicast_ = unicast_.from_string("127.0.0.1");
}
configuration_impl::~configuration_impl() {
}
bool configuration_impl::load(const std::string &_path) {
- bool is_loaded(true);
- boost::property_tree::ptree its_tree;
-
- try {
- boost::property_tree::json_parser::read_json(_path, its_tree);
-
- // Read the configuration data
- is_loaded = get_someip_configuration(its_tree);
- is_loaded = get_logging_configuration(its_tree);
- is_loaded = is_loaded && get_services_configuration(its_tree);
- is_loaded = is_loaded && get_routing_configuration(its_tree);
- is_loaded = is_loaded && get_service_discovery_configuration(its_tree);
- is_loaded = is_loaded && get_applications_configuration(its_tree);
- } catch (std::exception &e) {
- std::cerr << e.what() << std::endl;
- is_loaded = false;
- }
+ bool is_loaded(true);
+ boost::property_tree::ptree its_tree;
+
+ try {
+ boost::property_tree::json_parser::read_json(_path, its_tree);
+
+ // Read the configuration data
+ is_loaded = get_someip_configuration(its_tree);
+ is_loaded = get_logging_configuration(its_tree);
+ is_loaded = is_loaded && get_services_configuration(its_tree);
+ is_loaded = is_loaded && get_routing_configuration(its_tree);
+ is_loaded = is_loaded && get_service_discovery_configuration(its_tree);
+ is_loaded = is_loaded && get_applications_configuration(its_tree);
+ } catch (std::exception &e) {
+ std::cerr << e.what() << std::endl;
+ is_loaded = false;
+ }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_someip_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- std::string its_value = _tree.get < std::string > ("unicast");
- unicast_ = unicast_.from_string(its_value);
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ std::string its_value = _tree.get<std::string>("unicast");
+ unicast_ = unicast_.from_string(its_value);
+ } catch (...) {
+ is_loaded = false;
+ }
+ return is_loaded;
}
bool configuration_impl::get_logging_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- auto its_logging = _tree.get_child("logging");
- for (auto i = its_logging.begin(); i != its_logging.end(); ++i) {
- std::string its_key(i->first);
- if (its_key == "console") {
- std::string its_value(i->second.data());
- has_console_log_ = (its_value == "true");
- } else if (its_key == "file") {
- for (auto j : i->second) {
- std::string its_sub_key(j.first);
- std::string its_sub_value(j.second.data());
- if (its_sub_key == "enable") {
- has_file_log_ = (its_sub_value == "true");
- } else if (its_sub_key == "path") {
- logfile_ = its_sub_value;
- }
- }
- } else if (its_key == "dlt") {
- std::string its_value(i->second.data());
- has_dlt_log_ = (its_value == "true");
- } else if (its_key == "level") {
- std::string its_value(i->second.data());
- loglevel_ =
- (its_value == "trace" ?
- boost::log::trivial::severity_level::trace :
- (its_value == "debug" ?
- boost::log::trivial::severity_level::debug :
- (its_value == "info" ?
- boost::log::trivial::severity_level::info :
- (its_value == "warning" ?
- boost::log::trivial::severity_level::warning :
+ boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ auto its_logging = _tree.get_child("logging");
+ for (auto i = its_logging.begin(); i != its_logging.end(); ++i) {
+ std::string its_key(i->first);
+ if (its_key == "console") {
+ std::string its_value(i->second.data());
+ has_console_log_ = (its_value == "true");
+ } else if (its_key == "file") {
+ for (auto j : i->second) {
+ std::string its_sub_key(j.first);
+ std::string its_sub_value(j.second.data());
+ if (its_sub_key == "enable") {
+ has_file_log_ = (its_sub_value == "true");
+ } else if (its_sub_key == "path") {
+ logfile_ = its_sub_value;
+ }
+ }
+ } else if (its_key == "dlt") {
+ std::string its_value(i->second.data());
+ has_dlt_log_ = (its_value == "true");
+ } else if (its_key == "level") {
+ std::string its_value(i->second.data());
+ loglevel_ = (its_value == "trace" ?
+ boost::log::trivial::severity_level::trace :
+ (its_value == "debug" ?
+ boost::log::trivial::severity_level::debug :
+ (its_value == "info" ?
+ boost::log::trivial::severity_level::info :
+ (its_value == "warning" ?
+ boost::log::trivial::severity_level::warning :
(its_value == "error" ?
boost::log::trivial::severity_level::error :
- (its_value == "fatal" ?
- boost::log::trivial::severity_level::fatal :
- boost::log::trivial::severity_level::info))))));
- }
+ (its_value == "fatal" ?
+ boost::log::trivial::severity_level::fatal :
+ boost::log::trivial::severity_level::info))))));
+ }
+ }
+ } catch (...) {
+ is_loaded = false;
}
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_services_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- auto its_services = _tree.get_child("servicegroups");
- for (auto i = its_services.begin(); i != its_services.end(); ++i)
- is_loaded = is_loaded && get_servicegroup_configuration(i->second);
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ auto its_services = _tree.get_child("servicegroups");
+ for (auto i = its_services.begin(); i != its_services.end(); ++i)
+ is_loaded = is_loaded && get_servicegroup_configuration(i->second);
+ } catch (...) {
+ // This section is optional!
+ }
+ return is_loaded;
}
bool configuration_impl::get_servicegroup_configuration(
- const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- std::shared_ptr<servicegroup> its_servicegroup(
- std::make_shared<servicegroup>());
- its_servicegroup->unicast_ = "local"; // Default
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- std::string its_key(i->first);
- if (its_key == "name") {
- its_servicegroup->name_ = i->second.data();
- } else if (its_key == "unicast") {
- its_servicegroup->unicast_ = i->second.data();
- } else if (its_key == "delays") {
- is_loaded = is_loaded
- && get_delays_configuration(its_servicegroup, i->second);
- } else if (its_key == "services") {
- for (auto j = i->second.begin(); j != i->second.end(); ++j)
- is_loaded = is_loaded
- && get_service_configuration(its_servicegroup, j->second);
- }
+ const boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ std::shared_ptr<servicegroup> its_servicegroup(
+ std::make_shared<servicegroup>());
+ its_servicegroup->unicast_ = "local"; // Default
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ std::string its_key(i->first);
+ if (its_key == "name") {
+ its_servicegroup->name_ = i->second.data();
+ } else if (its_key == "unicast") {
+ its_servicegroup->unicast_ = i->second.data();
+ } else if (its_key == "delays") {
+ is_loaded = is_loaded
+ && get_delays_configuration(its_servicegroup,
+ i->second);
+ } else if (its_key == "services") {
+ for (auto j = i->second.begin(); j != i->second.end(); ++j)
+ is_loaded = is_loaded
+ && get_service_configuration(its_servicegroup,
+ j->second);
+ }
+ }
+ servicegroups_[its_servicegroup->name_] = its_servicegroup;
+ } catch (...) {
+ is_loaded = false;
}
- servicegroups_[its_servicegroup->name_] = its_servicegroup;
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_delays_configuration(
- std::shared_ptr<servicegroup> &_group,
- const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- std::stringstream its_converter;
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- std::string its_key(i->first);
- if (its_key == "initial") {
- _group->min_initial_delay_ = i->second.get < uint32_t > ("minimum");
- _group->max_initial_delay_ = i->second.get < uint32_t > ("maximum");
- } else if (its_key == "repetition-base") {
- its_converter << std::dec << i->second.data();
- its_converter >> _group->repetition_base_delay_;
- } else if (its_key == "repetition-max") {
- int tmp_repetition_max;
- its_converter << std::dec << i->second.data();
- its_converter >> tmp_repetition_max;
- _group->repetition_max_ = tmp_repetition_max;
- } else if (its_key == "cyclic-offer") {
- its_converter << std::dec << i->second.data();
- its_converter >> _group->cyclic_offer_delay_;
- } else if (its_key == "cyclic-request") {
- its_converter << std::dec << i->second.data();
- its_converter >> _group->cyclic_request_delay_;
- }
- its_converter.str("");
- its_converter.clear();
+ std::shared_ptr<servicegroup> &_group,
+ const boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ std::stringstream its_converter;
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ std::string its_key(i->first);
+ if (its_key == "initial") {
+ _group->min_initial_delay_ = i->second.get<uint32_t>("minimum");
+ _group->max_initial_delay_ = i->second.get<uint32_t>("maximum");
+ } else if (its_key == "repetition-base") {
+ its_converter << std::dec << i->second.data();
+ its_converter >> _group->repetition_base_delay_;
+ } else if (its_key == "repetition-max") {
+ int tmp_repetition_max;
+ its_converter << std::dec << i->second.data();
+ its_converter >> tmp_repetition_max;
+ _group->repetition_max_ = tmp_repetition_max;
+ } else if (its_key == "cyclic-offer") {
+ its_converter << std::dec << i->second.data();
+ its_converter >> _group->cyclic_offer_delay_;
+ } else if (its_key == "cyclic-request") {
+ its_converter << std::dec << i->second.data();
+ its_converter >> _group->cyclic_request_delay_;
+ }
+ its_converter.str("");
+ its_converter.clear();
+ }
+ } catch (...) {
+ is_loaded = false;
}
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_service_configuration(
- std::shared_ptr<servicegroup> &_group,
- const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- bool use_magic_cookies(false);
-
- std::shared_ptr<service> its_service(std::make_shared<service>());
- its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT;
- its_service->use_magic_cookies_ = false;
- its_service->group_ = _group;
- its_service->multicast_address_ = "";
- its_service->multicast_port_ = ILLEGAL_PORT;
- its_service->multicast_group_ = 0xFFFF; // TODO: use symbolic constant
-
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- std::string its_key(i->first);
- std::string its_value(i->second.data());
- std::stringstream its_converter;
-
- if (its_key == "reliable") {
- try {
- its_value = i->second.get_child("port").data();
- its_converter << its_value;
- its_converter >> its_service->reliable_;
- } catch (...) {
- its_converter << its_value;
- its_converter >> its_service->reliable_;
+ std::shared_ptr<servicegroup> &_group,
+ const boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ bool use_magic_cookies(false);
+
+ std::shared_ptr<service> its_service(std::make_shared<service>());
+ its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT;
+ its_service->use_magic_cookies_ = false;
+ its_service->group_ = _group;
+ its_service->multicast_address_ = "";
+ its_service->multicast_port_ = ILLEGAL_PORT;
+ its_service->multicast_group_ = 0xFFFF; // TODO: use symbolic constant
+
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ std::string its_key(i->first);
+ std::string its_value(i->second.data());
+ std::stringstream its_converter;
+
+ if (its_key == "reliable") {
+ try {
+ its_value = i->second.get_child("port").data();
+ its_converter << its_value;
+ its_converter >> its_service->reliable_;
+ } catch (...) {
+ its_converter << its_value;
+ its_converter >> its_service->reliable_;
+ }
+ try {
+ its_value =
+ i->second.get_child("enable-magic-cookies").data();
+ use_magic_cookies = ("true" == its_value);
+ } catch (...) {
+
+ }
+ } else if (its_key == "unreliable") {
+ its_converter << its_value;
+ its_converter >> its_service->unreliable_;
+ } else if (its_key == "multicast") {
+ try {
+ its_value = i->second.get_child("address").data();
+ its_service->multicast_address_ = its_value;
+ its_value = i->second.get_child("port").data();
+ its_converter << its_value;
+ its_converter >> its_service->multicast_port_;
+ } catch (...) {
+ }
+ } else if (its_key == "events") {
+ get_event_configuration(its_service, i->second);
+ } else if (its_key == "eventgroups") {
+ get_eventgroup_configuration(its_service, i->second);
+ } else {
+ // Trim "its_value"
+ if (its_value[0] == '0' && its_value[1] == 'x') {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+
+ if (its_key == "service") {
+ its_converter >> its_service->service_;
+ } else if (its_key == "instance") {
+ its_converter >> its_service->instance_;
+ }
+ }
}
- try {
- its_value = i->second.get_child("enable-magic-cookies").data();
- use_magic_cookies = ("true" == its_value);
- } catch (...) {
- }
- } else if (its_key == "unreliable") {
- its_converter << its_value;
- its_converter >> its_service->unreliable_;
- } else if (its_key == "multicast") {
- try {
- its_value = i->second.get_child("address").data();
- its_service->multicast_address_ = its_value;
- its_value = i->second.get_child("port").data();
- its_converter << its_value;
- its_converter >> its_service->multicast_port_;
- } catch (...) {
- }
- } else if (its_key == "events") {
- get_event_configuration(its_service, i->second);
- } else if (its_key == "eventgroups") {
- get_eventgroup_configuration(its_service, i->second);
- } else {
- // Trim "its_value"
- if (its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
- } else {
- its_converter << std::dec << its_value;
+ auto found_service = services_.find(its_service->service_);
+ if (found_service != services_.end()) {
+ auto found_instance = found_service->second.find(
+ its_service->instance_);
+ if (found_instance != found_service->second.end()) {
+ is_loaded = false;
+ }
}
- if (its_key == "service") {
- its_converter >> its_service->service_;
- } else if (its_key == "instance") {
- its_converter >> its_service->instance_;
+ if (is_loaded) {
+ services_[its_service->service_][its_service->instance_] =
+ its_service;
}
- }
- }
- auto found_service = services_.find(its_service->service_);
- if (found_service != services_.end()) {
- auto found_instance = found_service->second.find(its_service->instance_);
- if (found_instance != found_service->second.end()) {
+ if (use_magic_cookies) {
+ std::string its_unicast(_group->unicast_);
+ if (its_unicast == "local")
+ its_unicast = unicast_.to_string();
+ magic_cookies_[its_unicast].insert(its_service->reliable_);
+ }
+ } catch (...) {
is_loaded = false;
- }
- }
-
- if (is_loaded) {
- services_[its_service->service_][its_service->instance_] = its_service;
}
-
- if (use_magic_cookies) {
- std::string its_unicast(_group->unicast_);
- if (its_unicast == "local")
- its_unicast = unicast_.to_string();
- magic_cookies_[its_unicast].insert(its_service->reliable_);
- }
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_event_configuration(
- std::shared_ptr<service> &_service,
- const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- event_t its_event_id(0);
- bool its_is_field(false);
- bool its_is_reliable(false);
-
- for (auto j = i->second.begin(); j != i->second.end(); ++j) {
- std::string its_key(j->first);
- std::string its_value(j->second.data());
- if (its_key == "event") {
- std::stringstream its_converter;
- if (its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
- } else {
- its_converter << std::dec << its_value;
+ std::shared_ptr<service> &_service,
+ const boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ event_t its_event_id(0);
+ bool its_is_field(false);
+ bool its_is_reliable(false);
+
+ for (auto j = i->second.begin(); j != i->second.end(); ++j) {
+ std::string its_key(j->first);
+ std::string its_value(j->second.data());
+ if (its_key == "event") {
+ std::stringstream its_converter;
+ if (its_value[0] == '0' && its_value[1] == 'x') {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_event_id;
+ } else if (its_key == "is_field") {
+ its_is_field = (its_value == "true");
+ } else if (its_key == "is_reliable") {
+ its_is_reliable = (its_value == "true");
+ }
}
- its_converter >> its_event_id;
- } else if (its_key == "is_field") {
- its_is_field = (its_value == "true");
- } else if (its_key == "is_reliable") {
- its_is_reliable = (its_value == "true");
- }
- }
- if (its_event_id > 0) {
- auto found_event = _service->events_.find(its_event_id);
- if (found_event != _service->events_.end()) {
- found_event->second->is_field_ = its_is_field;
- } else {
- std::shared_ptr<event> its_event = std::make_shared < event
- > (its_event_id, its_is_field, its_is_reliable);
- _service->events_[its_event_id] = its_event;
- }
+ if (its_event_id > 0) {
+ auto found_event = _service->events_.find(its_event_id);
+ if (found_event != _service->events_.end()) {
+ found_event->second->is_field_ = its_is_field;
+ } else {
+ std::shared_ptr<event> its_event = std::make_shared<event>(
+ its_event_id, its_is_field, its_is_reliable);
+ _service->events_[its_event_id] = its_event;
+ }
+ }
}
- }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_eventgroup_configuration(
- std::shared_ptr<service> &_service,
- const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- bool is_multicast;
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- is_multicast = false;
- std::shared_ptr<eventgroup> its_eventgroup = std::make_shared<eventgroup>();
- for (auto j = i->second.begin(); j != i->second.end(); ++j) {
- std::string its_key(j->first);
- if (its_key == "eventgroup") {
- std::stringstream its_converter;
- std::string its_value(j->second.data());
- if (its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
- } else {
- its_converter << std::dec << its_value;
- }
- its_converter >> its_eventgroup->id_;
- } else if (its_key == "is_multicast") {
- std::string its_value(j->second.data());
- is_multicast = (its_value == "true");
- } else if (its_key == "events") {
- for (auto k = j->second.begin(); k != j->second.end(); ++k) {
- std::stringstream its_converter;
- std::string its_value(k->second.data());
- event_t its_event_id(0);
- if (its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
- } else {
- its_converter << std::dec << its_value;
- }
- its_converter >> its_event_id;
- if (0 < its_event_id) {
- std::shared_ptr<event> its_event(nullptr);
- auto find_event = _service->events_.find(its_event_id);
- if (find_event != _service->events_.end()) {
- its_event = find_event->second;
- } else {
- its_event = std::make_shared<event>(its_event_id, false, false);
- }
- if (its_event) {
- its_event->groups_.push_back(its_eventgroup);
- its_eventgroup->events_.insert(its_event);
- _service->events_[its_event_id] = its_event;
+ std::shared_ptr<service> &_service,
+ const boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ bool is_multicast;
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ is_multicast = false;
+ std::shared_ptr<eventgroup> its_eventgroup =
+ std::make_shared<eventgroup>();
+ for (auto j = i->second.begin(); j != i->second.end(); ++j) {
+ std::string its_key(j->first);
+ if (its_key == "eventgroup") {
+ std::stringstream its_converter;
+ std::string its_value(j->second.data());
+ if (its_value[0] == '0' && its_value[1] == 'x') {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_eventgroup->id_;
+ } else if (its_key == "is_multicast") {
+ std::string its_value(j->second.data());
+ is_multicast = (its_value == "true");
+ } else if (its_key == "events") {
+ for (auto k = j->second.begin(); k != j->second.end(); ++k) {
+ std::stringstream its_converter;
+ std::string its_value(k->second.data());
+ event_t its_event_id(0);
+ if (its_value[0] == '0' && its_value[1] == 'x') {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_event_id;
+ if (0 < its_event_id) {
+ std::shared_ptr<event> its_event(nullptr);
+ auto find_event = _service->events_.find(its_event_id);
+ if (find_event != _service->events_.end()) {
+ its_event = find_event->second;
+ } else {
+ its_event = std::make_shared<event>(its_event_id,
+ false, false);
+ }
+ if (its_event) {
+ its_event->groups_.push_back(its_eventgroup);
+ its_eventgroup->events_.insert(its_event);
+ _service->events_[its_event_id] = its_event;
+ }
+ }
+ }
}
- }
}
- }
- }
- if (its_eventgroup->id_ > 0) {
- if (is_multicast) {
- _service->multicast_group_ = its_eventgroup->id_;
- }
- _service->eventgroups_[its_eventgroup->id_] = its_eventgroup;
+ if (its_eventgroup->id_ > 0) {
+ if (is_multicast) {
+ _service->multicast_group_ = its_eventgroup->id_;
+ }
+ _service->eventgroups_[its_eventgroup->id_] = its_eventgroup;
+ }
}
- }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_routing_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- auto its_routing = _tree.get_child("routing");
- routing_host_ = its_routing.data();
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ auto its_routing = _tree.get_child("routing");
+ routing_host_ = its_routing.data();
+ } catch (...) {
+ is_loaded = false;
+ }
+ return is_loaded;
}
bool configuration_impl::get_service_discovery_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- auto its_service_discovery = _tree.get_child("service-discovery");
- for (auto i = its_service_discovery.begin();
- i != its_service_discovery.end(); ++i) {
- std::string its_key(i->first);
- std::string its_value(i->second.data());
- if (its_key == "enable") {
- is_service_discovery_enabled_ = (its_value == "true");
- } else if (its_key == "multicast") {
- service_discovery_multicast_ = its_value;
- } else if (its_key == "port") {
- std::stringstream its_converter;
- its_converter << its_value;
- its_converter >> service_discovery_port_;
- } else if (its_key == "protocol") {
- service_discovery_protocol_ = its_value;
- }
+ boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ auto its_service_discovery = _tree.get_child("service-discovery");
+ for (auto i = its_service_discovery.begin();
+ i != its_service_discovery.end(); ++i) {
+ std::string its_key(i->first);
+ std::string its_value(i->second.data());
+ if (its_key == "enable") {
+ is_service_discovery_enabled_ = (its_value == "true");
+ } else if (its_key == "multicast") {
+ service_discovery_multicast_ = its_value;
+ } else if (its_key == "port") {
+ std::stringstream its_converter;
+ its_converter << its_value;
+ its_converter >> service_discovery_port_;
+ } else if (its_key == "protocol") {
+ service_discovery_protocol_ = its_value;
+ }
+ }
+ } catch (...) {
+ is_loaded = false;
}
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_applications_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- std::stringstream its_converter;
- auto its_applications = _tree.get_child("applications");
- for (auto i = its_applications.begin(); i != its_applications.end(); ++i)
- is_loaded = is_loaded && get_application_configuration(i->second);
- } catch (...) {
- is_loaded = false;
- }
+ boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ try {
+ std::stringstream its_converter;
+ auto its_applications = _tree.get_child("applications");
+ for (auto i = its_applications.begin(); i != its_applications.end();
+ ++i)
+ is_loaded = is_loaded && get_application_configuration(i->second);
+ } catch (...) {
+ is_loaded = false;
+ }
- return is_loaded;
+ return is_loaded;
}
bool configuration_impl::get_application_configuration(
- const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- std::string its_name("");
- client_t its_id;
- for (auto i = _tree.begin(); i != _tree.end(); ++i) {
- std::string its_key(i->first);
- std::string its_value(i->second.data());
- std::stringstream its_converter;
- if (its_key == "name") {
- its_name = its_value;
- } else if (its_key == "id") {
- if (its_value[0] == '0' && its_value[1] == 'x') {
- its_converter << std::hex << its_value;
- } else {
- its_converter << std::dec << its_value;
- }
- its_converter >> its_id;
+ const boost::property_tree::ptree &_tree) {
+ bool is_loaded(true);
+ std::string its_name("");
+ client_t its_id;
+ std::size_t its_num_dispatchers(0);
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ std::string its_key(i->first);
+ std::string its_value(i->second.data());
+ std::stringstream its_converter;
+ if (its_key == "name") {
+ its_name = its_value;
+ } else if (its_key == "id") {
+ if (its_value[0] == '0' && its_value[1] == 'x') {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_id;
+ } else if (its_key == "num_dispatchers") {
+ if (its_value[0] == '0' && its_value[1] == 'x') {
+ its_converter << std::hex << its_value;
+ } else {
+ its_converter << std::dec << its_value;
+ }
+ its_converter >> its_num_dispatchers;
+ }
}
- }
- if (its_name != "" && its_id != 0) {
- applications_[its_name] = its_id;
- }
- return is_loaded;
+ if (its_name != "" && its_id != 0) {
+ applications_[its_name] = {its_id, its_num_dispatchers};
+ }
+ return is_loaded;
}
// Public interface
const boost::asio::ip::address & configuration_impl::get_unicast() const {
- return unicast_;
+ return unicast_;
}
bool configuration_impl::is_v4() const {
- return unicast_.is_v4();
+ return unicast_.is_v4();
}
bool configuration_impl::is_v6() const {
- return unicast_.is_v6();
+ return unicast_.is_v6();
}
bool configuration_impl::has_console_log() const {
- return has_console_log_;
+ return has_console_log_;
}
bool configuration_impl::has_file_log() const {
- return has_file_log_;
+ return has_file_log_;
}
bool configuration_impl::has_dlt_log() const {
- return has_dlt_log_;
+ return has_dlt_log_;
}
const std::string & configuration_impl::get_logfile() const {
- return logfile_;
+ return logfile_;
}
boost::log::trivial::severity_level configuration_impl::get_loglevel() const {
- return loglevel_;
+ return loglevel_;
}
std::set<std::string> configuration_impl::get_servicegroups() const {
- std::set < std::string > its_keys;
- for (auto i : servicegroups_)
- its_keys.insert(i.first);
- return its_keys;
+ std::set<std::string> its_keys;
+ for (auto i : servicegroups_)
+ its_keys.insert(i.first);
+ return its_keys;
}
bool configuration_impl::is_local_servicegroup(const std::string &_name) const {
- bool is_local(false);
+ bool is_local(false);
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup) {
- is_local = (its_servicegroup->unicast_ == "local"
- || its_servicegroup->unicast_ == get_unicast().to_string());
- }
+ servicegroup *its_servicegroup = find_servicegroup(_name);
+ if (its_servicegroup) {
+ is_local = (its_servicegroup->unicast_ == "local"
+ || its_servicegroup->unicast_ == get_unicast().to_string());
+ }
- return is_local;
+ return is_local;
}
int32_t configuration_impl::get_min_initial_delay(
- const std::string &_name) const {
- int32_t its_delay = VSOMEIP_DEFAULT_MIN_INITIAL_DELAY;
+ const std::string &_name) const {
+ int32_t its_delay = 0;
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->min_initial_delay_;
+ servicegroup *its_servicegroup = find_servicegroup(_name);
+ if (its_servicegroup)
+ its_delay = its_servicegroup->min_initial_delay_;
- return its_delay;
+ return its_delay;
}
int32_t configuration_impl::get_max_initial_delay(
- const std::string &_name) const {
- int32_t its_delay = VSOMEIP_DEFAULT_MAX_INITIAL_DELAY;
+ const std::string &_name) const {
+ int32_t its_delay = 0;
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->max_initial_delay_;
+ servicegroup *its_servicegroup = find_servicegroup(_name);
+ if (its_servicegroup)
+ its_delay = its_servicegroup->max_initial_delay_;
- return its_delay;
+ return its_delay;
}
int32_t configuration_impl::get_repetition_base_delay(
- const std::string &_name) const {
- int32_t its_delay = VSOMEIP_DEFAULT_REPETITION_BASE_DELAY;
+ const std::string &_name) const {
+ int32_t its_delay = 0;
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->repetition_base_delay_;
+ servicegroup *its_servicegroup = find_servicegroup(_name);
+ if (its_servicegroup)
+ its_delay = its_servicegroup->repetition_base_delay_;
- return its_delay;
+ return its_delay;
}
uint8_t configuration_impl::get_repetition_max(const std::string &_name) const {
- uint8_t its_max = VSOMEIP_DEFAULT_REPETITION_MAX;
+ uint8_t its_max = 0;
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_max = its_servicegroup->repetition_max_;
+ servicegroup *its_servicegroup = find_servicegroup(_name);
+ if (its_servicegroup)
+ its_max = its_servicegroup->repetition_max_;
- return its_max;
+ return its_max;
}
int32_t configuration_impl::get_cyclic_offer_delay(
- const std::string &_name) const {
- uint32_t its_delay = VSOMEIP_DEFAULT_CYCLIC_OFFER_DELAY;
+ const std::string &_name) const {
+ uint32_t its_delay = 0;
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->cyclic_offer_delay_;
+ servicegroup *its_servicegroup = find_servicegroup(_name);
+ if (its_servicegroup)
+ its_delay = its_servicegroup->cyclic_offer_delay_;
- return its_delay;
+ return its_delay;
}
int32_t configuration_impl::get_cyclic_request_delay(
- const std::string &_name) const {
- uint32_t its_delay = VSOMEIP_DEFAULT_CYCLIC_REQUEST_DELAY;
+ const std::string &_name) const {
+ uint32_t its_delay = 0;
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->cyclic_request_delay_;
+ servicegroup *its_servicegroup = find_servicegroup(_name);
+ if (its_servicegroup)
+ its_delay = its_servicegroup->cyclic_request_delay_;
- return its_delay;
+ return its_delay;
}
std::string configuration_impl::get_group(service_t _service,
- instance_t _instance) const {
- std::string its_group("default");
- service *its_service = find_service(_service, _instance);
- if (nullptr != its_service) {
- its_group = its_service->group_->name_;
- }
- return its_group;
+ instance_t _instance) const {
+ std::string its_group("default");
+ service *its_service = find_service(_service, _instance);
+ if (nullptr != its_service) {
+ its_group = its_service->group_->name_;
+ }
+ return its_group;
}
std::string configuration_impl::get_unicast(service_t _service,
- instance_t _instance) const {
- std::string its_unicast("");
- service *its_service = find_service(_service, _instance);
- if (its_service)
- its_unicast = its_service->group_->unicast_;
- return its_unicast;
+ instance_t _instance) const {
+ std::string its_unicast("");
+ service *its_service = find_service(_service, _instance);
+ if (its_service)
+ its_unicast = its_service->group_->unicast_;
+ return its_unicast;
}
-std::string configuration_impl::get_multicast_address(
- service_t _service, instance_t _instance) const {
- std::string its_multicast_address("");
- service *its_service = find_service(_service, _instance);
- if (its_service)
- its_multicast_address = its_service->multicast_address_;
- return its_multicast_address;
+std::string configuration_impl::get_multicast_address(service_t _service,
+ instance_t _instance) const {
+ std::string its_multicast_address("");
+ service *its_service = find_service(_service, _instance);
+ if (its_service)
+ its_multicast_address = its_service->multicast_address_;
+ return its_multicast_address;
}
-uint16_t configuration_impl::get_multicast_port(
- service_t _service, instance_t _instance) const {
- uint16_t its_multicast_port(ILLEGAL_PORT);
- service *its_service = find_service(_service, _instance);
- if (its_service)
- its_multicast_port = its_service->multicast_port_;
- return its_multicast_port;
+uint16_t configuration_impl::get_multicast_port(service_t _service,
+ instance_t _instance) const {
+ uint16_t its_multicast_port(ILLEGAL_PORT);
+ service *its_service = find_service(_service, _instance);
+ if (its_service)
+ its_multicast_port = its_service->multicast_port_;
+ return its_multicast_port;
}
uint16_t configuration_impl::get_multicast_group(service_t _service,
- instance_t _instance) const {
- uint16_t its_multicast_group(0xFFFF);
- service *its_service = find_service(_service, _instance);
- if (its_service)
- its_multicast_group = its_service->multicast_group_;
- return its_multicast_group;
+ instance_t _instance) const {
+ uint16_t its_multicast_group(0xFFFF);
+ service *its_service = find_service(_service, _instance);
+ if (its_service)
+ its_multicast_group = its_service->multicast_group_;
+ return its_multicast_group;
}
uint16_t configuration_impl::get_reliable_port(service_t _service,
- instance_t _instance) const {
- uint16_t its_reliable = ILLEGAL_PORT;
+ instance_t _instance) const {
+ uint16_t its_reliable = ILLEGAL_PORT;
- service *its_service = find_service(_service, _instance);
- if (its_service)
- its_reliable = its_service->reliable_;
+ service *its_service = find_service(_service, _instance);
+ if (its_service)
+ its_reliable = its_service->reliable_;
- return its_reliable;
+ return its_reliable;
}
bool configuration_impl::has_enabled_magic_cookies(std::string _address,
- uint16_t _port) const {
- bool has_enabled(false);
- auto find_address = magic_cookies_.find(_address);
- if (find_address != magic_cookies_.end()) {
- auto find_port = find_address->second.find(_port);
- if (find_port != find_address->second.end()) {
- has_enabled = true;
+ uint16_t _port) const {
+ bool has_enabled(false);
+ auto find_address = magic_cookies_.find(_address);
+ if (find_address != magic_cookies_.end()) {
+ auto find_port = find_address->second.find(_port);
+ if (find_port != find_address->second.end()) {
+ has_enabled = true;
+ }
}
- }
- return has_enabled;
+ return has_enabled;
}
uint16_t configuration_impl::get_unreliable_port(service_t _service,
- instance_t _instance) const {
- uint16_t its_unreliable = ILLEGAL_PORT;
+ instance_t _instance) const {
+ uint16_t its_unreliable = ILLEGAL_PORT;
- service *its_service = find_service(_service, _instance);
- if (its_service)
- its_unreliable = its_service->unreliable_;
+ service *its_service = find_service(_service, _instance);
+ if (its_service)
+ its_unreliable = its_service->unreliable_;
- return its_unreliable;
+ return its_unreliable;
}
const std::string & configuration_impl::get_routing_host() const {
- return routing_host_;
+ return routing_host_;
}
bool configuration_impl::is_service_discovery_enabled() const {
- return is_service_discovery_enabled_;
+ return is_service_discovery_enabled_;
}
-const std::string & configuration_impl::get_service_discovery_protocol() const {
- return service_discovery_protocol_;
+const std::string &
+configuration_impl::get_service_discovery_protocol() const {
+ return service_discovery_protocol_;
}
-const std::string & configuration_impl::get_service_discovery_multicast() const {
- return service_discovery_multicast_;
+const std::string &
+configuration_impl::get_service_discovery_multicast() const {
+ return service_discovery_multicast_;
}
uint16_t configuration_impl::get_service_discovery_port() const {
- return service_discovery_port_;
+ return service_discovery_port_;
}
client_t configuration_impl::get_id(const std::string &_name) const {
- client_t its_client = 0;
+ client_t its_client = 0;
- auto found_application = applications_.find(_name);
- if (found_application != applications_.end()) {
- its_client = found_application->second;
- }
+ auto found_application = applications_.find(_name);
+ if (found_application != applications_.end()) {
+ its_client = found_application->second.first;
+ }
- return its_client;
+ return its_client;
}
-std::set<std::pair<service_t, instance_t> > configuration_impl::get_remote_services() const {
- std::set < std::pair<service_t, instance_t> > its_remote_services;
- for (auto i : services_) {
- for (auto j : i.second) {
- if (j.second->group_->unicast_ != "local")
- its_remote_services.insert(std::make_pair(i.first, j.first));
+std::size_t configuration_impl::get_num_dispatchers(
+ const std::string &_name) const {
+ std::size_t its_num_dispatchers = 0;
+
+ auto found_application = applications_.find(_name);
+ if (found_application != applications_.end()) {
+ its_num_dispatchers = found_application->second.second;
}
- }
- return its_remote_services;
+
+ return its_num_dispatchers;
}
-std::map<service_t,
- std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > configuration_impl::get_eventgroups() const {
- std::map<service_t,
- std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups;
- for (auto i : services_) {
- for (auto j : i.second) {
- if (j.second->group_->unicast_ == "local") {
- for (auto k : j.second->eventgroups_) {
- for (auto l : k.second->events_) {
- its_eventgroups[i.first][j.first][k.second->id_].insert(l->id_);
- }
+std::set<std::pair<service_t, instance_t> >
+configuration_impl::get_remote_services() const {
+ std::set<std::pair<service_t, instance_t> > its_remote_services;
+ for (auto i : services_) {
+ for (auto j : i.second) {
+ if (j.second->group_->unicast_ != "local")
+ its_remote_services.insert(std::make_pair(i.first, j.first));
}
- }
}
- }
- return its_eventgroups;
+ return its_remote_services;
}
-std::map<service_t, std::map<instance_t, std::set<event_t> > > configuration_impl::get_events() const {
- std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events;
- for (auto i : services_) {
- for (auto j : i.second) {
- if (j.second->group_->unicast_ == "local") {
- for (auto k : j.second->events_) {
- its_events[i.first][j.first].insert(k.first);
+std::map<service_t,
+ std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > >
+configuration_impl::get_eventgroups() const {
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups;
+ for (auto i : services_) {
+ for (auto j : i.second) {
+ if (j.second->group_->unicast_ == "local") {
+ for (auto k : j.second->eventgroups_) {
+ for (auto l : k.second->events_) {
+ its_eventgroups[i.first][j.first]
+ [k.second->id_].insert(l->id_);
+ }
+ }
+ }
+ }
+ }
+ return its_eventgroups;
+}
+
+std::map<service_t, std::map<instance_t, std::set<event_t> > >
+configuration_impl::get_events() const {
+ std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events;
+ for (auto i : services_) {
+ for (auto j : i.second) {
+ if (j.second->group_->unicast_ == "local") {
+ for (auto k : j.second->events_) {
+ its_events[i.first][j.first].insert(k.first);
+ }
+ }
}
- }
}
- }
- return its_events;
+ return its_events;
}
void configuration_impl::set_event(
- std::shared_ptr<vsomeip::event> &_event) const {
- auto found_service = services_.find(_event->get_service());
- if (found_service != services_.end()) {
- auto found_instance = found_service->second.find(_event->get_instance());
- if (found_instance != found_service->second.end()) {
- auto found_event = found_instance->second->events_.find(
- _event->get_event());
- if (found_event != found_instance->second->events_.end()) {
- _event->set_field(found_event->second->is_field_);
- _event->set_reliable(found_event->second->is_reliable_);
- }
+ std::shared_ptr<vsomeip::event> &_event) const {
+ auto found_service = services_.find(_event->get_service());
+ if (found_service != services_.end()) {
+ auto found_instance = found_service->second.find(
+ _event->get_instance());
+ if (found_instance != found_service->second.end()) {
+ auto found_event = found_instance->second->events_.find(
+ _event->get_event());
+ if (found_event != found_instance->second->events_.end()) {
+ _event->set_field(found_event->second->is_field_);
+ _event->set_reliable(found_event->second->is_reliable_);
+ }
+ }
}
- }
}
servicegroup *configuration_impl::find_servicegroup(
- const std::string &_name) const {
- servicegroup *its_servicegroup(0);
- auto find_servicegroup = servicegroups_.find(_name);
- if (find_servicegroup != servicegroups_.end()) {
- its_servicegroup = find_servicegroup->second.get();
- }
- return its_servicegroup;
+ const std::string &_name) const {
+ servicegroup *its_servicegroup(0);
+ auto find_servicegroup = servicegroups_.find(_name);
+ if (find_servicegroup != servicegroups_.end()) {
+ its_servicegroup = find_servicegroup->second.get();
+ }
+ return its_servicegroup;
}
service *configuration_impl::find_service(service_t _service,
- instance_t _instance) const {
- service *its_service(0);
- auto find_service = services_.find(_service);
- if (find_service != services_.end()) {
- auto find_instance = find_service->second.find(_instance);
- if (find_instance != find_service->second.end()) {
- its_service = find_instance->second.get();
+ instance_t _instance) const {
+ service *its_service(0);
+ auto find_service = services_.find(_service);
+ if (find_service != services_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end()) {
+ its_service = find_instance->second.get();
+ }
}
- }
- return its_service;
+ return its_service;
}
} // namespace config
diff --git a/implementation/endpoints/include/buffer.hpp b/implementation/endpoints/include/buffer.hpp
index 8e9fbd7..f76c8d1 100644
--- a/implementation/endpoints/include/buffer.hpp
+++ b/implementation/endpoints/include/buffer.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,11 +14,11 @@
namespace vsomeip {
-typedef std::array< byte_t, VSOMEIP_PACKET_SIZE > packet_buffer_t;
-typedef std::shared_ptr< packet_buffer_t > packet_buffer_ptr_t;
+typedef std::array<byte_t, VSOMEIP_PACKET_SIZE> packet_buffer_t;
+typedef std::shared_ptr<packet_buffer_t> packet_buffer_ptr_t;
-typedef std::vector< byte_t > message_buffer_t;
-typedef std::shared_ptr< message_buffer_t > message_buffer_ptr_t;
+typedef std::vector<byte_t> message_buffer_t;
+typedef std::shared_ptr<message_buffer_t> message_buffer_ptr_t;
} // namespace vsomeip
diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp
index 7e460b6..0be6616 100644
--- a/implementation/endpoints/include/client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/client_endpoint_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -24,60 +23,59 @@ namespace vsomeip {
class endpoint;
class endpoint_host;
-template < typename Protocol, int MaxBufferSize >
-class client_endpoint_impl
- : public endpoint_impl< MaxBufferSize >,
- public std::enable_shared_from_this< client_endpoint_impl< Protocol, MaxBufferSize > > {
+template<typename Protocol, int MaxBufferSize>
+class client_endpoint_impl: public endpoint_impl<MaxBufferSize>,
+ public std::enable_shared_from_this<
+ client_endpoint_impl<Protocol, MaxBufferSize> > {
public:
- typedef typename Protocol::socket socket_type;
- typedef typename Protocol::endpoint endpoint_type;
+ typedef typename Protocol::socket socket_type;
+ typedef typename Protocol::endpoint endpoint_type;
- client_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _remote,
- boost::asio::io_service &_io);
- virtual ~client_endpoint_impl();
+ client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _remote, boost::asio::io_service &_io);
+ virtual ~client_endpoint_impl();
- bool send(const uint8_t *_data, uint32_t _size, bool _flush);
- bool send_to(const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush = true);
- bool flush();
+ bool send(const uint8_t *_data, uint32_t _size, bool _flush);bool send_to(
+ const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush = true);bool flush();
- void stop();
- void restart();
+ void stop();
+ void restart();
- bool is_client() const;
+ bool is_client() const;
- bool is_connected() const;
+ bool is_connected() const;
public:
- void connect_cbk(boost::system::error_code const &_error);
- void wait_connect_cbk(boost::system::error_code const &_error);
- void send_cbk(message_buffer_ptr_t _buffer, boost::system::error_code const &_error, std::size_t _bytes);
- void flush_cbk(boost::system::error_code const &_error);
+ void connect_cbk(boost::system::error_code const &_error);
+ void wait_connect_cbk(boost::system::error_code const &_error);
+ void send_cbk(message_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes);
+ void flush_cbk(boost::system::error_code const &_error);
public:
- virtual void connect() = 0;
- virtual void receive() = 0;
+ virtual void connect() = 0;
+ virtual void receive() = 0;
protected:
- socket_type socket_;
- endpoint_type remote_;
+ virtual void send_queued(message_buffer_ptr_t) = 0;
- boost::asio::system_timer flush_timer_;
- boost::asio::system_timer connect_timer_;
- uint32_t connect_timeout_;
- bool is_connected_;
+ socket_type socket_;
+ endpoint_type remote_;
- // send data
- message_buffer_ptr_t packetizer_;
+ boost::asio::system_timer flush_timer_;
+ boost::asio::system_timer connect_timer_;
+ uint32_t connect_timeout_;bool is_connected_;
- // receive data
- message_buffer_t message_;
+ // send data
+ message_buffer_ptr_t packetizer_;
- std::mutex mutex_;
+ // receive data
+ message_buffer_t message_;
- uint32_t queued_;
- virtual void send_queued(message_buffer_ptr_t) = 0;
+ std::mutex mutex_;
+
+ uint32_t queued_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp
index adc765a..49688ef 100644
--- a/implementation/endpoints/include/endpoint.hpp
+++ b/implementation/endpoints/include/endpoint.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,31 +14,34 @@ namespace vsomeip {
class endpoint_definition;
-class endpoint
-{
+class endpoint {
public:
- virtual ~endpoint() {};
+ virtual ~endpoint() {}
- virtual void start() = 0;
- virtual void stop() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
- virtual bool is_connected() const = 0;
+ virtual bool is_connected() const = 0;
- virtual bool send(const byte_t *_data, uint32_t _size, bool _flush = true) = 0;
- virtual bool send_to(std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush = true) = 0;
- virtual void enable_magic_cookies() = 0;
- virtual void receive() = 0;
+ virtual bool send(const byte_t *_data, uint32_t _size,
+ bool _flush = true) = 0;
+ virtual bool send_to(const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush = true) = 0;
+ virtual void enable_magic_cookies() = 0;
+ virtual void receive() = 0;
- virtual void join(const std::string &_address) = 0;
- virtual void leave(const std::string &_address) = 0;
+ virtual void join(const std::string &_address) = 0;
+ virtual void leave(const std::string &_address) = 0;
- virtual void add_multicast(service_t _service, event_t _event,
- const std::string &_address, uint16_t _port) = 0;
- virtual void remove_multicast(service_t _service, event_t _event) = 0;
+ virtual void add_multicast(service_t _service, event_t _event,
+ const std::string &_address, uint16_t _port) = 0;
+ virtual void remove_multicast(service_t _service, event_t _event) = 0;
- virtual unsigned short get_port() const = 0;
- virtual bool is_reliable() const = 0;
+ virtual bool get_remote_address(boost::asio::ip::address &_address) const = 0;
+ virtual unsigned short get_local_port() const = 0;
+ virtual unsigned short get_remote_port() const = 0;
+ virtual bool is_reliable() const = 0;
+ virtual bool is_local() const = 0;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_definition.hpp b/implementation/endpoints/include/endpoint_definition.hpp
index c0da686..30f53fd 100644
--- a/implementation/endpoints/include/endpoint_definition.hpp
+++ b/implementation/endpoints/include/endpoint_definition.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,26 +8,34 @@
#include <boost/asio/ip/address.hpp>
+#include <vsomeip/export.hpp>
+
namespace vsomeip {
class endpoint_definition {
public:
- endpoint_definition();
- endpoint_definition(const boost::asio::ip::address &_address, uint16_t _port, bool _is_reliable);
+ VSOMEIP_EXPORT endpoint_definition();
+ VSOMEIP_EXPORT endpoint_definition(
+ const boost::asio::ip::address &_address,
+ uint16_t _port, bool _is_reliable);
+
+ VSOMEIP_EXPORT const boost::asio::ip::address &get_address() const;
+ VSOMEIP_EXPORT void set_address(const boost::asio::ip::address &_address);
- const boost::asio::ip::address & get_address() const;
- void set_address(const boost::asio::ip::address &_address);
+ VSOMEIP_EXPORT uint16_t get_port() const;
+ VSOMEIP_EXPORT void set_port(uint16_t _port);
- uint16_t get_port() const;
- void set_port(uint16_t _port);
+ VSOMEIP_EXPORT uint16_t get_remote_port() const;
+ VSOMEIP_EXPORT void set_remote_port(uint16_t _port);
- bool is_reliable() const;
- void set_reliable(bool _is_reliable);
+ VSOMEIP_EXPORT bool is_reliable() const;
+ VSOMEIP_EXPORT void set_reliable(bool _is_reliable);
private:
- boost::asio::ip::address address_;
- uint16_t port_;
- bool is_reliable_;
+ boost::asio::ip::address address_;
+ uint16_t port_;
+ uint16_t remote_port_;
+ bool is_reliable_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_host.hpp b/implementation/endpoints/include/endpoint_host.hpp
index 4700a7e..af0c9b1 100644
--- a/implementation/endpoints/include/endpoint_host.hpp
+++ b/implementation/endpoints/include/endpoint_host.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,11 +16,12 @@ class endpoint;
class endpoint_host {
public:
- virtual ~endpoint_host() {};
+ virtual ~endpoint_host() {}
- virtual void on_connect(std::shared_ptr< endpoint > _endpoint) = 0;
- virtual void on_disconnect(std::shared_ptr< endpoint > _endpoint) = 0;
- virtual void on_message(const byte_t *_data, length_t _length, endpoint *_receiver) = 0;
+ virtual void on_connect(std::shared_ptr<endpoint> _endpoint) = 0;
+ virtual void on_disconnect(std::shared_ptr<endpoint> _endpoint) = 0;
+ virtual void on_message(const byte_t *_data, length_t _length,
+ endpoint *_receiver) = 0;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp
index 058c9cd..5c6fe39 100644
--- a/implementation/endpoints/include/endpoint_impl.hpp
+++ b/implementation/endpoints/include/endpoint_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -20,49 +19,53 @@ namespace vsomeip {
class endpoint_host;
-template < int MaxBufferSize >
-class endpoint_impl
- : public endpoint
-{
+template<int MaxBufferSize>
+class endpoint_impl: public endpoint {
public:
- endpoint_impl(std::shared_ptr< endpoint_host > _adapter, boost::asio::io_service &_io);
- virtual ~endpoint_impl();
+ endpoint_impl(std::shared_ptr<endpoint_host> _adapter,
+ boost::asio::io_service &_io);
+ virtual ~endpoint_impl();
- void enable_magic_cookies();
+ void enable_magic_cookies();
- // Dummy implementations as we only need these for UDP (servers)
- // TODO: redesign
- void join(const std::string &);
- void leave(const std::string &);
- void add_multicast(service_t, event_t, const std::string &, uint16_t);
- void remove_multicast(service_t, event_t);
+ // Dummy implementations as we only need these for UDP (servers)
+ // TODO: redesign
+ void join(const std::string &);
+ void leave(const std::string &);
+ void add_multicast(service_t, event_t, const std::string &, uint16_t);
+ void remove_multicast(service_t, event_t);
- // Dummy implementations as we only need these for server endpoints
- // TODO: redesign
- unsigned short get_port() const;
- bool is_reliable() const;
+ // Dummy implementation as we only need this for IP client endpoints
+ // TODO: redesign
+ bool get_remote_address(boost::asio::ip::address &_address) const;
-public: // required
- virtual bool is_client() const = 0;
- virtual void receive() = 0;
- virtual void restart() = 0;
+ // Dummy implementations as we only need these for server endpoints
+ // TODO: redesign
+ unsigned short get_local_port() const;
+ unsigned short get_remote_port() const;
+ bool is_reliable() const;
+
+public:
+ // required
+ virtual bool is_client() const = 0;
+ virtual void receive() = 0;
+ virtual void restart() = 0;
protected:
- virtual bool is_magic_cookie() const;
- uint32_t find_magic_cookie(message_buffer_t &_buffer);
+ virtual bool is_magic_cookie() const;
+ uint32_t find_magic_cookie(message_buffer_t &_buffer);
protected:
- // Reference to service context
- boost::asio::io_service &service_;
+ // Reference to service context
+ boost::asio::io_service &service_;
- // Reference to host
- endpoint_host *host_;
+ // Reference to host
+ std::weak_ptr<endpoint_host> host_;
- bool is_supporting_magic_cookies_;
- bool has_enabled_magic_cookies_;
+ bool is_supporting_magic_cookies_;bool has_enabled_magic_cookies_;
- // Filter configuration
- std::map< service_t, uint8_t > opened_;
+ // Filter configuration
+ std::map<service_t, uint8_t> opened_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_client_endpoint_impl.hpp
index d5abb92..9891ae4 100644
--- a/implementation/endpoints/include/local_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/local_client_endpoint_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -10,35 +9,49 @@
#include <boost/asio/io_service.hpp>
#include <boost/asio/local/stream_protocol.hpp>
+#ifdef WIN32
+#include <boost/asio/ip/tcp.hpp>
+#endif
+
#include <vsomeip/defines.hpp>
#include "client_endpoint_impl.hpp"
namespace vsomeip {
-typedef client_endpoint_impl<
- boost::asio::local::stream_protocol,
- VSOMEIP_MAX_LOCAL_MESSAGE_SIZE > local_client_endpoint_base_impl;
+#ifdef WIN32
+typedef client_endpoint_impl<boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE > local_client_endpoint_base_impl;
+#else
+typedef client_endpoint_impl<boost::asio::local::stream_protocol,
+ VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> local_client_endpoint_base_impl;
+#endif
-class local_client_endpoint_impl
- : public local_client_endpoint_base_impl {
+class local_client_endpoint_impl: public local_client_endpoint_base_impl {
public:
- local_client_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _local, boost::asio::io_service &_io);
+ local_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io);
+
+ virtual ~local_client_endpoint_impl();
+
+ void start();
- void start();
+ void send_queued(message_buffer_ptr_t _data);
- void send_queued(message_buffer_ptr_t _data);
+ bool is_local() const;
private:
- void send_magic_cookie();
+ void send_magic_cookie();
- void connect();
- void receive();
+ void connect();
+ void receive();
- void send_tag_cbk(boost::system::error_code const &_error, std::size_t _bytes);
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes);
+ void send_tag_cbk(boost::system::error_code const &_error,
+ std::size_t _bytes);
+ void receive_cbk(packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error,
+ std::size_t _bytes);
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/local_server_endpoint_impl.hpp b/implementation/endpoints/include/local_server_endpoint_impl.hpp
index 05c1122..a47858a 100644
--- a/implementation/endpoints/include/local_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/local_server_endpoint_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,6 +12,10 @@
#include <boost/asio/local/stream_protocol.hpp>
#include <boost/enable_shared_from_this.hpp>
+#ifdef WIN32
+#include <boost/asio/ip/tcp.hpp>
+#endif
+
#include <vsomeip/defines.hpp>
#include "buffer.hpp"
@@ -20,68 +23,80 @@
namespace vsomeip {
-typedef server_endpoint_impl<
- boost::asio::local::stream_protocol,
- VSOMEIP_MAX_LOCAL_MESSAGE_SIZE > local_server_endpoint_base_impl;
+#ifdef WIN32
+typedef server_endpoint_impl<boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE > local_server_endpoint_base_impl;
+#else
+typedef server_endpoint_impl<boost::asio::local::stream_protocol,
+ VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> local_server_endpoint_base_impl;
+#endif
-class local_server_endpoint_impl
- : public local_server_endpoint_base_impl {
+class local_server_endpoint_impl: public local_server_endpoint_base_impl {
public:
- local_server_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _local, boost::asio::io_service &_io);
- virtual ~local_server_endpoint_impl();
+ local_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io);
+ virtual ~local_server_endpoint_impl();
+
+ void start();
+ void stop();
- void start();
- void stop();
+ void restart();
+ void receive();
- void restart();
- void receive();
+ bool send_to(const std::shared_ptr<endpoint_definition>,
+ const byte_t *_data, uint32_t _size, bool _flush);
+ void send_queued(endpoint_type _target, message_buffer_ptr_t _data);
- bool send_to(const std::shared_ptr<endpoint_definition>,
- const byte_t *_data, uint32_t _size, bool _flush);
- void send_queued(endpoint_type _target, message_buffer_ptr_t _data);
+ endpoint_type get_remote() const;
+ bool get_multicast(service_t, event_t, endpoint_type &) const;
- endpoint_type get_remote() const;
- bool get_multicast(service_t, event_t, endpoint_type &) const;
+ bool is_local() const;
private:
- class connection
- : public boost::enable_shared_from_this< connection > {
+ class connection: public boost::enable_shared_from_this<connection> {
+
+ public:
+ typedef boost::shared_ptr<connection> ptr;
- public:
- typedef boost::shared_ptr< connection > ptr;
+ static ptr create(local_server_endpoint_impl *_server);
+ socket_type & get_socket();
- static ptr create(local_server_endpoint_impl *_server);
- socket_type & get_socket();
+ void start();
- void start();
+ void send_queued(message_buffer_ptr_t _data);
- void send_queued(message_buffer_ptr_t _data);
+ private:
+ connection(local_server_endpoint_impl *_owner);
- private:
- connection(local_server_endpoint_impl *_owner);
+ void send_magic_cookie();
- void send_magic_cookie();
+ local_server_endpoint_impl::socket_type socket_;
+ local_server_endpoint_impl *server_;
- local_server_endpoint_impl::socket_type socket_;
- local_server_endpoint_impl *server_;
+ // the current message
+ message_buffer_t message_;
- // the current message
- message_buffer_t message_;
+ private:
+ void receive_cbk(packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error,
+ std::size_t _bytes);
+ };
- private:
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes);
- };
+#ifdef WIN32
+ boost::asio::ip::tcp::acceptor acceptor_;
+#else
+ boost::asio::local::stream_protocol::acceptor acceptor_;
+#endif
- boost::asio::local::stream_protocol::acceptor acceptor_;
- std::map< endpoint_type, connection::ptr > connections_;
- connection *current_;
+ std::map<endpoint_type, connection::ptr> connections_;
+ connection *current_;
private:
- void remove_connection(connection *_connection);
- void accept_cbk(connection::ptr _connection, boost::system::error_code const &_error);
+ void remove_connection(connection *_connection);
+ void accept_cbk(connection::ptr _connection,
+ boost::system::error_code const &_error);
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/server_endpoint_impl.hpp b/implementation/endpoints/include/server_endpoint_impl.hpp
index 6d4b676..eca9c5a 100644
--- a/implementation/endpoints/include/server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/server_endpoint_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -22,49 +21,51 @@
namespace vsomeip {
template<typename Protocol, int MaxBufferSize>
-class server_endpoint_impl : public endpoint_impl<MaxBufferSize>,
- public std::enable_shared_from_this<
- server_endpoint_impl<Protocol, MaxBufferSize> > {
- public:
- typedef typename Protocol::socket socket_type;
- typedef typename Protocol::endpoint endpoint_type;
- typedef boost::array<uint8_t, MaxBufferSize> buffer_type;
+class server_endpoint_impl: public endpoint_impl<MaxBufferSize>,
+ public std::enable_shared_from_this<
+ server_endpoint_impl<Protocol, MaxBufferSize> > {
+public:
+ typedef typename Protocol::socket socket_type;
+ typedef typename Protocol::endpoint endpoint_type;
+ typedef boost::array<uint8_t, MaxBufferSize> buffer_type;
- server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
- endpoint_type _local, boost::asio::io_service &_io);
+ server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local, boost::asio::io_service &_io);
- bool is_client() const;
- bool is_connected() const;
+ bool is_client() const;
+ bool is_connected() const;
- bool send(const uint8_t *_data, uint32_t _size, bool _flush);
- bool flush(endpoint_type _target);
+ bool send(const uint8_t *_data, uint32_t _size, bool _flush);
+ bool flush(endpoint_type _target);
- public:
- void connect_cbk(boost::system::error_code const &_error);
- void send_cbk(message_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes);
- void flush_cbk(endpoint_type _target,
- const boost::system::error_code &_error);
+public:
+ void connect_cbk(boost::system::error_code const &_error);
+ void send_cbk(message_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes);
+ void flush_cbk(endpoint_type _target,
+ const boost::system::error_code &_error);
- public:
- virtual bool send_intern(endpoint_type _target, const byte_t *_data, uint32_t _port, bool _flush);
- virtual void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) = 0;
+public:
+ virtual bool send_intern(endpoint_type _target, const byte_t *_data,
+ uint32_t _port, bool _flush);
+ virtual void send_queued(endpoint_type _target,
+ message_buffer_ptr_t _buffer) = 0;
- virtual endpoint_type get_remote() const = 0;
- virtual bool get_multicast(service_t _service, event_t _event,
- endpoint_type &_target) const = 0;
+ virtual endpoint_type get_remote() const = 0;
+ virtual bool get_multicast(service_t _service, event_t _event,
+ endpoint_type &_target) const = 0;
- protected:
- std::map<endpoint_type, message_buffer_ptr_t> packetizer_;
- std::map<client_t, std::map<session_t, endpoint_type> > clients_;
+protected:
+ std::map<endpoint_type, message_buffer_ptr_t> packetizer_;
+ std::map<client_t, std::map<session_t, endpoint_type> > clients_;
- boost::asio::system_timer flush_timer_;
+ boost::asio::system_timer flush_timer_;
- endpoint_type local_;
+ endpoint_type local_;
- std::mutex mutex_;
+ std::mutex mutex_;
};
-} // namespace vsomeip
+} // namespace vsomeip
#endif // VSOMEIP_SERVICE_ENDPOINT_IMPL_HPP
diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
index dc3f63d..3bb7f26 100644
--- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,31 +13,35 @@
namespace vsomeip {
-typedef client_endpoint_impl<
- boost::asio::ip::tcp,
- VSOMEIP_MAX_TCP_MESSAGE_SIZE > tcp_client_endpoint_base_impl;
+typedef client_endpoint_impl<boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE> tcp_client_endpoint_base_impl;
-class tcp_client_endpoint_impl
- : public tcp_client_endpoint_base_impl {
+class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl {
public:
- tcp_client_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _local, boost::asio::io_service &_io);
- virtual ~tcp_client_endpoint_impl();
+ tcp_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io);
+ virtual ~tcp_client_endpoint_impl();
- void start();
- void send_queued(message_buffer_ptr_t _buffer);
+ void start();
+ void send_queued(message_buffer_ptr_t _buffer);
- unsigned short get_port() const;
- bool is_reliable() const;
+ bool get_remote_address(boost::asio::ip::address &_address) const;
+ unsigned short get_local_port() const;
+ unsigned short get_remote_port() const;
+ bool is_reliable() const;
+ bool is_local() const;
private:
- bool is_magic_cookie() const;
- void send_magic_cookie(message_buffer_ptr_t &_buffer);
+ bool is_magic_cookie() const;
+ void send_magic_cookie(message_buffer_ptr_t &_buffer);
- void receive_cbk(packet_buffer_ptr_t _buffer, boost::system::error_code const &_error, std::size_t _bytes);
+ void receive_cbk(packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error,
+ std::size_t _bytes);
- void connect();
- void receive();
+ void connect();
+ void receive();
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
index 0aea5d8..10d52e6 100644
--- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,72 +16,77 @@
namespace vsomeip {
-typedef server_endpoint_impl<
- boost::asio::ip::tcp,
- VSOMEIP_MAX_TCP_MESSAGE_SIZE > tcp_server_endpoint_base_impl;
+typedef server_endpoint_impl<boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE> tcp_server_endpoint_base_impl;
-class tcp_server_endpoint_impl
- : public tcp_server_endpoint_base_impl {
+class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl {
public:
- tcp_server_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _local, boost::asio::io_service &_io);
- virtual ~tcp_server_endpoint_impl();
+ tcp_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io);
+ virtual ~tcp_server_endpoint_impl();
- void start();
- void stop();
+ void start();
+ void stop();
- bool send_to(const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush);
- void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
+ bool send_to(const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush);
+ void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
- endpoint_type get_remote() const;
- bool get_multicast(service_t, event_t, endpoint_type &) const;
+ endpoint_type get_remote() const;
+ bool get_multicast(service_t, event_t, endpoint_type &) const;
- unsigned short get_port() const;
- bool is_reliable() const;
+ unsigned short get_local_port() const;
+ bool is_reliable() const;
+ bool is_local() const;
- // dummies to implement endpoint_impl interface
- // TODO: think about a better design!
- void receive();
- void restart();
+ client_t get_client(std::shared_ptr<endpoint_definition> _endpoint);
+
+ // dummies to implement endpoint_impl interface
+ // TODO: think about a better design!
+ void receive();
+ void restart();
private:
- class connection
- : public boost::enable_shared_from_this< connection > {
+ class connection: public boost::enable_shared_from_this<connection> {
+
+ public:
+ typedef boost::shared_ptr<connection> ptr;
- public:
- typedef boost::shared_ptr< connection > ptr;
+ static ptr create(tcp_server_endpoint_impl *_server);
+ socket_type & get_socket();
- static ptr create(tcp_server_endpoint_impl *_server);
- socket_type & get_socket();
+ void start();
+ void stop();
- void start();
- void stop();
+ client_t get_client(endpoint_type _endpoint_type);
- void send_queued(message_buffer_ptr_t _buffer);
+ void send_queued(message_buffer_ptr_t _buffer);
- private:
- connection(tcp_server_endpoint_impl *_owner);
- void send_magic_cookie(message_buffer_ptr_t &_buffer);
+ private:
+ connection(tcp_server_endpoint_impl *_owner);
+ void send_magic_cookie(message_buffer_ptr_t &_buffer);
- tcp_server_endpoint_impl::socket_type socket_;
- tcp_server_endpoint_impl *server_;
+ tcp_server_endpoint_impl::socket_type socket_;
+ tcp_server_endpoint_impl *server_;
- message_buffer_t message_;
+ message_buffer_t message_;
- private:
- bool is_magic_cookie() const;
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes);
- };
+ private:
+ bool is_magic_cookie() const;
+ void receive_cbk(packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error,
+ std::size_t _bytes);
+ };
- boost::asio::ip::tcp::acceptor acceptor_;
- std::map< endpoint_type, connection::ptr > connections_;
- connection *current_;
+ boost::asio::ip::tcp::acceptor acceptor_;
+ std::map<endpoint_type, connection::ptr> connections_;
+ connection *current_;
private:
- void accept_cbk(connection::ptr _connection, boost::system::error_code const &_error);
+ void accept_cbk(connection::ptr _connection,
+ boost::system::error_code const &_error);
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp
index e0e348c..0b20600 100644
--- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp
@@ -1,13 +1,7 @@
-//
-// udp_client_impl.hpp
-//
-// Author: Lutz Bichler
-//
-// This file is part of the BMW Some/IP implementation.
-//
-// Copyright �� 2013, 2024 Bayerische Motoren Werke AG (BMW).
-// All rights reserved.
-//
+// Copyright (C) 2014-2015 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_INTERNAL_UDP_CLIENT_IMPL_HPP
#define VSOMEIP_INTERNAL_UDP_CLIENT_IMPL_HPP
@@ -25,32 +19,35 @@ namespace vsomeip {
class endpoint_adapter;
-typedef client_endpoint_impl<
- boost::asio::ip::udp,
- VSOMEIP_MAX_UDP_MESSAGE_SIZE > udp_client_endpoint_base_impl;
+typedef client_endpoint_impl<boost::asio::ip::udp,
+ VSOMEIP_MAX_UDP_MESSAGE_SIZE> udp_client_endpoint_base_impl;
-class udp_client_endpoint_impl
- : virtual public udp_client_endpoint_base_impl {
+class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl {
public:
- udp_client_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _remote, boost::asio::io_service &_io);
- virtual ~udp_client_endpoint_impl();
-
- void start();
- void send_queued(message_buffer_ptr_t _buffer);
-
- unsigned short get_port() const;
-
- void join(const std::string &_address);
- void leave(const std::string &_address);
-
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes);
+ udp_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _remote,
+ boost::asio::io_service &_io);
+ virtual ~udp_client_endpoint_impl();
+
+ void start();
+ void send_queued(message_buffer_ptr_t _buffer);
+
+ void join(const std::string &_address);
+ void leave(const std::string &_address);
+
+ void receive_cbk(packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error,
+ std::size_t _bytes);
+
+ bool get_remote_address(boost::asio::ip::address &_address) const;
+ unsigned short get_local_port() const;
+ unsigned short get_remote_port() const;
+ bool is_local() const;
private:
- void connect();
- void receive();
+ void connect();
+ void receive();
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
index 8e843b9..4c7beaf 100644
--- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
@@ -1,13 +1,7 @@
-//
-// udp_service_impl.hpp
-//
-// Author: Lutz Bichler
-//
-// This file is part of the BMW Some/IP implementation.
-//
-// Copyright 2013, 2024 Bayerische Motoren Werke AG (BMW).
-// All rights reserved.
-//
+// Copyright (C) 2014-2015 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_INTERNAL_UDP_SERVICE_IMPL_HPP
#define VSOMEIP_INTERNAL_UDP_SERVICE_IMPL_HPP
@@ -20,51 +14,55 @@
namespace vsomeip {
-typedef server_endpoint_impl<
- boost::asio::ip::udp,
- VSOMEIP_MAX_UDP_MESSAGE_SIZE > udp_server_endpoint_base_impl;
+typedef server_endpoint_impl<boost::asio::ip::udp,
+ VSOMEIP_MAX_UDP_MESSAGE_SIZE> udp_server_endpoint_base_impl;
-class udp_server_endpoint_impl
- : public udp_server_endpoint_base_impl {
+class udp_server_endpoint_impl: public udp_server_endpoint_base_impl {
public:
- udp_server_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _local, boost::asio::io_service &_io);
- virtual ~udp_server_endpoint_impl();
+ udp_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io);
+ virtual ~udp_server_endpoint_impl();
- void start();
- void stop();
+ void start();
+ void stop();
- void restart();
- void receive();
+ void restart();
+ void receive();
- bool send_to(const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush);
- void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
+ bool send_to(const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush);
+ void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
- endpoint_type get_remote() const;
- bool get_multicast(service_t _service, event_t _event, endpoint_type &_target) const;
+ endpoint_type get_remote() const;
+ bool get_multicast(service_t _service, event_t _event,
+ endpoint_type &_target) const;
- void join(const std::string &_address);
- void leave(const std::string &_address);
- void add_multicast(service_t _service, instance_t _instance,
- const std::string &_address, uint16_t _port);
- void remove_multicast(service_t _service, instance_t _instance);
+ void join(const std::string &_address);
+ void leave(const std::string &_address);
+ void add_multicast(service_t _service, instance_t _instance,
+ const std::string &_address, uint16_t _port);
+ void remove_multicast(service_t _service, instance_t _instance);
- unsigned short get_port() const;
+ unsigned short get_local_port() const;
+ bool is_local() const;
+
+ client_t get_client(std::shared_ptr<endpoint_definition> _endpoint);
public:
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _size);
+ void receive_cbk(packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error,
+ std::size_t _size);
private:
- void set_broadcast();
+ void set_broadcast();
private:
- socket_type socket_;
- endpoint_type remote_;
- std::map<service_t, std::map<instance_t, endpoint_type> > multicasts_;
- message_buffer_t message_;
+ socket_type socket_;
+ endpoint_type remote_;
+ std::map<service_t, std::map<instance_t, endpoint_type> > multicasts_;
+ message_buffer_t message_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp
index 77bd7d7..5c2e399 100644
--- a/implementation/endpoints/src/client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/client_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,16 +24,13 @@ namespace vsomeip {
template<typename Protocol, int MaxBufferSize>
client_endpoint_impl<Protocol, MaxBufferSize>::client_endpoint_impl(
- std::shared_ptr<endpoint_host> _host, endpoint_type _remote,
- boost::asio::io_service &_io)
- : endpoint_impl<MaxBufferSize>(_host, _io),
- socket_(_io),
- connect_timer_(_io),
- flush_timer_(_io),
- remote_(_remote),
- packetizer_(std::make_shared<message_buffer_t>()),
- connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable
- is_connected_(false) {
+ std::shared_ptr<endpoint_host> _host, endpoint_type _remote,
+ boost::asio::io_service &_io)
+ : endpoint_impl<MaxBufferSize>(_host, _io), socket_(_io),
+ connect_timer_(_io), flush_timer_(_io), remote_(_remote),
+ packetizer_(std::make_shared<message_buffer_t>()),
+ connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable
+ is_connected_(false) {
}
template<typename Protocol, int MaxBufferSize>
@@ -43,157 +39,164 @@ client_endpoint_impl<Protocol, MaxBufferSize>::~client_endpoint_impl() {
template<typename Protocol, int MaxBufferSize>
bool client_endpoint_impl<Protocol, MaxBufferSize>::is_client() const {
- return true;
+ return true;
}
template<typename Protocol, int MaxBufferSize>
bool client_endpoint_impl<Protocol, MaxBufferSize>::is_connected() const {
- return is_connected_;
+ return is_connected_;
}
template<typename Protocol, int MaxBufferSize>
void client_endpoint_impl<Protocol, MaxBufferSize>::stop() {
- if (socket_.is_open()) {
- socket_.close();
- }
+ if (socket_.is_open()) {
+ socket_.close();
+ }
}
template<typename Protocol, int MaxBufferSize>
void client_endpoint_impl<Protocol, MaxBufferSize>::restart() {
- receive();
+ receive();
}
template<typename Protocol, int MaxBufferSize>
bool client_endpoint_impl<Protocol, MaxBufferSize>::send_to(
- const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush) {
- VSOMEIP_ERROR
- << "Clients endpoints must not be used to send to explicitely specified targets";
- return false;
+ const std::shared_ptr<endpoint_definition> _target, const byte_t *_data,
+ uint32_t _size, bool _flush) {
+ VSOMEIP_ERROR<< "Clients endpoints must not be used to "
+ << "send to explicitely specified targets";
+ return false;
}
template<typename Protocol, int MaxBufferSize>
bool client_endpoint_impl<Protocol, MaxBufferSize>::send(const uint8_t *_data,
- uint32_t _size,
- bool _flush) {
- std::lock_guard<std::mutex> its_lock(mutex_);
+ uint32_t _size, bool _flush) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
#if 0
- std::stringstream msg;
- msg << "cei::send: ";
- for (uint32_t i = 0; i < _size; i++)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "cei::send: ";
+ for (uint32_t i = 0; i < _size; i++)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (packetizer_->size() + _size > MaxBufferSize) {
- send_queued(packetizer_);
- packetizer_ = std::make_shared<message_buffer_t>();
- }
-
- packetizer_->insert(packetizer_->end(), _data, _data + _size);
-
- if (_flush) {
- flush_timer_.cancel();
- send_queued(packetizer_);
- packetizer_ = std::make_shared<message_buffer_t>();
- } else {
- flush_timer_.expires_from_now(
- std::chrono::milliseconds(VSOMEIP_DEFAULT_FLUSH_TIMEOUT)); // TODO: use config variable
- flush_timer_.async_wait(
- std::bind(&client_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
- this->shared_from_this(), std::placeholders::_1));
- }
-
- return (true);
+ if (packetizer_->size() + _size > MaxBufferSize) {
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared<message_buffer_t>();
+ }
+
+ packetizer_->insert(packetizer_->end(), _data, _data + _size);
+
+ if (_flush) {
+ flush_timer_.cancel();
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared<message_buffer_t>();
+ } else {
+ flush_timer_.expires_from_now(
+ std::chrono::milliseconds(VSOMEIP_DEFAULT_FLUSH_TIMEOUT)); // TODO: use config variable
+ flush_timer_.async_wait(
+ std::bind(
+ &client_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
+ this->shared_from_this(), std::placeholders::_1));
+ }
+
+ return (true);
}
template<typename Protocol, int MaxBufferSize>
bool client_endpoint_impl<Protocol, MaxBufferSize>::flush() {
- bool is_successful(true);
+ bool is_successful(true);
- if (!packetizer_->empty()) {
- send_queued(packetizer_);
- packetizer_ = std::make_shared<message_buffer_t>();
- } else {
- is_successful = false;
- }
+ if (!packetizer_->empty()) {
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared<message_buffer_t>();
+ } else {
+ is_successful = false;
+ }
- return is_successful;
+ return is_successful;
}
template<typename Protocol, int MaxBufferSize>
void client_endpoint_impl<Protocol, MaxBufferSize>::connect_cbk(
- boost::system::error_code const &_error) {
- if (_error) {
- socket_.close();
-
- connect_timer_.expires_from_now(
- std::chrono::milliseconds(connect_timeout_));
- connect_timer_.async_wait(
- std::bind(
- &client_endpoint_impl<Protocol, MaxBufferSize>::wait_connect_cbk,
- this->shared_from_this(), std::placeholders::_1));
-
- // next time we wait longer
- connect_timeout_ <<= 1;
-
- if (is_connected_) {
- is_connected_ = false;
- this->host_->on_disconnect(this->shared_from_this());
+ boost::system::error_code const &_error) {
+ std::shared_ptr<endpoint_host> its_host = this->host_.lock();
+ if (its_host) {
+ if (_error) {
+ socket_.close();
+
+ connect_timer_.expires_from_now(
+ std::chrono::milliseconds(connect_timeout_));
+ connect_timer_.async_wait(
+ std::bind(&client_endpoint_impl<
+ Protocol, MaxBufferSize>::wait_connect_cbk,
+ this->shared_from_this(), std::placeholders::_1));
+
+ // next time we wait longer
+ connect_timeout_ <<= 1;
+
+ if (is_connected_) {
+ is_connected_ = false;
+ its_host->on_disconnect(this->shared_from_this());
+ }
+ } else {
+ connect_timer_.cancel();
+ connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; // TODO: use config variable
+
+ if (!is_connected_) {
+ is_connected_ = true;
+ its_host->on_connect(this->shared_from_this());
+ }
+
+ receive();
+ }
}
- } else {
- connect_timer_.cancel();
- connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; // TODO: use config variable
-
- if (!is_connected_) {
- is_connected_ = true;
- this->host_->on_connect(this->shared_from_this());
- }
-
- receive();
- }
}
template<typename Protocol, int MaxBufferSize>
void client_endpoint_impl<Protocol, MaxBufferSize>::wait_connect_cbk(
- boost::system::error_code const &_error) {
- if (!_error) {
- connect();
- }
+ boost::system::error_code const &_error) {
+ if (!_error) {
+ connect();
+ }
}
template<typename Protocol, int MaxBufferSize>
void client_endpoint_impl<Protocol, MaxBufferSize>::send_cbk(
- message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
- std::size_t _bytes) {
+ message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
+ std::size_t _bytes) {
#if 0
- std::stringstream msg;
- msg << "cei<" << this << ">::scb (" << _error.message() << "): ";
- for (std::size_t i = 0; i < _data->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "cei<" << this << ">::scb (" << _error.message() << "): ";
+ for (std::size_t i = 0; i < _data->size(); ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (_error == boost::asio::error::broken_pipe) {
- is_connected_ = false;
- socket_.close();
- connect();
- }
+ if (_error == boost::asio::error::broken_pipe) {
+ is_connected_ = false;
+ socket_.close();
+ connect();
+ }
}
template<typename Protocol, int MaxBufferSize>
void client_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk(
- boost::system::error_code const &_error) {
- if (!_error) {
- (void) flush();
- }
+ boost::system::error_code const &_error) {
+ if (!_error) {
+ (void) flush();
+ }
}
// Instantiate template
+#ifndef WIN32
template class client_endpoint_impl<boost::asio::local::stream_protocol,
- VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
+VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
+#endif
template class client_endpoint_impl<boost::asio::ip::tcp,
- VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
+VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
template class client_endpoint_impl<boost::asio::ip::udp,
- VSOMEIP_MAX_UDP_MESSAGE_SIZE> ;
+VSOMEIP_MAX_UDP_MESSAGE_SIZE> ;
} // namespace vsomeip
diff --git a/implementation/endpoints/src/endpoint_definition.cpp b/implementation/endpoints/src/endpoint_definition.cpp
index 6a824c0..9a4caea 100644
--- a/implementation/endpoints/src/endpoint_definition.cpp
+++ b/implementation/endpoints/src/endpoint_definition.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -10,37 +9,48 @@
namespace vsomeip {
-endpoint_definition::endpoint_definition() :
- port_(ILLEGAL_PORT) {
+endpoint_definition::endpoint_definition()
+ : port_(ILLEGAL_PORT) {
}
endpoint_definition::endpoint_definition(
- const boost::asio::ip::address &_address, uint16_t _port, bool _is_reliable) :
- address_(_address), port_(_port), is_reliable_(_is_reliable) {
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _is_reliable)
+ : address_(_address), port_(_port), is_reliable_(_is_reliable), remote_port_(_port) {
}
const boost::asio::ip::address & endpoint_definition::get_address() const {
- return address_;
+ return address_;
}
-void endpoint_definition::set_address(const boost::asio::ip::address &_address) {
- address_ = _address;
+void endpoint_definition::set_address(
+ const boost::asio::ip::address &_address) {
+ address_ = _address;
}
uint16_t endpoint_definition::get_port() const {
- return port_;
+ return port_;
}
void endpoint_definition::set_port(uint16_t _port) {
- port_ = _port;
+ port_ = _port;
}
bool endpoint_definition::is_reliable() const {
- return is_reliable_;
+ return is_reliable_;
}
void endpoint_definition::set_reliable(bool _is_reliable) {
- is_reliable_ = _is_reliable;
+ is_reliable_ = _is_reliable;
}
+uint16_t endpoint_definition::get_remote_port() const {
+ return remote_port_;
+}
+
+void endpoint_definition::set_remote_port(uint16_t _port) {
+ remote_port_ = _port;
+}
+
+
} // namespace vsomeip
diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp
index 63c2c18..e7ffffa 100644
--- a/implementation/endpoints/src/endpoint_impl.cpp
+++ b/implementation/endpoints/src/endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,111 +12,119 @@
namespace vsomeip {
-template < int MaxBufferSize >
-endpoint_impl< MaxBufferSize >::endpoint_impl(
- std::shared_ptr< endpoint_host > _host, boost::asio::io_service &_io)
- : host_(_host.get()),
- service_(_io),
- is_supporting_magic_cookies_(false),
- has_enabled_magic_cookies_(false) {
+template<int MaxBufferSize>
+endpoint_impl<MaxBufferSize>::endpoint_impl(
+ std::shared_ptr<endpoint_host> _host, boost::asio::io_service &_io)
+ : host_(_host),
+ service_(_io),
+ is_supporting_magic_cookies_(false),
+ has_enabled_magic_cookies_(false) {
}
-template < int MaxBufferSize >
-endpoint_impl< MaxBufferSize >::~endpoint_impl() {
+template<int MaxBufferSize>
+endpoint_impl<MaxBufferSize>::~endpoint_impl() {
}
-template < int MaxBufferSize >
-void endpoint_impl< MaxBufferSize >::enable_magic_cookies() {
- has_enabled_magic_cookies_ = is_supporting_magic_cookies_;
+template<int MaxBufferSize>
+void endpoint_impl<MaxBufferSize>::enable_magic_cookies() {
+ has_enabled_magic_cookies_ = is_supporting_magic_cookies_;
}
-template < int MaxBufferSize >
-bool endpoint_impl< MaxBufferSize >::is_magic_cookie() const {
- return false;
+template<int MaxBufferSize>
+bool endpoint_impl<MaxBufferSize>::is_magic_cookie() const {
+ return false;
}
-template < int MaxBufferSize >
-uint32_t endpoint_impl< MaxBufferSize >::find_magic_cookie(message_buffer_t &_buffer) {
- bool is_found(false);
- uint32_t its_offset = 0xFFFFFFFF;
- if (has_enabled_magic_cookies_) {
- uint8_t its_cookie_identifier, its_cookie_type;
-
- if (is_client()) {
- its_cookie_identifier
- = static_cast< uint8_t >(MAGIC_COOKIE_SERVICE_MESSAGE);
- its_cookie_type
- = static_cast< uint8_t >(MAGIC_COOKIE_SERVICE_MESSAGE_TYPE);
- } else {
- its_cookie_identifier
- = static_cast< uint8_t >(MAGIC_COOKIE_CLIENT_MESSAGE);
- its_cookie_type
- = static_cast< uint8_t >(MAGIC_COOKIE_CLIENT_MESSAGE_TYPE);
- }
-
- do {
- its_offset++; // --> first loop has "its_offset = 0"
- if (_buffer.size() > its_offset + 16) {
- is_found = (
- _buffer[its_offset] == 0xFF &&
- _buffer[its_offset+1] == 0xFF &&
- _buffer[its_offset+2] == its_cookie_identifier &&
- _buffer[its_offset+3] == 0x00 &&
- _buffer[its_offset+4] == 0x00 &&
- _buffer[its_offset+5] == 0x00 &&
- _buffer[its_offset+6] == 0x00 &&
- _buffer[its_offset+7] == 0x08 &&
- _buffer[its_offset+8] == 0xDE &&
- _buffer[its_offset+9] == 0xAD &&
- _buffer[its_offset+10] == 0xBE &&
- _buffer[its_offset+11] == 0xEF &&
- _buffer[its_offset+12] == 0x01 &&
- _buffer[its_offset+13] == 0x01 &&
- _buffer[its_offset+14] == its_cookie_type &&
- _buffer[its_offset+15] == 0x00
- );
- } else {
- break;
- }
-
- } while (!is_found);
- }
-
- return (is_found ? its_offset : 0xFFFFFFFF);
+template<int MaxBufferSize>
+uint32_t endpoint_impl<MaxBufferSize>::find_magic_cookie(
+ message_buffer_t &_buffer) {
+ bool is_found(false);
+ uint32_t its_offset = 0xFFFFFFFF;
+ if (has_enabled_magic_cookies_) {
+ uint8_t its_cookie_identifier, its_cookie_type;
+
+ if (is_client()) {
+ its_cookie_identifier =
+ static_cast<uint8_t>(MAGIC_COOKIE_SERVICE_MESSAGE);
+ its_cookie_type =
+ static_cast<uint8_t>(MAGIC_COOKIE_SERVICE_MESSAGE_TYPE);
+ } else {
+ its_cookie_identifier =
+ static_cast<uint8_t>(MAGIC_COOKIE_CLIENT_MESSAGE);
+ its_cookie_type =
+ static_cast<uint8_t>(MAGIC_COOKIE_CLIENT_MESSAGE_TYPE);
+ }
+
+ do {
+ its_offset++; // --> first loop has "its_offset = 0"
+ if (_buffer.size() > its_offset + 16) {
+ is_found = (_buffer[its_offset] == 0xFF
+ && _buffer[its_offset + 1] == 0xFF
+ && _buffer[its_offset + 2] == its_cookie_identifier
+ && _buffer[its_offset + 3] == 0x00
+ && _buffer[its_offset + 4] == 0x00
+ && _buffer[its_offset + 5] == 0x00
+ && _buffer[its_offset + 6] == 0x00
+ && _buffer[its_offset + 7] == 0x08
+ && _buffer[its_offset + 8] == 0xDE
+ && _buffer[its_offset + 9] == 0xAD
+ && _buffer[its_offset + 10] == 0xBE
+ && _buffer[its_offset + 11] == 0xEF
+ && _buffer[its_offset + 12] == 0x01
+ && _buffer[its_offset + 13] == 0x01
+ && _buffer[its_offset + 14] == its_cookie_type
+ && _buffer[its_offset + 15] == 0x00);
+ } else {
+ break;
+ }
+
+ } while (!is_found);
+ }
+
+ return (is_found ? its_offset : 0xFFFFFFFF);
}
-template < int MaxBufferSize >
-void endpoint_impl< MaxBufferSize >::join(const std::string &) {
+template<int MaxBufferSize>
+void endpoint_impl<MaxBufferSize>::join(const std::string &) {
}
-template < int MaxBufferSize >
-void endpoint_impl< MaxBufferSize >::leave(const std::string &) {
+template<int MaxBufferSize>
+void endpoint_impl<MaxBufferSize>::leave(const std::string &) {
}
-template < int MaxBufferSize >
-void endpoint_impl< MaxBufferSize >::add_multicast(
- service_t, event_t, const std::string &, uint16_t) {
+template<int MaxBufferSize>
+void endpoint_impl<MaxBufferSize>::add_multicast(
+ service_t, event_t, const std::string &, uint16_t) {
}
-template < int MaxBufferSize >
-void endpoint_impl< MaxBufferSize >::remove_multicast(service_t, event_t) {
+template<int MaxBufferSize>
+void endpoint_impl<MaxBufferSize>::remove_multicast(service_t, event_t) {
}
-template < int MaxBufferSize >
-unsigned short endpoint_impl< MaxBufferSize >::get_port() const {
- return 0;
+template<int MaxBufferSize>
+bool endpoint_impl<MaxBufferSize>::get_remote_address(
+ boost::asio::ip::address &_address) const {
+ return false;
}
-template < int MaxBufferSize >
-bool endpoint_impl< MaxBufferSize >::is_reliable() const {
- return false;
+template<int MaxBufferSize>
+unsigned short endpoint_impl<MaxBufferSize>::get_local_port() const {
+ return 0;
}
-// Instantiate template
-template class endpoint_impl< VSOMEIP_MAX_LOCAL_MESSAGE_SIZE >;
-template class endpoint_impl< VSOMEIP_MAX_TCP_MESSAGE_SIZE >;
-template class endpoint_impl< VSOMEIP_MAX_UDP_MESSAGE_SIZE >;
+template<int MaxBufferSize>
+unsigned short endpoint_impl<MaxBufferSize>::get_remote_port() const {
+ return 0;
+}
-} // namespace vsomeip
+template<int MaxBufferSize>
+bool endpoint_impl<MaxBufferSize>::is_reliable() const {
+ return false;
+}
+// Instantiate template
+template class endpoint_impl< VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
+template class endpoint_impl< VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
+template class endpoint_impl< VSOMEIP_MAX_UDP_MESSAGE_SIZE> ;
+} // namespace vsomeip
diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp
index 9740104..b465baa 100644
--- a/implementation/endpoints/src/local_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -18,107 +17,124 @@
namespace vsomeip {
local_client_endpoint_impl::local_client_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _remote, boost::asio::io_service &_io)
- : local_client_endpoint_base_impl(_host, _remote, _io) {
- is_supporting_magic_cookies_ = false;
+ std::shared_ptr< endpoint_host > _host, endpoint_type _remote,
+ boost::asio::io_service &_io)
+ : local_client_endpoint_base_impl(_host, _remote, _io) {
+ is_supporting_magic_cookies_ = false;
+}
+
+local_client_endpoint_impl::~local_client_endpoint_impl() {
+
+}
+
+bool local_client_endpoint_impl::is_local() const {
+ return true;
}
void local_client_endpoint_impl::start() {
- connect();
+ connect();
}
void local_client_endpoint_impl::connect() {
- socket_.open(remote_.protocol());
-
- socket_.async_connect(
- remote_,
- std::bind(
- &local_client_endpoint_base_impl::connect_cbk,
- shared_from_this(),
- std::placeholders::_1
- )
- );
+ socket_.open(remote_.protocol());
+
+ socket_.async_connect(
+ remote_,
+ std::bind(
+ &local_client_endpoint_base_impl::connect_cbk,
+ shared_from_this(),
+ std::placeholders::_1
+ )
+ );
}
void local_client_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive(
- boost::asio::buffer(*its_buffer),
- std::bind(
- &local_client_endpoint_impl::receive_cbk,
- std::dynamic_pointer_cast< local_client_endpoint_impl >(shared_from_this()),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ packet_buffer_ptr_t its_buffer
+ = std::make_shared< packet_buffer_t >();
+ socket_.async_receive(
+ boost::asio::buffer(*its_buffer),
+ std::bind(
+ &local_client_endpoint_impl::receive_cbk,
+ std::dynamic_pointer_cast<
+ local_client_endpoint_impl
+ >(shared_from_this()),
+ its_buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
#if 0
- std::stringstream msg;
- msg << "lce<" << this << ">::sq: ";
- for (std::size_t i = 0; i < _buffer->size(); i++)
- msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "lce<" << this << ">::sq: ";
+ for (std::size_t i = 0; i < _buffer->size(); i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- static byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 };
- static byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 };
-
- boost::asio::async_write(
- socket_,
- boost::asio::buffer(
- its_start_tag,
- sizeof(its_start_tag)
- ),
- std::bind(
- &local_client_endpoint_impl::send_tag_cbk,
- std::dynamic_pointer_cast< local_client_endpoint_impl >(shared_from_this()),
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
-
- boost::asio::async_write(
- socket_,
- boost::asio::buffer(*_buffer),
- std::bind(
- &client_endpoint_impl::send_cbk,
- this->shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
-
- boost::asio::async_write(
- socket_,
- boost::asio::buffer(
- its_end_tag,
- sizeof(its_end_tag)
- ),
- std::bind(
- &local_client_endpoint_impl::send_tag_cbk,
- std::dynamic_pointer_cast< local_client_endpoint_impl >(shared_from_this()),
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ static byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 };
+ static byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 };
+
+ boost::asio::async_write(
+ socket_,
+ boost::asio::buffer(
+ its_start_tag,
+ sizeof(its_start_tag)
+ ),
+ std::bind(
+ &local_client_endpoint_impl::send_tag_cbk,
+ std::dynamic_pointer_cast<
+ local_client_endpoint_impl
+ >(shared_from_this()),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+
+ boost::asio::async_write(
+ socket_,
+ boost::asio::buffer(*_buffer),
+ std::bind(
+ &client_endpoint_impl::send_cbk,
+ this->shared_from_this(),
+ _buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+
+ boost::asio::async_write(
+ socket_,
+ boost::asio::buffer(
+ its_end_tag,
+ sizeof(its_end_tag)
+ ),
+ std::bind(
+ &local_client_endpoint_impl::send_tag_cbk,
+ std::dynamic_pointer_cast<
+ local_client_endpoint_impl
+ >(shared_from_this()),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
void local_client_endpoint_impl::send_magic_cookie() {
}
void local_client_endpoint_impl::send_tag_cbk(
- boost::system::error_code const &_error, std::size_t _bytes) {
+ boost::system::error_code const &_error, std::size_t _bytes) {
}
void local_client_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
- VSOMEIP_ERROR << "Local endpoint received message (" << _error.message() << ")";
+ packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes) {
+ VSOMEIP_ERROR << "Local endpoint received message ("
+ << _error.message() << ")";
}
} // namespace vsomeip
diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_server_endpoint_impl.cpp
index 6926a71..3a237c6 100644
--- a/implementation/endpoints/src/local_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/local_server_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,195 +18,235 @@
namespace vsomeip {
local_server_endpoint_impl::local_server_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io)
- : local_server_endpoint_base_impl(_host, _local, _io),
- acceptor_(_io, _local) {
- is_supporting_magic_cookies_ = false;
+ std::shared_ptr< endpoint_host > _host,
+ endpoint_type _local, boost::asio::io_service &_io)
+ : local_server_endpoint_base_impl(_host, _local, _io),
+ acceptor_(_io, _local) {
+ is_supporting_magic_cookies_ = false;
}
local_server_endpoint_impl::~local_server_endpoint_impl() {
}
+bool local_server_endpoint_impl::is_local() const {
+ return true;
+}
+
void local_server_endpoint_impl::start() {
- connection::ptr new_connection = connection::create(this);
+ connection::ptr new_connection = connection::create(this);
- acceptor_.async_accept(
- new_connection->get_socket(),
- std::bind(
- &local_server_endpoint_impl::accept_cbk,
- std::dynamic_pointer_cast< local_server_endpoint_impl >(shared_from_this()),
- new_connection,
- std::placeholders::_1
- )
- );
+ acceptor_.async_accept(
+ new_connection->get_socket(),
+ std::bind(
+ &local_server_endpoint_impl::accept_cbk,
+ std::dynamic_pointer_cast<
+ local_server_endpoint_impl
+ >(shared_from_this()),
+ new_connection,
+ std::placeholders::_1
+ )
+ );
}
void local_server_endpoint_impl::stop() {
-
}
-bool local_server_endpoint_impl::send_to(const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush) {
+bool local_server_endpoint_impl::send_to(
+ const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush) {
return false;
}
-void local_server_endpoint_impl::send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) {
- auto connection_iterator = connections_.find(_target);
- if (connection_iterator != connections_.end())
- connection_iterator->second->send_queued(_buffer);
+void local_server_endpoint_impl::send_queued(
+ endpoint_type _target, message_buffer_ptr_t _buffer) {
+ auto connection_iterator = connections_.find(_target);
+ if (connection_iterator != connections_.end())
+ connection_iterator->second->send_queued(_buffer);
}
void local_server_endpoint_impl::receive() {
- // intentionally left empty
+ // intentionally left empty
}
void local_server_endpoint_impl::restart() {
- current_->start();
+ current_->start();
}
-local_server_endpoint_impl::endpoint_type local_server_endpoint_impl::get_remote() const {
- return current_->get_socket().remote_endpoint();
+local_server_endpoint_impl::endpoint_type
+local_server_endpoint_impl::get_remote() const {
+ return current_->get_socket().remote_endpoint();
}
bool local_server_endpoint_impl::get_multicast(
- service_t, event_t, local_server_endpoint_impl::endpoint_type &) const {
- return false;
+ service_t, event_t,
+ local_server_endpoint_impl::endpoint_type &) const {
+ return false;
}
-void local_server_endpoint_impl::remove_connection(local_server_endpoint_impl::connection *_connection) {
- std::map< endpoint_type, connection::ptr >::iterator i = connections_.end();
- for (i = connections_.begin(); i != connections_.end(); i++) {
- if (i->second.get() == _connection)
- break;
- }
+void local_server_endpoint_impl::remove_connection(
+ local_server_endpoint_impl::connection *_connection) {
+ std::map< endpoint_type, connection::ptr >::iterator i
+ = connections_.end();
+ for (i = connections_.begin(); i != connections_.end(); i++) {
+ if (i->second.get() == _connection)
+ break;
+ }
- if (i != connections_.end()) {
- connections_.erase(i);
- }
+ if (i != connections_.end()) {
+ connections_.erase(i);
+ }
}
void local_server_endpoint_impl::accept_cbk(
- connection::ptr _connection, boost::system::error_code const &_error) {
+ connection::ptr _connection, boost::system::error_code const &_error) {
- if (!_error) {
- socket_type &new_connection_socket = _connection->get_socket();
- endpoint_type remote = new_connection_socket.remote_endpoint();
+ if (!_error) {
+ socket_type &new_connection_socket = _connection->get_socket();
+ endpoint_type remote = new_connection_socket.remote_endpoint();
- connections_[remote] = _connection;
- _connection->start();
- }
+ connections_[remote] = _connection;
+ _connection->start();
+ }
- start();
+ start();
}
///////////////////////////////////////////////////////////////////////////////
-// class tcp_service_impl::connection
+// class local_service_impl::connection
///////////////////////////////////////////////////////////////////////////////
-local_server_endpoint_impl::connection::connection(local_server_endpoint_impl *_server)
- : socket_(_server->service_), server_(_server) {
+local_server_endpoint_impl::connection::connection(
+ local_server_endpoint_impl *_server)
+ : socket_(_server->service_), server_(_server) {
}
local_server_endpoint_impl::connection::ptr
-local_server_endpoint_impl::connection::create(local_server_endpoint_impl *_server) {
- return ptr(new connection(_server));
+local_server_endpoint_impl::connection::create(
+ local_server_endpoint_impl *_server) {
+ return ptr(new connection(_server));
}
-local_server_endpoint_impl::socket_type & local_server_endpoint_impl::connection::get_socket() {
- return socket_;
+local_server_endpoint_impl::socket_type &
+local_server_endpoint_impl::connection::get_socket() {
+ return socket_;
}
void local_server_endpoint_impl::connection::start() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive(
- boost::asio::buffer(*its_buffer),
- std::bind(
- &local_server_endpoint_impl::connection::receive_cbk,
- shared_from_this(),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
-}
-
-void local_server_endpoint_impl::connection::send_queued(message_buffer_ptr_t _buffer) {
+ packet_buffer_ptr_t its_buffer
+ = std::make_shared< packet_buffer_t >();
+ socket_.async_receive(
+ boost::asio::buffer(*its_buffer),
+ std::bind(
+ &local_server_endpoint_impl::connection::receive_cbk,
+ shared_from_this(),
+ its_buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+}
+
+void local_server_endpoint_impl::connection::send_queued(
+ message_buffer_ptr_t _buffer) {
#if 0
- std::stringstream msg;
- msg << "lse::sq: ";
- for (std::size_t i = 0; i < _buffer->size(); i++)
- msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "lse::sq: ";
+ for (std::size_t i = 0; i < _buffer->size(); i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- boost::asio::async_write(
- socket_,
- boost::asio::buffer(*_buffer),
- std::bind(
- &local_server_endpoint_base_impl::send_cbk,
- server_->shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ boost::asio::async_write(
+ socket_,
+ boost::asio::buffer(*_buffer),
+ std::bind(
+ &local_server_endpoint_base_impl::send_cbk,
+ server_->shared_from_this(),
+ _buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
void local_server_endpoint_impl::connection::send_magic_cookie() {
}
void local_server_endpoint_impl::connection::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
-
- static std::size_t its_start = -1;
- std::size_t its_end;
-
- if (!_error && 0 < _bytes) {
-#if 0
- std::stringstream msg;
- msg << "lse::c<" << this << ">rcb: ";
- for (std::size_t i = 0; i < _bytes; i++)
- msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
-
- message_.insert(message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
-
- do {
- if (its_start == -1) {
- its_start = 0;
- while (its_start + 3 < message_.size() &&
- (message_[its_start] != 0x67 || message_[its_start+1] != 0x37 ||
- message_[its_start+2] != 0x6d || message_[its_start+3] != 0x07)) {
- its_start ++;
- }
-
- its_start = (its_start + 3 == message_.size() ? -1 : its_start+4);
- }
-
- if (its_start != -1) {
- its_end = its_start;
- while (its_end + 3 < message_.size() &&
- (message_[its_end] != 0x07 || message_[its_end+1] != 0x6d ||
- message_[its_end+2] != 0x37 || message_[its_end+3] != 0x67)) {
- its_end ++;
- }
- }
-
- if (its_start != -1 && its_end+3 < message_.size()) {
- server_->host_->on_message(&message_[its_start], its_end - its_start, server_);
- message_.erase(message_.begin(), message_.begin() + its_end + 4);
- its_start = -1;
- }
-
- } while (message_.size() > 8 && its_start == -1); // start tag + end tag --> 8 Byte
- }
-
- if (_error == boost::asio::error::misc_errors::eof) {
- server_->remove_connection(this);
- } else {
- start();
- }
+ packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes) {
+
+ std::shared_ptr<endpoint_host> its_host = server_->host_.lock();
+ if (its_host) {
+ std::size_t its_start;
+ std::size_t its_end;
+
+ if (!_error && 0 < _bytes) {
+ #if 0
+ std::stringstream msg;
+ msg << "lse::c<" << this << ">rcb: ";
+ for (std::size_t i = 0; i < _bytes; i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+ #endif
+
+ message_.insert(message_.end(), _buffer->begin(),
+ _buffer->begin() + _bytes);
+
+ #define MESSAGE_IS_EMPTY (-1)
+ #define FOUND_MESSAGE (-2)
+
+ do {
+ its_start = 0;
+ while (its_start + 3 < message_.size() &&
+ (message_[its_start] != 0x67 ||
+ message_[its_start+1] != 0x37 ||
+ message_[its_start+2] != 0x6d ||
+ message_[its_start+3] != 0x07)) {
+ its_start ++;
+ }
+
+ its_start = (its_start + 3 == message_.size() ?
+ MESSAGE_IS_EMPTY : its_start+4);
+
+ if (its_start != MESSAGE_IS_EMPTY) {
+ its_end = its_start;
+ while (its_end + 3 < message_.size() &&
+ (message_[its_end] != 0x07 ||
+ message_[its_end+1] != 0x6d ||
+ message_[its_end+2] != 0x37 ||
+ message_[its_end+3] != 0x67)) {
+ its_end ++;
+ }
+ }
+
+ if (its_start != MESSAGE_IS_EMPTY &&
+ its_end+3 < message_.size()) {
+ its_host->on_message(&message_[its_start],
+ its_end - its_start, server_);
+
+ #if 0
+ std::stringstream local_msg;
+ local_msg << "lse::c<" << this << ">rcb::thunk: ";
+ for (std::size_t i = its_start; i < its_end; i++)
+ local_msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int)(message_)[i] << " ";
+ VSOMEIP_DEBUG << local_msg.str();
+ #endif
+
+ message_.erase(message_.begin(),
+ message_.begin() + its_end + 4);
+ its_start = FOUND_MESSAGE;
+ }
+ } while (message_.size() > 0 && its_start == FOUND_MESSAGE);
+ }
+
+ if (_error == boost::asio::error::misc_errors::eof) {
+ server_->remove_connection(this);
+ } else {
+ start();
+ }
+ }
}
} // namespace vsomeip
diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp
index ea6a93f..0158cf6 100644
--- a/implementation/endpoints/src/server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/server_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -24,153 +23,159 @@ namespace vsomeip {
template<typename Protocol, int MaxBufferSize>
server_endpoint_impl<Protocol, MaxBufferSize>::server_endpoint_impl(
- std::shared_ptr<endpoint_host> _host, endpoint_type _local,
- boost::asio::io_service &_io)
- : endpoint_impl<MaxBufferSize>(_host, _io),
- flush_timer_(_io) {
+ std::shared_ptr<endpoint_host> _host, endpoint_type _local,
+ boost::asio::io_service &_io)
+ : endpoint_impl<MaxBufferSize>(_host, _io), flush_timer_(_io) {
}
template<typename Protocol, int MaxBufferSize>
bool server_endpoint_impl<Protocol, MaxBufferSize>::is_client() const {
- return false;
+ return false;
}
template<typename Protocol, int MaxBufferSize>
bool server_endpoint_impl<Protocol, MaxBufferSize>::is_connected() const {
- return true;
+ return true;
}
template<typename Protocol, int MaxBufferSize>
-bool server_endpoint_impl<Protocol, MaxBufferSize>::send(
- const uint8_t *_data, uint32_t _size, bool _flush) {
+bool server_endpoint_impl<Protocol, MaxBufferSize>::send(const uint8_t *_data,
+ uint32_t _size, bool _flush) {
#if 0
- std::stringstream msg;
- msg << "sei::send ";
- for (uint32_t i = 0; i < _size; i++)
- msg << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "sei::send ";
+ for (uint32_t i = 0; i < _size; i++)
+ msg << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- endpoint_type its_target;
- bool is_valid_target(false);
+ endpoint_type its_target;
+ bool is_valid_target(false);
- if (VSOMEIP_SESSION_POS_MAX < _size) {
- std::lock_guard<std::mutex> its_lock(mutex_);
+ if (VSOMEIP_SESSION_POS_MAX < _size) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
- service_t its_service;
- std::memcpy(&its_service, &_data[VSOMEIP_SERVICE_POS_MIN],
+ service_t its_service;
+ std::memcpy(&its_service, &_data[VSOMEIP_SERVICE_POS_MIN],
sizeof(service_t));
- client_t its_client;
- std::memcpy(&its_client, &_data[VSOMEIP_CLIENT_POS_MIN], sizeof(client_t));
- session_t its_session;
- std::memcpy(&its_session, &_data[VSOMEIP_SESSION_POS_MIN],
+ client_t its_client;
+ std::memcpy(&its_client, &_data[VSOMEIP_CLIENT_POS_MIN],
+ sizeof(client_t));
+ session_t its_session;
+ std::memcpy(&its_session, &_data[VSOMEIP_SESSION_POS_MIN],
sizeof(session_t));
- auto found_client = clients_.find(its_client);
- if (found_client != clients_.end()) {
- auto found_session = found_client->second.find(its_session);
- if (found_session != found_client->second.end()) {
- its_target = found_session->second;
- is_valid_target = true;
- }
+ auto found_client = clients_.find(its_client);
+ if (found_client != clients_.end()) {
+ auto found_session = found_client->second.find(its_session);
+ if (found_session != found_client->second.end()) {
+ its_target = found_session->second;
+ is_valid_target = true;
+ }
+ } else {
+ event_t its_event = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_METHOD_POS_MIN],
+ _data[VSOMEIP_METHOD_POS_MAX]);
+ is_valid_target
+ = get_multicast(its_service, its_event, its_target);
+ }
+
+ if (is_valid_target) {
+ is_valid_target = send_intern(its_target, _data, _size, _flush);
+ }
+ }
+ return is_valid_target;
+}
+
+template<typename Protocol, int MaxBufferSize>
+bool server_endpoint_impl<Protocol, MaxBufferSize>::send_intern(
+ endpoint_type _target, const byte_t *_data, uint32_t _size,
+ bool _flush) {
+
+ std::shared_ptr<std::vector<byte_t> > target_packetizer;
+ auto found_packetizer = packetizer_.find(_target);
+ if (found_packetizer != packetizer_.end()) {
+ target_packetizer = found_packetizer->second;
} else {
- event_t its_event = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
- _data[VSOMEIP_METHOD_POS_MAX]);
- is_valid_target = get_multicast(its_service, its_event, its_target);
+ target_packetizer = std::make_shared<message_buffer_t>();
+ packetizer_.insert(std::make_pair(_target, target_packetizer));
}
- if (is_valid_target) {
- is_valid_target = send_intern(its_target, _data, _size, _flush);
+ if (target_packetizer->size() + _size > MaxBufferSize) {
+ send_queued(_target, target_packetizer);
+ packetizer_[_target] = std::make_shared<message_buffer_t>();
}
- }
- return is_valid_target;
-}
-template<typename Protocol, int MaxBufferSize>
-bool server_endpoint_impl<Protocol, MaxBufferSize>::send_intern(endpoint_type _target,
- const byte_t *_data, uint32_t _size, bool _flush) {
-
- std::shared_ptr < std::vector<byte_t> > target_packetizer;
- auto found_packetizer = packetizer_.find(_target);
- if (found_packetizer != packetizer_.end()) {
- target_packetizer = found_packetizer->second;
- } else {
- target_packetizer = std::make_shared<message_buffer_t>();
- packetizer_.insert(
- std::make_pair(_target, target_packetizer));
- }
-
- if (target_packetizer->size() + _size > MaxBufferSize) {
- send_queued(_target, target_packetizer);
- packetizer_[_target] = std::make_shared<message_buffer_t>();
- }
-
- target_packetizer->insert(
- target_packetizer->end(), _data, _data + _size);
-
- if (_flush) {
- flush_timer_.cancel();
- send_queued(_target, target_packetizer);
- packetizer_[_target] = std::make_shared<message_buffer_t>();
- } else {
- std::chrono::milliseconds flush_timeout(VSOMEIP_DEFAULT_FLUSH_TIMEOUT);
- flush_timer_.expires_from_now(flush_timeout); // TODO: use configured value
- flush_timer_.async_wait(
- std::bind(
- &server_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
- this->shared_from_this(), _target,
- std::placeholders::_1));
- }
- return true;
+ target_packetizer->insert(target_packetizer->end(), _data, _data + _size);
+
+ if (_flush) {
+ flush_timer_.cancel();
+ send_queued(_target, target_packetizer);
+ packetizer_[_target] = std::make_shared<message_buffer_t>();
+ } else {
+ std::chrono::milliseconds flush_timeout(VSOMEIP_DEFAULT_FLUSH_TIMEOUT);
+ flush_timer_.expires_from_now(flush_timeout); // TODO: use configured value
+ flush_timer_.async_wait(
+ std::bind(&server_endpoint_impl<
+ Protocol, MaxBufferSize
+ >::flush_cbk,
+ this->shared_from_this(),
+ _target,
+ std::placeholders::_1));
+ }
+ return true;
}
template<typename Protocol, int MaxBufferSize>
bool server_endpoint_impl<Protocol, MaxBufferSize>::flush(
- endpoint_type _target) {
- bool is_flushed = false;
- std::lock_guard<std::mutex> its_lock(mutex_);
- auto i = packetizer_.find(_target);
- if (i != packetizer_.end() && !i->second->empty()) {
- send_queued(_target, i->second);
- i->second = std::make_shared<message_buffer_t>();
- is_flushed = true;
- }
-
- return is_flushed;
+ endpoint_type _target) {
+ bool is_flushed = false;
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ auto i = packetizer_.find(_target);
+ if (i != packetizer_.end() && !i->second->empty()) {
+ send_queued(_target, i->second);
+ i->second = std::make_shared<message_buffer_t>();
+ is_flushed = true;
+ }
+
+ return is_flushed;
}
template<typename Protocol, int MaxBufferSize>
void server_endpoint_impl<Protocol, MaxBufferSize>::connect_cbk(
- boost::system::error_code const &_error) {
+ boost::system::error_code const &_error) {
}
template<typename Protocol, int MaxBufferSize>
void server_endpoint_impl<Protocol, MaxBufferSize>::send_cbk(
- message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
- std::size_t _bytes) {
+ message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
+ std::size_t _bytes) {
#if 0
-std::stringstream msg;
-msg << "sei::scb (" << _error.message() << "): ";
-for (std::size_t i = 0; i < _buffer->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
-VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "sei::scb (" << _error.message() << "): ";
+ for (std::size_t i = 0; i < _buffer->size(); ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
}
template<typename Protocol, int MaxBufferSize>
void server_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk(
- endpoint_type _target, const boost::system::error_code &_error_code) {
-if (!_error_code) {
- (void) flush(_target);
-}
+ endpoint_type _target, const boost::system::error_code &_error_code) {
+ if (!_error_code) {
+ (void) flush(_target);
+ }
}
// Instantiate template
-#ifndef __WINDOWS__
+#ifndef WIN32
template class server_endpoint_impl<boost::asio::local::stream_protocol,
VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
#else
// TODO: put instantiation for windows here!
+//template class server_endpoint_impl<boost::asio::ip::tcp,
+// VSOMEIP_MAX_TCP_MESSAGE_SIZE>;
#endif
template class server_endpoint_impl<boost::asio::ip::tcp,
VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
index ad20d15..cf91fa7 100644
--- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -21,141 +20,166 @@ namespace ip = boost::asio::ip;
namespace vsomeip {
tcp_client_endpoint_impl::tcp_client_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _remote, boost::asio::io_service &_io)
- : tcp_client_endpoint_base_impl(_host, _remote, _io) {
- is_supporting_magic_cookies_ = true;
+ std::shared_ptr< endpoint_host > _host, endpoint_type _remote, boost::asio::io_service &_io)
+ : tcp_client_endpoint_base_impl(_host, _remote, _io) {
+ is_supporting_magic_cookies_ = true;
}
tcp_client_endpoint_impl::~tcp_client_endpoint_impl() {
}
+bool tcp_client_endpoint_impl::is_local() const {
+ return false;
+}
+
void tcp_client_endpoint_impl::start() {
- connect();
+ connect();
}
void tcp_client_endpoint_impl::connect() {
- socket_.open(remote_.protocol());
-
- // Nagle algorithm off
- ip::tcp::no_delay option;
- socket_.set_option(option);
-
- socket_.async_connect(
- remote_,
- std::bind(
- &tcp_client_endpoint_base_impl::connect_cbk,
- shared_from_this(),
- std::placeholders::_1
- )
- );
+ socket_.open(remote_.protocol());
+
+ // Nagle algorithm off
+ ip::tcp::no_delay option;
+ socket_.set_option(option);
+
+ socket_.async_connect(
+ remote_,
+ std::bind(
+ &tcp_client_endpoint_base_impl::connect_cbk,
+ shared_from_this(),
+ std::placeholders::_1
+ )
+ );
}
void tcp_client_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive(
- boost::asio::buffer(*its_buffer),
- std::bind(
- &tcp_client_endpoint_impl::receive_cbk,
- std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ packet_buffer_ptr_t its_buffer
+ = std::make_shared< packet_buffer_t >();
+ socket_.async_receive(
+ boost::asio::buffer(*its_buffer),
+ std::bind(
+ &tcp_client_endpoint_impl::receive_cbk,
+ std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()),
+ its_buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
- if (has_enabled_magic_cookies_)
- send_magic_cookie(_buffer);
-
- boost::asio::async_write(
- socket_,
- boost::asio::buffer(*_buffer),
- std::bind(
- &tcp_client_endpoint_base_impl::send_cbk,
- shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ if (has_enabled_magic_cookies_)
+ send_magic_cookie(_buffer);
+
+ boost::asio::async_write(
+ socket_,
+ boost::asio::buffer(*_buffer),
+ std::bind(
+ &tcp_client_endpoint_base_impl::send_cbk,
+ shared_from_this(),
+ _buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+}
+
+bool tcp_client_endpoint_impl::get_remote_address(
+ boost::asio::ip::address &_address) const {
+ _address = remote_.address();
+ return true;
}
-unsigned short tcp_client_endpoint_impl::get_port() const {
+unsigned short tcp_client_endpoint_impl::get_local_port() const {
return socket_.local_endpoint().port();
}
+unsigned short tcp_client_endpoint_impl::get_remote_port() const {
+ return socket_.remote_endpoint().port();
+}
+
bool tcp_client_endpoint_impl::is_reliable() const {
return true;
}
bool tcp_client_endpoint_impl::is_magic_cookie() const {
- return (0 == std::memcmp(SERVICE_COOKIE, &message_[0], sizeof(SERVICE_COOKIE)));
+ return (0 == std::memcmp(SERVICE_COOKIE, &message_[0], sizeof(SERVICE_COOKIE)));
}
void tcp_client_endpoint_impl::send_magic_cookie(message_buffer_ptr_t &_buffer) {
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
- VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
- _buffer->insert(
- _buffer->begin(),
- CLIENT_COOKIE,
- CLIENT_COOKIE + sizeof(CLIENT_COOKIE)
- );
- } else {
- VSOMEIP_WARNING << "Packet full. Cannot insert magic cookie!";
- }
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
+ VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
+ _buffer->insert(
+ _buffer->begin(),
+ CLIENT_COOKIE,
+ CLIENT_COOKIE + sizeof(CLIENT_COOKIE)
+ );
+ } else {
+ VSOMEIP_WARNING << "Packet full. Cannot insert magic cookie!";
+ }
}
void tcp_client_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
+ packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes) {
#if 0
- std::stringstream msg;
- msg << "cei::rcb (" << _error.message() << "): ";
- for (std::size_t i = 0; i < _bytes; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "cei::rcb (" << _error.message() << "): ";
+ for (std::size_t i = 0; i < _bytes; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (!_error && 0 < _bytes) {
- this->message_.insert(this->message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
-
- bool has_full_message;
- do {
- uint32_t current_message_size = utility::get_message_size(message_);
- has_full_message = (current_message_size > 0 && current_message_size <= message_.size());
- if (has_full_message) {
- bool needs_forwarding(true);
- if (is_magic_cookie()) {
- has_enabled_magic_cookies_ = true;
- } else {
- if (has_enabled_magic_cookies_) {
- uint32_t its_offset = find_magic_cookie(message_);
- if (its_offset < current_message_size) {
- VSOMEIP_ERROR << "Message includes Magic Cookie. Ignoring it.";
- current_message_size = its_offset;
- needs_forwarding = false;
- }
- }
- }
- if (needs_forwarding)
- host_->on_message(&message_[0], current_message_size, this);
- message_.erase(message_.begin(), message_.begin() + current_message_size);
- } else if (has_enabled_magic_cookies_ && message_.size() > 0){
- uint32_t its_offset = find_magic_cookie(message_);
- if (its_offset < message_.size()) {
- message_.erase(message_.begin(), message_.begin() + its_offset);
- has_full_message = true; // trigger next loop
- }
- } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
- VSOMEIP_ERROR << "Message exceeds maximum message size. Resetting receiver.";
- message_.clear();
- }
- } while (has_full_message);
- restart();
- } else {
- receive();
- }
+ std::shared_ptr<endpoint_host> its_host = host_.lock();
+ if (its_host) {
+ if (!_error && 0 < _bytes) {
+ this->message_.insert(this->message_.end(), _buffer->begin(),
+ _buffer->begin() + _bytes);
+
+ bool has_full_message;
+ do {
+ uint32_t current_message_size
+ = utility::get_message_size(message_);
+ has_full_message = (current_message_size > 0
+ && current_message_size <= message_.size());
+ if (has_full_message) {
+ bool needs_forwarding(true);
+ if (is_magic_cookie()) {
+ has_enabled_magic_cookies_ = true;
+ } else {
+ if (has_enabled_magic_cookies_) {
+ uint32_t its_offset = find_magic_cookie(message_);
+ if (its_offset < current_message_size) {
+ VSOMEIP_ERROR << "Message includes Magic Cookie. Ignoring it.";
+ current_message_size = its_offset;
+ needs_forwarding = false;
+ }
+ }
+ }
+ if (needs_forwarding)
+ its_host->on_message(&message_[0],
+ current_message_size, this);
+ message_.erase(message_.begin(),
+ message_.begin() + current_message_size);
+ } else if (has_enabled_magic_cookies_ && message_.size() > 0){
+ uint32_t its_offset = find_magic_cookie(message_);
+ if (its_offset < message_.size()) {
+ message_.erase(message_.begin(),
+ message_.begin() + its_offset);
+ has_full_message = true; // trigger next loop
+ }
+ } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
+ VSOMEIP_ERROR << "Message exceeds maximum message size. "
+ << "Resetting receiver.";
+ message_.clear();
+ }
+ } while (has_full_message);
+ restart();
+ } else {
+ receive();
+ }
+ }
}
} // namespace vsomeip
diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
index 9d1f918..be4ac5f 100644
--- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -21,205 +20,244 @@ namespace ip = boost::asio::ip;
namespace vsomeip {
tcp_server_endpoint_impl::tcp_server_endpoint_impl(
- std::shared_ptr<endpoint_host> _host, endpoint_type _local,
- boost::asio::io_service &_io) :
- tcp_server_endpoint_base_impl(_host, _local, _io), acceptor_(_io,
- _local), current_(0) {
- is_supporting_magic_cookies_ = true;
+ std::shared_ptr<endpoint_host> _host, endpoint_type _local,
+ boost::asio::io_service &_io)
+ : tcp_server_endpoint_base_impl(_host, _local, _io),
+ acceptor_(_io, _local),
+ current_(0) {
+ is_supporting_magic_cookies_ = true;
}
tcp_server_endpoint_impl::~tcp_server_endpoint_impl() {
}
+bool tcp_server_endpoint_impl::is_local() const {
+ return false;
+}
+
void tcp_server_endpoint_impl::start() {
- connection::ptr new_connection = connection::create(this);
+ connection::ptr new_connection = connection::create(this);
- acceptor_.async_accept(new_connection->get_socket(),
- std::bind(&tcp_server_endpoint_impl::accept_cbk,
- std::dynamic_pointer_cast<tcp_server_endpoint_impl>(
- shared_from_this()), new_connection,
- std::placeholders::_1));
+ acceptor_.async_accept(new_connection->get_socket(),
+ std::bind(&tcp_server_endpoint_impl::accept_cbk,
+ std::dynamic_pointer_cast<tcp_server_endpoint_impl>(
+ shared_from_this()), new_connection,
+ std::placeholders::_1));
}
void tcp_server_endpoint_impl::stop() {
- for (auto& i : connections_)
- i.second->stop();
- acceptor_.close();
+ for (auto& i : connections_)
+ i.second->stop();
+ acceptor_.close();
}
bool tcp_server_endpoint_impl::send_to(
- const std::shared_ptr<endpoint_definition> _target, const byte_t *_data,
- uint32_t _size, bool _flush) {
- endpoint_type its_target(_target->get_address(), _target->get_port());
- return send_intern(its_target, _data, _size, _flush);
+ const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data,
+ uint32_t _size, bool _flush) {
+ endpoint_type its_target(_target->get_address(), _target->get_port());
+ return send_intern(its_target, _data, _size, _flush);
}
void tcp_server_endpoint_impl::send_queued(endpoint_type _target,
- message_buffer_ptr_t _buffer) {
- auto connection_iterator = connections_.find(_target);
- if (connection_iterator != connections_.end())
- connection_iterator->second->send_queued(_buffer);
+ message_buffer_ptr_t _buffer) {
+ auto connection_iterator = connections_.find(_target);
+ if (connection_iterator != connections_.end())
+ connection_iterator->second->send_queued(_buffer);
}
-tcp_server_endpoint_impl::endpoint_type tcp_server_endpoint_impl::get_remote() const {
- return current_->get_socket().remote_endpoint();
+tcp_server_endpoint_impl::endpoint_type
+tcp_server_endpoint_impl::get_remote() const {
+ return current_->get_socket().remote_endpoint();
}
bool tcp_server_endpoint_impl::get_multicast(service_t, event_t,
- tcp_server_endpoint_impl::endpoint_type &) const {
- return false;
+ tcp_server_endpoint_impl::endpoint_type &) const {
+ return false;
}
void tcp_server_endpoint_impl::accept_cbk(connection::ptr _connection,
- boost::system::error_code const &_error) {
+ boost::system::error_code const &_error) {
- if (!_error) {
- socket_type &new_connection_socket = _connection->get_socket();
- endpoint_type remote = new_connection_socket.remote_endpoint();
+ if (!_error) {
+ socket_type &new_connection_socket = _connection->get_socket();
+ endpoint_type remote = new_connection_socket.remote_endpoint();
- connections_[remote] = _connection;
- _connection->start();
- }
+ connections_[remote] = _connection;
+ _connection->start();
+ }
- start();
+ start();
}
-unsigned short tcp_server_endpoint_impl::get_port() const {
- return acceptor_.local_endpoint().port();
+unsigned short tcp_server_endpoint_impl::get_local_port() const {
+ return acceptor_.local_endpoint().port();
}
bool tcp_server_endpoint_impl::is_reliable() const {
- return true;
+ return true;
}
///////////////////////////////////////////////////////////////////////////////
// class tcp_service_impl::connection
///////////////////////////////////////////////////////////////////////////////
tcp_server_endpoint_impl::connection::connection(
- tcp_server_endpoint_impl *_server) :
- socket_(_server->service_), server_(_server) {
+ tcp_server_endpoint_impl *_server) :
+ socket_(_server->service_), server_(_server) {
}
-tcp_server_endpoint_impl::connection::ptr tcp_server_endpoint_impl::connection::create(
- tcp_server_endpoint_impl *_server) {
- return ptr(new connection(_server));
+tcp_server_endpoint_impl::connection::ptr
+tcp_server_endpoint_impl::connection::create(
+ tcp_server_endpoint_impl *_server) {
+ return ptr(new connection(_server));
}
-tcp_server_endpoint_impl::socket_type & tcp_server_endpoint_impl::connection::get_socket() {
- return socket_;
+tcp_server_endpoint_impl::socket_type &
+tcp_server_endpoint_impl::connection::get_socket() {
+ return socket_;
}
void tcp_server_endpoint_impl::connection::start() {
- packet_buffer_ptr_t its_buffer = std::make_shared<packet_buffer_t>();
- socket_.async_receive(boost::asio::buffer(*its_buffer),
- std::bind(&tcp_server_endpoint_impl::connection::receive_cbk,
- shared_from_this(), its_buffer, std::placeholders::_1,
- std::placeholders::_2));
+ packet_buffer_ptr_t its_buffer = std::make_shared<packet_buffer_t>();
+ socket_.async_receive(boost::asio::buffer(*its_buffer),
+ std::bind(&tcp_server_endpoint_impl::connection::receive_cbk,
+ shared_from_this(), its_buffer, std::placeholders::_1,
+ std::placeholders::_2));
}
void tcp_server_endpoint_impl::connection::stop() {
- socket_.close();
+ socket_.close();
}
void tcp_server_endpoint_impl::connection::send_queued(
- message_buffer_ptr_t _buffer) {
- if (server_->has_enabled_magic_cookies_)
- send_magic_cookie(_buffer);
-
- boost::asio::async_write(socket_, boost::asio::buffer(*_buffer),
- std::bind(&tcp_server_endpoint_base_impl::send_cbk,
- server_->shared_from_this(), _buffer, std::placeholders::_1,
- std::placeholders::_2));
+ message_buffer_ptr_t _buffer) {
+ if (server_->has_enabled_magic_cookies_)
+ send_magic_cookie(_buffer);
+
+ boost::asio::async_write(socket_, boost::asio::buffer(*_buffer),
+ std::bind(&tcp_server_endpoint_base_impl::send_cbk,
+ server_->shared_from_this(),
+ _buffer, std::placeholders::_1,
+ std::placeholders::_2));
}
void tcp_server_endpoint_impl::connection::send_magic_cookie(
- message_buffer_ptr_t &_buffer) {
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
- VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
- _buffer->insert(_buffer->begin(), SERVICE_COOKIE,
- SERVICE_COOKIE + sizeof(SERVICE_COOKIE));
- }
+ message_buffer_ptr_t &_buffer) {
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
+ VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
+ _buffer->insert(_buffer->begin(), SERVICE_COOKIE,
+ SERVICE_COOKIE + sizeof(SERVICE_COOKIE));
+ }
}
bool tcp_server_endpoint_impl::connection::is_magic_cookie() const {
- return (0 == std::memcmp(CLIENT_COOKIE, &message_[0], sizeof(CLIENT_COOKIE)));
+ return (0 == std::memcmp(CLIENT_COOKIE, &message_[0],
+ sizeof(CLIENT_COOKIE)));
}
void tcp_server_endpoint_impl::connection::receive_cbk(
- packet_buffer_ptr_t _buffer, boost::system::error_code const &_error,
- std::size_t _bytes) {
+ packet_buffer_ptr_t _buffer, boost::system::error_code const &_error,
+ std::size_t _bytes) {
#if 0
- std::stringstream msg;
- for (std::size_t i = 0; i < _bytes; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0')
- << (int) (*_buffer)[i] << " ";
- VSOMEIP_DEBUG<< msg.str();
+ std::stringstream msg;
+ for (std::size_t i = 0; i < _bytes; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int) (*_buffer)[i] << " ";
+ VSOMEIP_DEBUG<< msg.str();
#endif
- if (!_error && 0 < _bytes) {
- message_.insert(message_.end(), _buffer->begin(),
- _buffer->begin() + _bytes);
-
- static int i = 1;
-
- bool has_full_message;
- do {
- uint32_t current_message_size = utility::get_message_size(message_);
- has_full_message = (current_message_size > 0 && current_message_size <= message_.size());
- if (has_full_message) {
- bool needs_forwarding(true);
- if (is_magic_cookie()) {
- server_->has_enabled_magic_cookies_ = true;
- } else {
- if (server_->has_enabled_magic_cookies_) {
- uint32_t its_offset = server_->find_magic_cookie(message_);
- if (its_offset < current_message_size) {
- VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
- current_message_size = its_offset;
- needs_forwarding = false;
- }
- }
- }
- if (needs_forwarding) {
- if (utility::is_request(message_[VSOMEIP_MESSAGE_TYPE_POS])) {
- client_t its_client;
- std::memcpy(&its_client,
- &message_[VSOMEIP_CLIENT_POS_MIN],
- sizeof(client_t));
- session_t its_session;
- std::memcpy(&its_session,
- &message_[VSOMEIP_SESSION_POS_MIN],
- sizeof(session_t));
- server_->clients_[its_client][its_session] =
- socket_.remote_endpoint();
- }
- server_->host_->on_message(&message_[0],
- current_message_size, server_);
- }
- message_.erase(message_.begin(), message_.begin() + current_message_size);
- } else if (server_->has_enabled_magic_cookies_ && message_.size() > 0){
- uint32_t its_offset = server_->find_magic_cookie(message_);
- if (its_offset < message_.size()) {
- VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
- message_.erase(message_.begin(), message_.begin() + its_offset);
- has_full_message = true; // trigger next loop
- }
- } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
- VSOMEIP_ERROR << "Message exceeds maximum message size. Resetting receiver.";
- message_.clear();
- }
- } while (has_full_message);
-
- start();
- }
+ std::shared_ptr<endpoint_host> its_host = server_->host_.lock();
+ if (its_host) {
+ if (!_error && 0 < _bytes) {
+ message_.insert(message_.end(), _buffer->begin(),
+ _buffer->begin() + _bytes);
+
+ static int i = 1;
+
+ bool has_full_message;
+ do {
+ uint32_t current_message_size
+ = utility::get_message_size(message_);
+ has_full_message = (current_message_size > 0
+ && current_message_size <= message_.size());
+ if (has_full_message) {
+ bool needs_forwarding(true);
+ if (is_magic_cookie()) {
+ server_->has_enabled_magic_cookies_ = true;
+ } else {
+ if (server_->has_enabled_magic_cookies_) {
+ uint32_t its_offset
+ = server_->find_magic_cookie(message_);
+ if (its_offset < current_message_size) {
+ VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
+ current_message_size = its_offset;
+ needs_forwarding = false;
+ }
+ }
+ }
+ if (needs_forwarding) {
+ if (utility::is_request(message_[VSOMEIP_MESSAGE_TYPE_POS])) {
+ client_t its_client;
+ std::memcpy(&its_client,
+ &message_[VSOMEIP_CLIENT_POS_MIN],
+ sizeof(client_t));
+ session_t its_session;
+ std::memcpy(&its_session,
+ &message_[VSOMEIP_SESSION_POS_MIN],
+ sizeof(session_t));
+ server_->clients_[its_client][its_session] =
+ socket_.remote_endpoint();
+ }
+ its_host->on_message(&message_[0], current_message_size, server_);
+ }
+ message_.erase(message_.begin(), message_.begin() + current_message_size);
+ } else if (server_->has_enabled_magic_cookies_ && message_.size() > 0){
+ uint32_t its_offset = server_->find_magic_cookie(message_);
+ if (its_offset < message_.size()) {
+ VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
+ message_.erase(message_.begin(), message_.begin() + its_offset);
+ has_full_message = true; // trigger next loop
+ }
+ } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
+ VSOMEIP_ERROR << "Message exceeds maximum message size. Resetting receiver.";
+ message_.clear();
+ }
+ } while (has_full_message);
+
+ start();
+ }
+ }
+}
+
+client_t tcp_server_endpoint_impl::get_client(std::shared_ptr<endpoint_definition> _endpoint) {
+ endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port());
+ auto its_remote = connections_.find(endpoint);
+ if (its_remote != connections_.end()) {
+ return its_remote->second->get_client(endpoint);
+ }
+ return 0;
+}
+
+client_t tcp_server_endpoint_impl::connection::get_client(endpoint_type _endpoint_type) {
+ for (auto its_client : server_->clients_) {
+ for (auto its_session : server_->clients_[its_client.first]) {
+ auto endpoint = its_session.second;
+ if (endpoint == _endpoint_type) {
+ // TODO: Check system byte order before convert!
+ client_t client = its_client.first << 8 | its_client.first >> 8;
+ return client;
+ }
+ }
+ }
+ return 0;
}
// Dummies
void tcp_server_endpoint_impl::receive() {
- // intentionally left empty
+ // intentionally left empty
}
void tcp_server_endpoint_impl::restart() {
- // intentionally left empty
+ // intentionally left empty
}
} // namespace vsomeip
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
index e6da818..95f12c3 100644
--- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -18,127 +17,153 @@
namespace vsomeip {
udp_client_endpoint_impl::udp_client_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _remote, boost::asio::io_service &_io)
- : udp_client_endpoint_base_impl(_host, _remote, _io) {
+ std::shared_ptr< endpoint_host > _host, endpoint_type _remote,
+ boost::asio::io_service &_io)
+ : udp_client_endpoint_base_impl(_host, _remote, _io) {
}
udp_client_endpoint_impl::~udp_client_endpoint_impl() {
}
+bool udp_client_endpoint_impl::is_local() const {
+ return false;
+}
+
void udp_client_endpoint_impl::connect() {
- socket_.async_connect(
- remote_,
- std::bind(
- &udp_client_endpoint_base_impl::connect_cbk,
- shared_from_this(),
- std::placeholders::_1
- )
- );
+ socket_.async_connect(
+ remote_,
+ std::bind(
+ &udp_client_endpoint_base_impl::connect_cbk,
+ shared_from_this(),
+ std::placeholders::_1
+ )
+ );
}
void udp_client_endpoint_impl::start() {
- socket_.open(remote_.protocol());
- connect();
- receive();
+ socket_.open(remote_.protocol());
+ connect();
+ receive();
}
void udp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
#if 0
- std::stringstream msg;
- msg << "ucei<" << remote_.address() << ":" << std::dec << remote_.port() << ">::sq: ";
- for (std::size_t i = 0; i < _buffer->size(); i++)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "ucei<" << remote_.address() << ":"
+ << std::dec << remote_.port() << ">::sq: ";
+ for (std::size_t i = 0; i < _buffer->size(); i++)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- socket_.async_send(
- boost::asio::buffer(*_buffer),
- std::bind(
- &udp_client_endpoint_base_impl::send_cbk,
- shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
- receive();
+ socket_.async_send(
+ boost::asio::buffer(*_buffer),
+ std::bind(
+ &udp_client_endpoint_base_impl::send_cbk,
+ shared_from_this(),
+ _buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+ receive();
}
void udp_client_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive_from(
- boost::asio::buffer(*its_buffer),
- remote_,
- std::bind(
- &udp_client_endpoint_impl::receive_cbk,
- std::dynamic_pointer_cast< udp_client_endpoint_impl >(shared_from_this()),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ packet_buffer_ptr_t its_buffer
+ = std::make_shared< packet_buffer_t >();
+ socket_.async_receive_from(
+ boost::asio::buffer(*its_buffer),
+ remote_,
+ std::bind(
+ &udp_client_endpoint_impl::receive_cbk,
+ std::dynamic_pointer_cast<
+ udp_client_endpoint_impl
+ >(shared_from_this()),
+ its_buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
-unsigned short udp_client_endpoint_impl::get_port() const {
+bool udp_client_endpoint_impl::get_remote_address(
+ boost::asio::ip::address &_address) const {
+ _address = remote_.address();
+ return true;
+}
+
+unsigned short udp_client_endpoint_impl::get_local_port() const {
return socket_.local_endpoint().port();
}
+unsigned short udp_client_endpoint_impl::get_remote_port() const {
+ return socket_.remote_endpoint().port();
+}
+
void udp_client_endpoint_impl::join(const std::string &_address) {
- if (remote_.address().is_v4()) {
- try {
- socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
- socket_.set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_address)));
- }
- catch (...) {
- }
- } else {
- // TODO: support multicast for IPv6
- }
+ if (remote_.address().is_v4()) {
+ try {
+ socket_.set_option(
+ boost::asio::ip::udp::socket::reuse_address(true));
+ socket_.set_option(boost::asio::ip::multicast::join_group(
+ boost::asio::ip::address::from_string(_address)));
+ }
+ catch (...) {
+ }
+ } else {
+ // TODO: support multicast for IPv6
+ }
}
void udp_client_endpoint_impl::leave(const std::string &_address) {
- if (remote_.address().is_v4()) {
- try {
- socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
- socket_.set_option(boost::asio::ip::multicast::leave_group(
- boost::asio::ip::address::from_string(_address)));
- }
- catch (...) {
- }
- } else {
- // TODO: support multicast for IPv6
- }
+ if (remote_.address().is_v4()) {
+ try {
+ socket_.set_option(
+ boost::asio::ip::udp::socket::reuse_address(true));
+ socket_.set_option(boost::asio::ip::multicast::leave_group(
+ boost::asio::ip::address::from_string(_address)));
+ }
+ catch (...) {
+ }
+ } else {
+ // TODO: support multicast for IPv6
+ }
}
void udp_client_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
- if (!_error && 0 < _bytes) {
+ packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes) {
+ std::shared_ptr<endpoint_host> its_host = host_.lock();
+ if (!_error && 0 < _bytes && its_host) {
#if 0
- std::stringstream msg;
- msg << "ucei::rcb(" << _error.message() << "): ";
- for (std::size_t i = 0; i < _bytes; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "ucei::rcb(" << _error.message() << "): ";
+ for (std::size_t i = 0; i < _bytes; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- this->message_.insert(this->message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
-
- bool has_full_message;
- do {
- uint32_t current_message_size = utility::get_message_size(this->message_);
-
- has_full_message = (current_message_size > 0 && current_message_size <= this->message_.size());
- if (has_full_message) {
- host_->on_message(&message_[0], current_message_size, this);
- this->message_.erase(this->message_.begin(), this->message_.begin() + current_message_size);
- }
- } while (has_full_message);
- }
-
- receive();
+ this->message_.insert(this->message_.end(), _buffer->begin(),
+ _buffer->begin() + _bytes);
+
+ bool has_full_message;
+ do {
+ uint32_t current_message_size
+ = utility::get_message_size(this->message_);
+
+ has_full_message = (current_message_size > 0
+ && current_message_size <= this->message_.size());
+ if (has_full_message) {
+ its_host->on_message(&message_[0], current_message_size, this);
+ this->message_.erase(this->message_.begin(),
+ this->message_.begin() + current_message_size);
+ }
+ } while (has_full_message);
+ }
+
+ receive();
}
} // namespace vsomeip
-
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
index 84cddcf..f0fee37 100644
--- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -22,44 +21,60 @@ namespace ip = boost::asio::ip;
namespace vsomeip {
udp_server_endpoint_impl::udp_server_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io)
- : server_endpoint_impl< ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE >(_host, _local, _io),
- socket_(_io, _local) {
- boost::asio::socket_base::broadcast option(true);
- socket_.set_option(option);
+ std::shared_ptr< endpoint_host > _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io)
+ : server_endpoint_impl<
+ ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE
+ >(_host, _local, _io),
+ socket_(_io, _local.protocol()) {
+ boost::system::error_code ec;
+
+ boost::asio::socket_base::reuse_address optionReuseAddress(true);
+ socket_.set_option(optionReuseAddress);
+
+ socket_.bind(_local, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+
+ boost::asio::socket_base::broadcast option(true);
+ socket_.set_option(option);
}
udp_server_endpoint_impl::~udp_server_endpoint_impl() {
}
+bool udp_server_endpoint_impl::is_local() const {
+ return false;
+}
+
void udp_server_endpoint_impl::start() {
- receive();
+ receive();
}
void udp_server_endpoint_impl::stop() {
- if (socket_.is_open())
- socket_.close();
+ if (socket_.is_open())
+ socket_.close();
}
void udp_server_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive_from(
- boost::asio::buffer(*its_buffer),
- remote_,
- std::bind(
- &udp_server_endpoint_impl::receive_cbk,
- std::dynamic_pointer_cast<
- udp_server_endpoint_impl >(shared_from_this()),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ packet_buffer_ptr_t its_buffer
+ = std::make_shared< packet_buffer_t >();
+ socket_.async_receive_from(
+ boost::asio::buffer(*its_buffer),
+ remote_,
+ std::bind(
+ &udp_server_endpoint_impl::receive_cbk,
+ std::dynamic_pointer_cast<
+ udp_server_endpoint_impl >(shared_from_this()),
+ its_buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
void udp_server_endpoint_impl::restart() {
- receive();
+ receive();
}
bool udp_server_endpoint_impl::send_to(
@@ -69,131 +84,168 @@ bool udp_server_endpoint_impl::send_to(
return send_intern(its_target, _data, _size, _flush);
}
-void udp_server_endpoint_impl::send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) {
+void udp_server_endpoint_impl::send_queued(
+ endpoint_type _target, message_buffer_ptr_t _buffer) {
#if 0
- std::stringstream msg;
- msg << "usei::sq(" << _target.address().to_string() << ":" << _target.port() << "): ";
- for (std::size_t i = 0; i < _buffer->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "usei::sq(" << _target.address().to_string() << ":"
+ << _target.port() << "): ";
+ for (std::size_t i = 0; i < _buffer->size(); ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- socket_.async_send_to(
- boost::asio::buffer(*_buffer),
- _target,
- std::bind(
- &udp_server_endpoint_base_impl::send_cbk,
- shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ socket_.async_send_to(
+ boost::asio::buffer(*_buffer),
+ _target,
+ std::bind(
+ &udp_server_endpoint_base_impl::send_cbk,
+ shared_from_this(),
+ _buffer,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
}
-udp_server_endpoint_impl::endpoint_type udp_server_endpoint_impl::get_remote() const {
- return remote_;
+udp_server_endpoint_impl::endpoint_type
+udp_server_endpoint_impl::get_remote() const {
+ return remote_;
}
bool udp_server_endpoint_impl::get_multicast(service_t _service, event_t _event,
- udp_server_endpoint_impl::endpoint_type &_target) const {
- bool is_valid(false);
- auto find_service = multicasts_.find(_service);
- if (find_service != multicasts_.end()) {
- auto find_event = find_service->second.find(_event);
- if (find_event != find_service->second.end()) {
- _target = find_event->second;
- is_valid = true;
- }
- }
- return is_valid;
+ udp_server_endpoint_impl::endpoint_type &_target) const {
+ bool is_valid(false);
+ auto find_service = multicasts_.find(_service);
+ if (find_service != multicasts_.end()) {
+ auto find_event = find_service->second.find(_event);
+ if (find_event != find_service->second.end()) {
+ _target = find_event->second;
+ is_valid = true;
+ }
+ }
+ return is_valid;
}
void udp_server_endpoint_impl::join(const std::string &_address) {
- if (local_.address().is_v4()) {
- try {
- socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
- socket_.set_option(boost::asio::ip::multicast::enable_loopback(false));
- socket_.set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_address).to_v4()));
- }
- catch (const std::exception &e) {
- VSOMEIP_ERROR << e.what();
- }
- } else {
- // TODO: support multicast for IPv6
- }
+ if (local_.address().is_v4()) {
+ try {
+ socket_.set_option(
+ boost::asio::ip::udp::socket::reuse_address(true));
+ socket_.set_option(
+ boost::asio::ip::multicast::enable_loopback(false));
+ socket_.set_option(boost::asio::ip::multicast::join_group(
+ boost::asio::ip::address::from_string(_address).to_v4()));
+ }
+ catch (const std::exception &e) {
+ VSOMEIP_ERROR << e.what();
+ }
+ } else {
+ // TODO: support multicast for IPv6
+ }
}
void udp_server_endpoint_impl::leave(const std::string &_address) {
- if (local_.address().is_v4()) {
- try {
- socket_.set_option(boost::asio::ip::multicast::leave_group(
- boost::asio::ip::address::from_string(_address)));
- }
- catch (...) {
+ if (local_.address().is_v4()) {
+ try {
+ socket_.set_option(boost::asio::ip::multicast::leave_group(
+ boost::asio::ip::address::from_string(_address)));
+ }
+ catch (...) {
- }
- } else {
- // TODO: support multicast for IPv6
- }
+ }
+ } else {
+ // TODO: support multicast for IPv6
+ }
}
-void udp_server_endpoint_impl::add_multicast(service_t _service, instance_t _instance,
- const std::string &_address, uint16_t _port) {
- endpoint_type its_endpoint(boost::asio::ip::address::from_string(_address), _port);
- multicasts_[_service][_instance] = its_endpoint;
+void udp_server_endpoint_impl::add_multicast(
+ service_t _service, instance_t _instance,
+ const std::string &_address, uint16_t _port) {
+ endpoint_type its_endpoint(
+ boost::asio::ip::address::from_string(_address), _port);
+ multicasts_[_service][_instance] = its_endpoint;
}
-void udp_server_endpoint_impl::remove_multicast(service_t _service, instance_t _instance) {
- auto found_service = multicasts_.find(_service);
- if (found_service != multicasts_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- found_service->second.erase(_instance);
- }
- }
+void udp_server_endpoint_impl::remove_multicast(
+ service_t _service, instance_t _instance) {
+ auto found_service = multicasts_.find(_service);
+ if (found_service != multicasts_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ found_service->second.erase(_instance);
+ }
+ }
}
-unsigned short udp_server_endpoint_impl::get_port() const {
- return socket_.local_endpoint().port();
+unsigned short udp_server_endpoint_impl::get_local_port() const {
+ return socket_.local_endpoint().port();
}
// TODO: find a better way to structure the receive functions
void udp_server_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
+ packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes) {
#if 0
- std::stringstream msg;
- msg << "usei::rcb(" << _error.message() << "): ";
- for (std::size_t i = 0; i < _bytes; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "usei::rcb(" << _error.message() << "): ";
+ for (std::size_t i = 0; i < _bytes; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (!_error && 0 < _bytes) {
- message_.insert(message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
-
- bool has_full_message;
- do {
- uint32_t current_message_size = utility::get_message_size(message_);
- has_full_message = (current_message_size > 0 && current_message_size <= message_.size());
- if (has_full_message) {
- if (utility::is_request(message_[VSOMEIP_MESSAGE_TYPE_POS])) {
- client_t its_client;
- std::memcpy(&its_client, &message_[VSOMEIP_CLIENT_POS_MIN], sizeof(client_t));
- session_t its_session;
- std::memcpy(&its_session, &message_[VSOMEIP_SESSION_POS_MIN], sizeof(session_t));
- clients_[its_client][its_session] = remote_;
- }
-
- this->host_->on_message(&message_[0], current_message_size, this);
- message_.erase(message_.begin(), message_.begin() + current_message_size);
- }
- } while (has_full_message);
-
- restart();
- } else {
- receive();
- }
+ std::shared_ptr<endpoint_host> its_host = this->host_.lock();
+ if (its_host) {
+ if (!_error && 0 < _bytes) {
+ message_.insert(message_.end(), _buffer->begin(),
+ _buffer->begin() + _bytes);
+
+ bool has_full_message;
+ do {
+ uint32_t current_message_size
+ = utility::get_message_size(message_);
+ has_full_message = (current_message_size > 0
+ && current_message_size <= message_.size());
+ if (has_full_message) {
+ if (utility::is_request(
+ message_[VSOMEIP_MESSAGE_TYPE_POS])) {
+ client_t its_client;
+ std::memcpy(&its_client,
+ &message_[VSOMEIP_CLIENT_POS_MIN],
+ sizeof(client_t));
+ session_t its_session;
+ std::memcpy(&its_session,
+ &message_[VSOMEIP_SESSION_POS_MIN],
+ sizeof(session_t));
+ clients_[its_client][its_session] = remote_;
+ }
+
+ its_host->on_message(&message_[0],
+ current_message_size, this);
+ message_.erase(message_.begin(),
+ message_.begin() + current_message_size);
+ }
+ } while (has_full_message);
+
+ restart();
+ } else {
+ receive();
+ }
+ }
+}
+
+client_t udp_server_endpoint_impl::get_client(std::shared_ptr<endpoint_definition> _endpoint) {
+ endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port());
+ for (auto its_client : clients_) {
+ for (auto its_session : clients_[its_client.first]) {
+ if (endpoint == its_session.second) {
+ // TODO: Check system byte order before convert!
+ client_t client = its_client.first << 8 | its_client.first >> 8;
+ return client;
+ }
+ }
+ }
+ return 0;
}
} // namespace vsomeip
diff --git a/implementation/logging/include/logger_impl.hpp b/implementation/logging/include/logger_impl.hpp
index d06d64e..de98f25 100644
--- a/implementation/logging/include/logger_impl.hpp
+++ b/implementation/logging/include/logger_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,39 +18,39 @@
namespace vsomeip {
-BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string)
-BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", boost::log::trivial::severity_level)
+BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string)
+BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity",
+ boost::log::trivial::severity_level)
typedef boost::log::sinks::synchronous_sink<
- boost::log::sinks::text_ostream_backend > sink_t;
+ boost::log::sinks::text_ostream_backend> sink_t;
class logger_impl: public logger {
public:
- static logger & get();
- static void init(const std::string &_path);
+ static std::shared_ptr<logger_impl> & get();
+ static void init(const std::string &_path);
- logger_impl();
+ logger_impl();
- boost::log::sources::severity_logger<
- boost::log::trivial::severity_level > & get_internal();
-private:
- void enable_console();
- void enable_file(const std::string &_path);
- void enable_dlt();
+ boost::log::sources::severity_logger<
+ boost::log::trivial::severity_level> & get_internal();
private:
- static logger_impl the_logger__;
+ void enable_console();
+ void enable_file(const std::string &_path);
+ void enable_dlt();
- boost::log::sources::severity_logger<
- boost::log::trivial::severity_level > logger_;
- boost::log::trivial::severity_level loglevel_;
+private:
+ boost::log::sources::severity_logger<
+ boost::log::trivial::severity_level> logger_;
+ boost::log::trivial::severity_level loglevel_;
- boost::shared_ptr< sink_t > console_sink_;
- boost::shared_ptr< sink_t > file_sink_;
- //boost::shared_ptr< dlt_sink > dlt_sink_;
+ boost::shared_ptr<sink_t> console_sink_;
+ boost::shared_ptr<sink_t> file_sink_;
+ //boost::shared_ptr< dlt_sink > dlt_sink_;
private:
- void use_null_logger();
+ void use_null_logger();
};
} // namespace vsomeip
diff --git a/implementation/logging/src/logger.cpp b/implementation/logging/src/logger.cpp
index 5be4380..03f05aa 100644
--- a/implementation/logging/src/logger.cpp
+++ b/implementation/logging/src/logger.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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 +7,8 @@
namespace vsomeip {
-logger & logger::get() {
- return logger_impl::get();
+std::shared_ptr<logger> logger::get() {
+ return logger_impl::get();
}
} // namespace vsomeip
-
diff --git a/implementation/logging/src/logger_impl.cpp b/implementation/logging/src/logger_impl.cpp
index 7f38caf..f354a40 100644
--- a/implementation/logging/src/logger_impl.cpp
+++ b/implementation/logging/src/logger_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -24,8 +23,10 @@
// can/should be removed in case GPT is updating Boost to V1.55.
#if BOOST_VERSION < 105500
#include <boost/log/utility/empty_deleter.hpp>
-#else
+#elif BOOST_VERSION < 105600
#include <boost/utility/empty_deleter.hpp>
+#else
+#include <boost/core/null_deleter.hpp>
#endif
#include <vsomeip/configuration.hpp>
@@ -42,101 +43,99 @@ using namespace boost::log::trivial;
namespace vsomeip {
-logger_impl logger_impl::the_logger__;
-
-logger & logger_impl::get() {
- return the_logger__;
+std::shared_ptr<logger_impl> & logger_impl::get() {
+ static std::shared_ptr<logger_impl> the_logger__ = std::make_shared<
+ logger_impl>();
+ return the_logger__;
}
logger_impl::logger_impl()
- : loglevel_(debug) {
- logging::add_common_attributes();
+ : loglevel_(debug) {
+ logging::add_common_attributes();
}
-boost::log::sources::severity_logger< boost::log::trivial::severity_level > & logger_impl::get_internal() {
- return logger_;
+boost::log::sources::severity_logger<boost::log::trivial::severity_level> &
+logger_impl::get_internal() {
+ return logger_;
}
void logger_impl::init(const std::string &_path) {
- configuration *its_configuration = configuration::get(_path);
- the_logger__.loglevel_ = its_configuration->get_loglevel();
- logging::core::get()->set_filter(
- logging::trivial::severity >= the_logger__.loglevel_);
+ configuration *its_configuration = configuration::get(_path);
+ get()->loglevel_ = its_configuration->get_loglevel();
+ logging::core::get()->set_filter(
+ logging::trivial::severity >= get()->loglevel_);
- if (its_configuration->has_console_log())
- the_logger__.enable_console();
+ if (its_configuration->has_console_log())
+ get()->enable_console();
- if (its_configuration->has_file_log())
- the_logger__.enable_file(its_configuration->get_logfile());
+ if (its_configuration->has_file_log())
+ get()->enable_file(its_configuration->get_logfile());
- if (its_configuration->has_dlt_log())
- the_logger__.enable_dlt();
+ if (its_configuration->has_dlt_log())
+ get()->enable_dlt();
}
void logger_impl::enable_console() {
- if (console_sink_)
- return;
-
- auto vsomeip_log_format = expressions::stream
- << expressions::format_date_time<boost::posix_time::ptime>(
- "TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
- << " [" << expressions::attr<severity_level>("Severity") << "] "
- << expressions::smessage;
-
- boost::shared_ptr< sinks::text_ostream_backend > backend
- = boost::make_shared< sinks::text_ostream_backend >();
- backend->add_stream(
- boost::shared_ptr< std::ostream >(
- &std::clog,
+ if (console_sink_)
+ return;
+
+ auto vsomeip_log_format = expressions::stream
+ << expressions::format_date_time<boost::posix_time::ptime>(
+ "TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << " ["
+ << expressions::attr<severity_level>("Severity") << "] "
+ << expressions::smessage;
+
+ boost::shared_ptr<sinks::text_ostream_backend> backend = boost::make_shared<
+ sinks::text_ostream_backend>();
+ backend->add_stream(boost::shared_ptr<std::ostream>(&std::clog,
#if BOOST_VERSION < 105500
- boost::log::empty_deleter()
+ boost::log::empty_deleter()
+#elif BOOST_VERSION < 105600
+ boost::empty_deleter()
#else
- boost::empty_deleter()
+ boost::null_deleter()
#endif
- )
- );
+ ));
- console_sink_ = boost::make_shared< sink_t >(backend);
- console_sink_->set_formatter(vsomeip_log_format);
- logging::core::get()->add_sink(console_sink_);
+ console_sink_ = boost::make_shared<sink_t>(backend);
+ console_sink_->set_formatter(vsomeip_log_format);
+ logging::core::get()->add_sink(console_sink_);
}
void logger_impl::enable_file(const std::string &_path) {
- if (file_sink_)
- return;
-
- auto vsomeip_log_format = expressions::stream
- << expressions::format_date_time<boost::posix_time::ptime>(
- "TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
- << " [" << expressions::attr<severity_level>("Severity") << "] "
- << expressions::smessage;
-
- boost::shared_ptr< sinks::text_ostream_backend > backend
- = boost::make_shared< sinks::text_ostream_backend >();
- backend->add_stream(
- boost::shared_ptr< std::ostream >(boost::make_shared< std::ofstream>(_path))
- );
-
- file_sink_ = boost::make_shared< sink_t>(backend);
- file_sink_->set_formatter(vsomeip_log_format);
- logging::core::get()->add_sink(file_sink_);
+ if (file_sink_)
+ return;
+
+ auto vsomeip_log_format = expressions::stream
+ << expressions::format_date_time<boost::posix_time::ptime>(
+ "TimeStamp", "%Y-%m-%d %H:%M:%S.%f") << " ["
+ << expressions::attr<severity_level>("Severity") << "] "
+ << expressions::smessage;
+
+ boost::shared_ptr<sinks::text_ostream_backend> backend = boost::make_shared<
+ sinks::text_ostream_backend>();
+ backend->add_stream(
+ boost::shared_ptr<std::ostream>(
+ boost::make_shared<std::ofstream>(_path)));
+
+ file_sink_ = boost::make_shared<sink_t>(backend);
+ file_sink_->set_formatter(vsomeip_log_format);
+ logging::core::get()->add_sink(file_sink_);
}
void logger_impl::enable_dlt() {
- // TODO: implement
+ // TODO: implement
}
void logger_impl::use_null_logger() {
- boost::shared_ptr< sinks::text_ostream_backend > backend
- = boost::make_shared< sinks::text_ostream_backend >();
- backend->add_stream(
- boost::shared_ptr< std::ostream >(
- new std::ofstream("/dev/null") // TODO: how to call this on windows
- )
- );
-
- file_sink_ = boost::make_shared< sink_t>(backend);
- logging::core::get()->add_sink(file_sink_);
+ boost::shared_ptr<sinks::text_ostream_backend> backend = boost::make_shared<
+ sinks::text_ostream_backend>();
+ backend->add_stream(
+ boost::shared_ptr<std::ostream>(new std::ofstream("/dev/null") // TODO: how to call this on windows
+ ));
+
+ file_sink_ = boost::make_shared<sink_t>(backend);
+ logging::core::get()->add_sink(file_sink_);
}
} // namespace vsomeip
diff --git a/implementation/message/include/deserializer.hpp b/implementation/message/include/deserializer.hpp
index 7bff4b4..941358b 100644
--- a/implementation/message/include/deserializer.hpp
+++ b/implementation/message/include/deserializer.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,6 +8,7 @@
#include <vector>
+#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
namespace vsomeip {
@@ -17,42 +17,44 @@ class message;
class deserializer {
public:
- deserializer();
- deserializer(byte_t *_data, std::size_t _length);
- deserializer(const deserializer& _other);
- virtual ~deserializer();
-
- void set_data(const byte_t *_data, std::size_t _length);
- void append_data(const byte_t *_data, std::size_t _length);
- void drop_data(std::size_t _length);
-
- std::size_t get_available() const;
- std::size_t get_remaining() const;
- void set_remaining(std::size_t _length);
-
- // to be used by applications to deserialize a message
- message * deserialize_message();
-
- // to be used (internally) by objects to deserialize their members
- // Note: this needs to be encapsulated!
- bool deserialize(uint8_t& _value);
- bool deserialize(uint16_t& _value);
- bool deserialize(uint32_t& _value, bool _omit_last_byte = false);
- bool deserialize(uint8_t *_data, std::size_t _length);
- bool deserialize(std::vector< uint8_t >& _value);
-
- bool look_ahead(std::size_t _index, uint8_t &_value) const;
- bool look_ahead(std::size_t _index, uint16_t &_value) const;
- bool look_ahead(std::size_t _index, uint32_t &_value) const;
-
- void reset();
+ VSOMEIP_EXPORT deserializer();
+ VSOMEIP_EXPORT deserializer(byte_t *_data, std::size_t _length);
+ VSOMEIP_EXPORT deserializer(const deserializer& _other);
+ VSOMEIP_EXPORT virtual ~deserializer();
+
+ VSOMEIP_EXPORT void set_data(const byte_t *_data, std::size_t _length);
+ VSOMEIP_EXPORT void append_data(const byte_t *_data, std::size_t _length);
+ VSOMEIP_EXPORT void drop_data(std::size_t _length);
+
+ VSOMEIP_EXPORT std::size_t get_available() const;
+ VSOMEIP_EXPORT std::size_t get_remaining() const;
+ VSOMEIP_EXPORT void set_remaining(std::size_t _length);
+
+ // to be used by applications to deserialize a message
+ VSOMEIP_EXPORT message * deserialize_message();
+
+ // to be used (internally) by objects to deserialize their members
+ // Note: this needs to be encapsulated!
+ VSOMEIP_EXPORT bool deserialize(uint8_t& _value);
+ VSOMEIP_EXPORT bool deserialize(uint16_t& _value);
+ VSOMEIP_EXPORT bool deserialize(uint32_t& _value,
+ bool _omit_last_byte = false);
+ VSOMEIP_EXPORT bool deserialize(uint8_t *_data, std::size_t _length);
+ VSOMEIP_EXPORT bool deserialize(std::vector<uint8_t>& _value);
+
+ VSOMEIP_EXPORT bool look_ahead(std::size_t _index, uint8_t &_value) const;
+ VSOMEIP_EXPORT bool look_ahead(std::size_t _index, uint16_t &_value) const;
+ VSOMEIP_EXPORT bool look_ahead(std::size_t _index, uint32_t &_value) const;
+
+ VSOMEIP_EXPORT void reset();
+
#ifdef VSOMEIP_DEBUGGING
- void show() const;
+ VSOMEIP_EXPORT void show() const;
#endif
protected:
- std::vector< byte_t > data_;
- std::vector< byte_t >::iterator position_;
- std::size_t remaining_;
+ std::vector<byte_t> data_;
+ std::vector<byte_t>::iterator position_;
+ std::size_t remaining_;
};
} // namespace vsomeip
diff --git a/implementation/message/include/message_base_impl.hpp b/implementation/message/include/message_base_impl.hpp
index 4238168..58562f1 100644
--- a/implementation/message/include/message_base_impl.hpp
+++ b/implementation/message/include/message_base_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,6 +8,7 @@
#include <boost/thread.hpp>
+#include <vsomeip/export.hpp>
#include <vsomeip/message.hpp>
#include "message_header_impl.hpp"
@@ -16,48 +16,52 @@
namespace vsomeip {
class message_base_impl
- : virtual public message_base {
+ : virtual public message_base {
public:
- message_base_impl();
- virtual ~message_base_impl();
+ VSOMEIP_EXPORT message_base_impl();
+ VSOMEIP_EXPORT virtual ~message_base_impl();
- message_t get_message() const;
- void set_message(message_t _message);
+ VSOMEIP_EXPORT message_t get_message() const;
+ VSOMEIP_EXPORT void set_message(message_t _message);
- service_t get_service() const;
- void set_service(service_t _service);
+ VSOMEIP_EXPORT service_t get_service() const;
+ VSOMEIP_EXPORT void set_service(service_t _service);
- instance_t get_instance() const;
- void set_instance(instance_t _instance);
+ VSOMEIP_EXPORT instance_t get_instance() const;
+ VSOMEIP_EXPORT void set_instance(instance_t _instance);
- method_t get_method() const;
- void set_method(method_t _method);
+ VSOMEIP_EXPORT method_t get_method() const;
+ VSOMEIP_EXPORT void set_method(method_t _method);
- request_t get_request() const;
+ VSOMEIP_EXPORT request_t get_request() const;
- client_t get_client() const;
- void set_client(client_t _client);
+ VSOMEIP_EXPORT client_t get_client() const;
+ VSOMEIP_EXPORT void set_client(client_t _client);
- session_t get_session() const;
- void set_session(session_t _session);
+ VSOMEIP_EXPORT session_t get_session() const;
+ VSOMEIP_EXPORT void set_session(session_t _session);
- protocol_version_t get_protocol_version() const;
- void set_protocol_version(protocol_version_t _version);
+ VSOMEIP_EXPORT protocol_version_t get_protocol_version() const;
+ VSOMEIP_EXPORT void set_protocol_version(protocol_version_t _version);
- interface_version_t get_interface_version() const;
- void set_interface_version(interface_version_t _version);
+ VSOMEIP_EXPORT interface_version_t get_interface_version() const;
+ VSOMEIP_EXPORT void set_interface_version(interface_version_t _version);
- message_type_e get_message_type() const;
- void set_message_type(message_type_e _type);
+ VSOMEIP_EXPORT message_type_e get_message_type() const;
+ VSOMEIP_EXPORT void set_message_type(message_type_e _type);
- return_code_e get_return_code() const;
- void set_return_code(return_code_e _code);
+ VSOMEIP_EXPORT return_code_e get_return_code() const;
+ VSOMEIP_EXPORT void set_return_code(return_code_e _code);
- message * get_owner() const;
- void set_owner(message *_owner);
+ VSOMEIP_EXPORT bool is_reliable() const;
+ VSOMEIP_EXPORT void set_reliable(bool _is_reliable);
+
+ VSOMEIP_EXPORT message * get_owner() const;
+ VSOMEIP_EXPORT void set_owner(message *_owner);
protected: // members
- message_header_impl header_;
+ message_header_impl header_;
+ bool is_reliable_;
};
} // namespace vsomeip
diff --git a/implementation/message/include/message_header_impl.hpp b/implementation/message/include/message_header_impl.hpp
index 8d0507a..1d3e70b 100644
--- a/implementation/message/include/message_header_impl.hpp
+++ b/implementation/message/include/message_header_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,6 +6,7 @@
#ifndef VSOMEIP_MESSAGE_HEADER_IMPL_HPP
#define VSOMEIP_MESSAGE_HEADER_IMPL_HPP
+#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/enumeration_types.hpp>
#include <vsomeip/serializable.hpp>
@@ -15,32 +15,31 @@ namespace vsomeip {
class message_base;
-class message_header_impl : virtual public serializable {
-
+class message_header_impl: virtual public serializable {
public:
- message_header_impl();
- message_header_impl(const message_header_impl& header);
+ VSOMEIP_EXPORT message_header_impl();
+ VSOMEIP_EXPORT message_header_impl(const message_header_impl& header);
- virtual bool serialize(serializer *_to) const;
- virtual bool deserialize(deserializer *_from);
+ VSOMEIP_EXPORT virtual bool serialize(serializer *_to) const;
+ VSOMEIP_EXPORT virtual bool deserialize(deserializer *_from);
- // internal
- message_base * get_owner() const;
- void set_owner(message_base *_owner);
+ // internal
+ VSOMEIP_EXPORT message_base * get_owner() const;
+ VSOMEIP_EXPORT void set_owner(message_base *_owner);
public:
- service_t service_;
- method_t method_;
- length_t length_;
- client_t client_;
- session_t session_;
- protocol_version_t protocol_version_;
- interface_version_t interface_version_;
- message_type_e type_;
- return_code_e code_;
-
- instance_t instance_;
- message_base *owner_;
+ service_t service_;
+ method_t method_;
+ length_t length_;
+ client_t client_;
+ session_t session_;
+ protocol_version_t protocol_version_;
+ interface_version_t interface_version_;
+ message_type_e type_;
+ return_code_e code_;
+
+ instance_t instance_;
+ message_base *owner_;
};
} // namespace vsomeip
diff --git a/implementation/message/include/message_impl.hpp b/implementation/message/include/message_impl.hpp
index 662b013..7c8902c 100644
--- a/implementation/message/include/message_impl.hpp
+++ b/implementation/message/include/message_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,6 +8,7 @@
#include <memory>
+#include <vsomeip/export.hpp>
#include "message_base_impl.hpp"
namespace vsomeip {
@@ -16,23 +16,23 @@ namespace vsomeip {
class payload;
class message_impl
- : virtual public message,
- virtual public message_base_impl {
+ : virtual public message,
+ virtual public message_base_impl {
public:
- message_impl();
- virtual ~message_impl();
+ VSOMEIP_EXPORT message_impl();
+ VSOMEIP_EXPORT virtual ~message_impl();
- length_t get_length() const;
- void set_length(length_t _length);
+ VSOMEIP_EXPORT length_t get_length() const;
+ VSOMEIP_EXPORT void set_length(length_t _length);
- std::shared_ptr< payload > get_payload() const;
- void set_payload(std::shared_ptr< payload > _payload);
+ VSOMEIP_EXPORT std::shared_ptr< payload > get_payload() const;
+ VSOMEIP_EXPORT void set_payload(std::shared_ptr< payload > _payload);
- bool serialize(serializer *_to) const;
- bool deserialize(deserializer *_from);
+ VSOMEIP_EXPORT bool serialize(serializer *_to) const;
+ VSOMEIP_EXPORT bool deserialize(deserializer *_from);
protected: // members
- std::shared_ptr< payload > payload_;
+ std::shared_ptr< payload > payload_;
};
} // namespace vsomeip
diff --git a/implementation/message/include/payload_impl.hpp b/implementation/message/include/payload_impl.hpp
index 54d7097..2530ac8 100644
--- a/implementation/message/include/payload_impl.hpp
+++ b/implementation/message/include/payload_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,6 +6,7 @@
#ifndef VSOMEIP_PAYLOAD_IMPL_HPP
#define VSOMEIP_PAYLOAD_IMPL_HPP
+#include <vsomeip/export.hpp>
#include <vsomeip/payload.hpp>
namespace vsomeip {
@@ -16,28 +16,28 @@ class deserializer;
class payload_impl: public payload {
public:
- payload_impl();
- payload_impl(const byte_t *_data, uint32_t _size);
- payload_impl(const std::vector< byte_t > &_value);
- payload_impl(const payload_impl& _payload);
- virtual ~payload_impl();
+ VSOMEIP_EXPORT payload_impl();
+ VSOMEIP_EXPORT payload_impl(const byte_t *_data, uint32_t _size);
+ VSOMEIP_EXPORT payload_impl(const std::vector< byte_t > &_value);
+ VSOMEIP_EXPORT payload_impl(const payload_impl& _payload);
+ VSOMEIP_EXPORT virtual ~payload_impl();
- bool operator == (const payload &_other);
+ VSOMEIP_EXPORT bool operator == (const payload &_other);
- byte_t * get_data();
- const byte_t * get_data() const;
- length_t get_length() const;
+ VSOMEIP_EXPORT byte_t * get_data();
+ VSOMEIP_EXPORT const byte_t * get_data() const;
+ VSOMEIP_EXPORT length_t get_length() const;
- void set_capacity(length_t _capacity);
+ VSOMEIP_EXPORT void set_capacity(length_t _capacity);
- void set_data(const byte_t *_data, length_t _length);
- void set_data(const 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< byte_t > &_data);
- bool serialize(serializer *_to) const;
- bool deserialize(deserializer *_from);
+ VSOMEIP_EXPORT bool serialize(serializer *_to) const;
+ VSOMEIP_EXPORT bool deserialize(deserializer *_from);
private:
- std::vector< byte_t > data_;
+ std::vector<byte_t> data_;
};
} // namespace vsomeip
diff --git a/implementation/message/include/serializer.hpp b/implementation/message/include/serializer.hpp
index d07f669..427ee20 100644
--- a/implementation/message/include/serializer.hpp
+++ b/implementation/message/include/serializer.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,43 +8,43 @@
#include <vector>
+#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
namespace vsomeip {
class serializable;
-class serializer
-{
+class VSOMEIP_EXPORT serializer {
public:
- serializer();
- virtual ~serializer();
+ serializer();
+ virtual ~serializer();
- bool serialize(const serializable *_from);
+ bool serialize(const serializable *_from);
- bool serialize(const uint8_t _value);
- bool serialize(const uint16_t _value);
- bool serialize(const uint32_t _value, bool _omit_last_byte = false);
- bool serialize(const uint8_t *_data, uint32_t _length);
+ bool serialize(const uint8_t _value);
+ bool serialize(const uint16_t _value);
+ bool serialize(const uint32_t _value, bool _omit_last_byte = false);
+ bool serialize(const uint8_t *_data, uint32_t _length);
- virtual uint8_t * get_data() const;
- virtual uint32_t get_capacity() const;
- virtual uint32_t get_size() const;
+ virtual uint8_t * get_data() const;
+ virtual uint32_t get_capacity() const;
+ virtual uint32_t get_size() const;
- virtual void create_data(uint32_t _capacity);
- virtual void set_data(uint8_t *_data, uint32_t _capacity);
+ virtual void create_data(uint32_t _capacity);
+ virtual void set_data(uint8_t *_data, uint32_t _capacity);
- virtual void reset();
+ virtual void reset();
#ifdef VSOMEIP_DEBUGGING
- virtual void show();
+ virtual void show();
#endif
private:
- byte_t * data_;
- uint32_t capacity_;
+ byte_t * data_;
+ uint32_t capacity_;
- byte_t *position_;
- uint32_t remaining_;
+ byte_t *position_;
+ uint32_t remaining_;
};
} // namespace vsomeip
diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp
index 28d45c4..fb9cde6 100644
--- a/implementation/message/src/deserializer.cpp
+++ b/implementation/message/src/deserializer.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -193,10 +192,12 @@ void deserializer::reset() {
void deserializer::show() const {
std::stringstream its_message;
its_message << "("
- << std::hex << std::setw(2) << std::setfill('0') << (int)*position_ << ", "
+ << std::hex << std::setw(2) << std::setfill('0')
+ << (int)*position_ << ", "
<< std:: dec << remaining_ << ") ";
for (int i = 0; i < data_.size(); ++i)
- its_message << std::hex << std::setw(2) << std::setfill('0') << (int)data_[i] << " ";
+ its_message << std::hex << std::setw(2) << std::setfill('0')
+ << (int)data_[i] << " ";
VSOMEIP_DEBUG << its_message;
}
#endif
diff --git a/implementation/message/src/message_base_impl.cpp b/implementation/message/src/message_base_impl.cpp
index 5504c2e..c5ab95a 100644
--- a/implementation/message/src/message_base_impl.cpp
+++ b/implementation/message/src/message_base_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,7 +8,8 @@
namespace vsomeip {
-message_base_impl::message_base_impl() {
+message_base_impl::message_base_impl()
+ : is_reliable_(false) {
header_.set_owner(this);
}
@@ -102,4 +102,12 @@ void message_base_impl::set_return_code(return_code_e _code) {
header_.code_ = _code;
}
+bool message_base_impl::is_reliable() const {
+ return is_reliable_;
+}
+
+void message_base_impl::set_reliable(bool _is_reliable) {
+ is_reliable_ = _is_reliable;
+}
+
} // namespace vsomeip
diff --git a/implementation/message/src/message_header_impl.cpp b/implementation/message/src/message_header_impl.cpp
index ce22920..1bde36c 100644
--- a/implementation/message/src/message_header_impl.cpp
+++ b/implementation/message/src/message_header_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,7 +16,7 @@ message_header_impl::message_header_impl()
: service_(0x0), instance_(0x0), method_(0x0),
client_(0x0), session_(0x0),
protocol_version_(0x1), interface_version_(0x0),
- type_(message_type_e::UNKNOWN),
+ type_(message_type_e::MT_UNKNOWN),
code_(return_code_e::E_UNKNOWN) {
};
@@ -77,5 +76,3 @@ void message_header_impl::set_owner(message_base *_owner) {
}
} // namespace vsomeip
-
-
diff --git a/implementation/message/src/message_impl.cpp b/implementation/message/src/message_impl.cpp
index 4be896a..51596a0 100644
--- a/implementation/message/src/message_impl.cpp
+++ b/implementation/message/src/message_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,14 +12,16 @@
namespace vsomeip {
-message_impl::message_impl(): payload_(runtime::get()->create_payload()) {
+message_impl::message_impl()
+ : payload_(runtime::get()->create_payload()) {
}
message_impl::~message_impl() {
}
length_t message_impl::get_length() const {
- return VSOMEIP_SOMEIP_HEADER_SIZE + (payload_ ? payload_->get_length() : 0);
+ return (VSOMEIP_SOMEIP_HEADER_SIZE
+ + (payload_ ? payload_->get_length() : 0));
}
std::shared_ptr< payload > message_impl::get_payload() const {
@@ -32,7 +33,8 @@ void message_impl::set_payload(std::shared_ptr< payload > _payload) {
}
bool message_impl::serialize(serializer *_to) const {
- return (header_.serialize(_to) && (payload_ ? payload_->serialize(_to) : true));
+ return (header_.serialize(_to)
+ && (payload_ ? payload_->serialize(_to) : true));
}
bool message_impl::deserialize(deserializer *_from) {
diff --git a/implementation/message/src/payload_impl.cpp b/implementation/message/src/payload_impl.cpp
index 3541207..62e48e0 100644
--- a/implementation/message/src/payload_impl.cpp
+++ b/implementation/message/src/payload_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/message/src/serializer.cpp b/implementation/message/src/serializer.cpp
index 416e26b..cfa32ec 100644
--- a/implementation/message/src/serializer.cpp
+++ b/implementation/message/src/serializer.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -127,7 +126,8 @@ void serializer::show() {
std::stringstream its_data;
its_data << "SERIALIZED: ";
for (int i = 0; i < position_ - data_; ++i)
- its_data << std::setw(2) << std::setfill('0') << std::hex << (int)data_[i];
+ its_data << std::setw(2) << std::setfill('0')
+ << std::hex << (int)data_[i];
VSOMEIP_DEBUG << its_data.str();
}
#endif
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp
index a251d2c..7332c9a 100644
--- a/implementation/routing/include/event.hpp
+++ b/implementation/routing/include/event.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -26,61 +25,72 @@ class message;
class payload;
class routing_manager;
-class event : public std::enable_shared_from_this<event> {
- public:
- event(routing_manager *_routing);
+class event: public std::enable_shared_from_this<event> {
+public:
+ event(routing_manager *_routing);
- service_t get_service() const;
- void set_service(service_t _service);
+ service_t get_service() const;
+ void set_service(service_t _service);
- instance_t get_instance() const;
- void set_instance(instance_t _instance);
+ instance_t get_instance() const;
+ void set_instance(instance_t _instance);
- event_t get_event() const;
- void set_event(event_t _event);
+ event_t get_event() const;
+ void set_event(event_t _event);
- const std::shared_ptr<payload> get_payload() const;
- void set_payload(std::shared_ptr<payload> _payload);
+ const std::shared_ptr<payload> get_payload() const;
- bool is_field() const;
- void set_field(bool _is_field);
+ void set_payload(std::shared_ptr<payload> _payload, const client_t _client);
- bool is_reliable() const;
- void set_reliable(bool _is_reliable);
+ void set_payload(std::shared_ptr<payload> _payload,
+ const std::shared_ptr<endpoint_definition> _target);
- // SIP_RPC_357
- void set_update_cycle(std::chrono::milliseconds &_cycle);
+ void set_payload(std::shared_ptr<payload> _payload);
+ void unset_payload();
- // SIP_RPC_358
- void set_update_on_change(bool _is_on);
+ bool is_field() const;
+ void set_field(bool _is_field);
- // SIP_RPC_359 (epsilon change) is not supported!
+ bool is_reliable() const;
+ void set_reliable(bool _is_reliable);
+ // SIP_RPC_357
+ void set_update_cycle(std::chrono::milliseconds &_cycle);
- const std::set<eventgroup_t> & get_eventgroups() const;
- void add_eventgroup(eventgroup_t _eventgroup);
- void set_eventgroups(const std::set<eventgroup_t> &_eventgroups);
+ // SIP_RPC_358
+ void set_update_on_change(bool _is_on);
- void notify_one(const std::shared_ptr<endpoint_definition> &_target);
+ // SIP_RPC_359 (epsilon change) is not supported!
- private:
- void update_cbk(boost::system::error_code const &_error);
- void notify();
+ const std::set<eventgroup_t> & get_eventgroups() const;
+ void add_eventgroup(eventgroup_t _eventgroup);
+ void set_eventgroups(const std::set<eventgroup_t> &_eventgroups);
- private:
- routing_manager *routing_;
- std::mutex mutex_;
- std::shared_ptr<message> message_;
+ void notify_one(const std::shared_ptr<endpoint_definition> &_target);
+ void notify_one(client_t _client);
- bool is_field_;
- bool is_reliable_;
+private:
+ void update_cbk(boost::system::error_code const &_error);
+ void notify();
+ void notify(client_t _client, const std::shared_ptr<endpoint_definition> &_target);
- boost::asio::system_timer cycle_timer_;
- std::chrono::milliseconds cycle_;
+private:
+ bool set_payload_helper(std::shared_ptr<payload> _payload);
- bool is_updating_on_change_;
+ routing_manager *routing_;
+ std::mutex mutex_;
+ std::shared_ptr<message> message_;
- std::set<eventgroup_t> eventgroups_;
+ bool is_field_;
+
+ boost::asio::system_timer cycle_timer_;
+ std::chrono::milliseconds cycle_;
+
+ bool is_updating_on_change_;
+
+ std::set<eventgroup_t> eventgroups_;
+
+ bool is_set_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp
index 6c75ca3..558c3b9 100644
--- a/implementation/routing/include/eventgroupinfo.hpp
+++ b/implementation/routing/include/eventgroupinfo.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,6 +11,7 @@
#include <boost/asio/ip/address.hpp>
+#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
namespace vsomeip {
@@ -21,38 +21,41 @@ class event;
class eventgroupinfo {
public:
- eventgroupinfo();
- eventgroupinfo(major_version_t _major, ttl_t _ttl);
- ~eventgroupinfo();
+ VSOMEIP_EXPORT eventgroupinfo();
+ VSOMEIP_EXPORT eventgroupinfo(major_version_t _major, ttl_t _ttl);
+ VSOMEIP_EXPORT ~eventgroupinfo();
- major_version_t get_major() const;
- void set_major(major_version_t _major);
+ VSOMEIP_EXPORT major_version_t get_major() const;
+ VSOMEIP_EXPORT void set_major(major_version_t _major);
- ttl_t get_ttl() const;
- void set_ttl(ttl_t _ttl);
+ VSOMEIP_EXPORT ttl_t get_ttl() const;
+ VSOMEIP_EXPORT void set_ttl(ttl_t _ttl);
- bool is_multicast() const;
- bool get_multicast(boost::asio::ip::address &_address, uint16_t &_port) const;
- void set_multicast(const boost::asio::ip::address &_address, uint16_t _port);
+ VSOMEIP_EXPORT bool is_multicast() const;
+ VSOMEIP_EXPORT bool get_multicast(boost::asio::ip::address &_address,
+ uint16_t &_port) const;
+ VSOMEIP_EXPORT void set_multicast(const boost::asio::ip::address &_address,
+ uint16_t _port);
- const std::set<std::shared_ptr<event> > get_events() const;
- void add_event(std::shared_ptr<event> _event);
+ VSOMEIP_EXPORT const std::set<std::shared_ptr<event> > get_events() const;
+ VSOMEIP_EXPORT void add_event(std::shared_ptr<event> _event);
- const std::set<std::shared_ptr<endpoint_definition> > get_targets() const;
- void add_target(std::shared_ptr<endpoint_definition> _target);
- void del_target(std::shared_ptr<endpoint_definition> _target);
- void clear_targets();
+ VSOMEIP_EXPORT const std::set<
+ std::shared_ptr<endpoint_definition> > get_targets() const;
+ VSOMEIP_EXPORT void add_target(std::shared_ptr<endpoint_definition> _target);
+ VSOMEIP_EXPORT void del_target(std::shared_ptr<endpoint_definition> _target);
+ VSOMEIP_EXPORT void clear_targets();
private:
- major_version_t major_;
- ttl_t ttl_;
+ major_version_t major_;
+ ttl_t ttl_;
- bool is_multicast_;
- boost::asio::ip::address address_;
- uint16_t port_;
+ bool is_multicast_;
+ boost::asio::ip::address address_;
+ uint16_t port_;
- std::set<std::shared_ptr<event> > events_;
- std::set<std::shared_ptr<endpoint_definition> > targets_;
+ std::set<std::shared_ptr<event> > events_;
+ std::set<std::shared_ptr<endpoint_definition> > targets_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp
index 6391890..44a63ac 100644
--- a/implementation/routing/include/routing_manager.hpp
+++ b/implementation/routing/include/routing_manager.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,53 +24,55 @@ class service_info;
class routing_manager {
public:
- virtual ~routing_manager() {};
+ virtual ~routing_manager() {
+ }
- virtual boost::asio::io_service & get_io() = 0;
- virtual client_t get_client() const = 0;
+ virtual boost::asio::io_service & get_io() = 0;
+ virtual client_t get_client() const = 0;
- virtual void init() = 0;
- virtual void start() = 0;
- virtual void stop() = 0;
+ virtual void init() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
- virtual void offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) = 0;
+ virtual void offer_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl) = 0;
- virtual void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance) = 0;
+ virtual void stop_offer_service(client_t _client, service_t _service,
+ instance_t _instance) = 0;
- virtual void request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) = 0;
+ virtual void request_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl, bool _has_selective) = 0;
- virtual void release_service(client_t _client, service_t _service,
- instance_t _instance) = 0;
+ virtual void release_service(client_t _client, service_t _service,
+ instance_t _instance) = 0;
- virtual void subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl) = 0;
+ virtual void subscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl) = 0;
- virtual void unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) = 0;
+ virtual void unsubscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) = 0;
- virtual bool send(client_t _client, std::shared_ptr<message> _message,
- bool _flush, bool _reliable) = 0;
+ virtual bool send(client_t _client, std::shared_ptr<message> _message,
+ bool _flush) = 0;
- virtual bool send(client_t _client, const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush, bool _reliable) = 0;
+ virtual bool send(client_t _client, const byte_t *_data, uint32_t _size,
+ instance_t _instance, bool _flush, bool _reliable) = 0;
- virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message>) = 0;
+ virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message>) = 0;
- virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size) = 0;
+ virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ const byte_t *_data, uint32_t _size) = 0;
- virtual void notify(service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload) = 0;
+ virtual void notify(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload) = 0;
+
+ virtual void notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload, client_t _client) = 0;
- virtual bool is_available(service_t _service,
- instance_t _instance) const = 0;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_adapter.hpp b/implementation/routing/include/routing_manager_adapter.hpp
index 0dea6c2..fc0e55d 100644
--- a/implementation/routing/include/routing_manager_adapter.hpp
+++ b/implementation/routing/include/routing_manager_adapter.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,10 +12,11 @@ class routing_manager;
class routing_manager_adapter {
public:
- virtual ~routing_manager_adapter() {};
+ virtual ~routing_manager_adapter() {
+ }
- virtual routing_manager * get_manager() = 0;
- virtual void process_command(const byte_t *_data, length_t _length) = 0;
+ virtual routing_manager * get_manager() = 0;
+ virtual void process_command(const byte_t *_data, length_t _length) = 0;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp
index 58a8ce9..a80b86d 100644
--- a/implementation/routing/include/routing_manager_host.hpp
+++ b/implementation/routing/include/routing_manager_host.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -20,17 +19,21 @@ class message;
class routing_manager_host {
public:
- virtual ~routing_manager_host() {};
-
- virtual client_t get_client() const = 0;
- virtual const std::string & get_name() const = 0;
- virtual std::shared_ptr< configuration > get_configuration() const = 0;
- virtual boost::asio::io_service & get_io() = 0;
-
- virtual void on_availability(service_t _service, instance_t _instance, bool _is_available) const = 0;
- virtual void on_event(event_type_e _event) = 0;
- virtual void on_message(std::shared_ptr< message > _message) = 0;
- virtual void on_error(error_code_e _error) = 0;
+ virtual ~routing_manager_host() {
+ }
+
+ virtual client_t get_client() const = 0;
+ virtual const std::string & get_name() const = 0;
+ virtual std::shared_ptr<configuration> get_configuration() const = 0;
+ virtual boost::asio::io_service & get_io() = 0;
+
+ virtual void on_availability(service_t _service, instance_t _instance,
+ bool _is_available) const = 0;
+ virtual void on_event(event_type_e _event) = 0;
+ virtual void on_message(std::shared_ptr<message> _message) = 0;
+ virtual void on_error(error_code_e _error) = 0;
+ virtual bool on_subscription(service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ client_t _client, bool _subscribed) = 0;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp
index 66ea31f..b2d5200 100644
--- a/implementation/routing/include/routing_manager_impl.hpp
+++ b/implementation/routing/include/routing_manager_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -11,6 +10,7 @@
#include <memory>
#include <mutex>
#include <vector>
+#include <unordered_set>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/io_service.hpp>
@@ -44,191 +44,212 @@ class service_discovery;
// TODO: encapsulate common parts of classes "routing_manager_impl"
// and "routing_manager_proxy" into a base class.
-class routing_manager_impl:
- public routing_manager,
- public endpoint_host,
- public routing_manager_stub_host,
- public sd::service_discovery_host,
- public std::enable_shared_from_this<routing_manager_impl> {
+class routing_manager_impl: public routing_manager,
+ public endpoint_host,
+ public routing_manager_stub_host,
+ public sd::service_discovery_host,
+ public std::enable_shared_from_this<routing_manager_impl> {
public:
- routing_manager_impl(routing_manager_host *_host);
- ~routing_manager_impl();
-
- boost::asio::io_service & get_io();
- client_t get_client() const;
- std::shared_ptr<configuration> get_configuration() const;
-
- void init();
- void start();
- void stop();
-
- void offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
-
- void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance);
-
- void request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
-
- void release_service(client_t _client, service_t _service,
- instance_t _instance);
-
- void subscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
-
- void unsubscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup);
-
- bool send(client_t _client, std::shared_ptr<message> _message, bool _flush,
- bool _reliable);
-
- bool send(client_t _client, const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush, bool _reliable);
-
- bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message);
-
- bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size);
-
- void notify(service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload);
-
- bool is_available(service_t _service, instance_t _instance) const;
-
- // interface to stub
- std::shared_ptr<endpoint> create_local(client_t _client);
- std::shared_ptr<endpoint> find_local(client_t _client);
- std::shared_ptr<endpoint> find_or_create_local(client_t _client);
- void remove_local(client_t _client);
- std::shared_ptr<endpoint> find_local(service_t _service,
- instance_t _instance);
- void on_stop_offer_service(service_t _service, instance_t _instance);
-
- // interface "endpoint_host"
- std::shared_ptr<endpoint> find_remote_client(service_t _service,
- instance_t _instance,
- bool _reliable);
- void on_connect(std::shared_ptr<endpoint> _endpoint);
- void on_disconnect(std::shared_ptr<endpoint> _endpoint);
- void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
- void on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size);
-
- // interface "service_discovery_host"
- typedef std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_t;
- const servicegroups_t & get_servicegroups() const;
- std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) const;
- services_t get_offered_services(const std::string &_name) const;
- void create_service_discovery_endpoint(const std::string &_address,
- uint16_t _port, bool _reliable);
- void init_routing_info();
- void add_routing_info(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl,
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable);
- void del_routing_info(service_t _service, instance_t _instance,
- bool _reliable);
-
- void init_event_routing_info();
- void on_subscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _subscriber,
- std::shared_ptr<endpoint_definition> _target);
- void on_unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _target);
- void on_subscribe_ack(service_t _service, instance_t _instance,
- const boost::asio::ip::address &_address, uint16_t _port);
+ routing_manager_impl(routing_manager_host *_host);
+ ~routing_manager_impl();
+
+ boost::asio::io_service & get_io();
+ client_t get_client() const;
+ std::shared_ptr<configuration> get_configuration() const;
+
+ void init();
+ void start();
+ void stop();
+
+ void offer_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl);
+
+ void stop_offer_service(client_t _client, service_t _service,
+ instance_t _instance);
+
+ void request_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl, bool _has_selective);
+
+ void release_service(client_t _client, service_t _service,
+ instance_t _instance);
+
+ void subscribe(client_t _client, service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
+
+ void unsubscribe(client_t _client, service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup);
+
+ bool send(client_t _client, std::shared_ptr<message> _message, bool _flush);
+
+ bool send(client_t _client, const byte_t *_data, uint32_t _size,
+ instance_t _instance, bool _flush, bool _reliable);
+
+ bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message> _message);
+
+ bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ const byte_t *_data, uint32_t _size);
+
+ void notify(service_t _service, instance_t _instance, event_t _event,
+ std::shared_ptr<payload> _payload);
+
+ void notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload, client_t _client);
+
+ // interface to stub
+ std::shared_ptr<endpoint> create_local(client_t _client);
+ std::shared_ptr<endpoint> find_local(client_t _client);
+ std::shared_ptr<endpoint> find_or_create_local(client_t _client);
+ void remove_local(client_t _client);
+ std::shared_ptr<endpoint> find_local(service_t _service,
+ instance_t _instance);
+ void on_stop_offer_service(service_t _service, instance_t _instance);
+
+ // interface "endpoint_host"
+ std::shared_ptr<endpoint> find_or_create_remote_client(service_t _service,
+ instance_t _instance,
+ bool _reliable, client_t _client);
+ void on_connect(std::shared_ptr<endpoint> _endpoint);
+ void on_disconnect(std::shared_ptr<endpoint> _endpoint);
+ void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
+ void on_message(service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _size, bool _reliable);
+
+ // interface "service_discovery_host"
+ typedef std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_t;
+ const servicegroups_t & get_servicegroups() const;
+ std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) const;
+ services_t get_offered_services(const std::string &_name) const;
+ void create_service_discovery_endpoint(const std::string &_address,
+ uint16_t _port, bool _reliable);
+ void init_routing_info();
+ void add_routing_info(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl,
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable);
+ void del_routing_info(service_t _service, instance_t _instance,
+ bool _reliable);
+
+ void on_subscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup,
+ std::shared_ptr<endpoint_definition> _subscriber,
+ std::shared_ptr<endpoint_definition> _target);
+ void on_unsubscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup,
+ std::shared_ptr<endpoint_definition> _target);
+ void on_subscribe_ack(service_t _service, instance_t _instance,
+ const boost::asio::ip::address &_address, uint16_t _port);
+
+ void init_event_routing_info();
private:
- bool deliver_message(const byte_t *_data, length_t _length,
- instance_t _instance);
- bool send_local(std::shared_ptr<endpoint> &_target, client_t _client,
- const byte_t *_data, uint32_t _size,
- instance_t _instance,
- bool _flush, bool _reliable) const;
-
- client_t find_local_client(service_t _service, instance_t _instance);
- std::set<client_t> find_local_clients(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup);
- instance_t find_instance(service_t _service, endpoint *_endpoint);
-
- std::shared_ptr<serviceinfo> find_service(service_t _service,
- instance_t _instance) const;
- std::shared_ptr<serviceinfo> create_service(service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
-
- std::shared_ptr<endpoint> create_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable);
- std::shared_ptr<endpoint> find_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable);
- std::shared_ptr<endpoint> find_or_create_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable);
-
- std::shared_ptr<endpoint> create_server_endpoint(uint16_t _port,
- bool _reliable);
- std::shared_ptr<endpoint> find_server_endpoint(uint16_t _port,
- bool _reliable);
- std::shared_ptr<endpoint> find_or_create_server_endpoint(uint16_t _port,
- bool _reliable);
-
- std::set<std::shared_ptr<event> > find_events(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup);
- std::shared_ptr<event> find_event(service_t _service, instance_t _instance,
- event_t _event) const;
+ bool deliver_message(const byte_t *_data, length_t _length,
+ instance_t _instance, bool _reliable);
+ bool send_local(
+ std::shared_ptr<endpoint> &_target, client_t _client,
+ const byte_t *_data, uint32_t _size, instance_t _instance,
+ bool _flush, bool _reliable) const;
+
+ client_t find_local_client(service_t _service, instance_t _instance);
+ std::set<client_t> find_local_clients(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup);
+ instance_t find_instance(service_t _service, endpoint *_endpoint);
+
+ std::shared_ptr<serviceinfo> find_service(service_t _service,
+ instance_t _instance) const;
+ std::shared_ptr<serviceinfo> create_service(service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl);
+
+ std::shared_ptr<endpoint> create_client_endpoint(
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable, client_t _client);
+ std::shared_ptr<endpoint> find_client_endpoint(
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable, client_t _client);
+ std::shared_ptr<endpoint> find_or_create_client_endpoint(
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable, client_t _client);
+
+ std::shared_ptr<endpoint> create_server_endpoint(uint16_t _port,
+ bool _reliable);
+ std::shared_ptr<endpoint> find_server_endpoint(uint16_t _port,
+ bool _reliable);
+ std::shared_ptr<endpoint> find_or_create_server_endpoint(uint16_t _port,
+ bool _reliable);
+
+ std::set<std::shared_ptr<event> > find_events(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup);
+ std::shared_ptr<event> find_event(service_t _service, instance_t _instance,
+ event_t _event) const;
+
+ std::shared_ptr<endpoint> find_remote_client(service_t _service,
+ instance_t _instance,
+ bool _reliable, client_t _client);
+
+ std::shared_ptr<endpoint> create_remote_client(service_t _service,
+ instance_t _instance,
+ bool _reliable, client_t _client);
private:
- boost::asio::io_service &io_;
- routing_manager_host *host_;
+ void send_subscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl);
- std::shared_ptr<configuration> configuration_;
+ void send_unsubscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup);
- std::shared_ptr<deserializer> deserializer_;
- std::shared_ptr<serializer> serializer_;
+ boost::asio::io_service &io_;
+ routing_manager_host *host_;
- std::shared_ptr<routing_manager_stub> stub_;
- std::shared_ptr<sd::service_discovery> discovery_;
+ std::shared_ptr<configuration> configuration_;
- // Routing info
+ std::shared_ptr<deserializer> deserializer_;
+ std::shared_ptr<serializer> serializer_;
- // Local
- std::map<client_t, std::shared_ptr<endpoint> > local_clients_;
- std::map<service_t, std::map<instance_t, client_t> > local_services_;
+ std::shared_ptr<routing_manager_stub> stub_;
+ std::shared_ptr<sd::service_discovery> discovery_;
- // Server endpoints for local services
- std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > server_endpoints_;
- std::map<service_t, std::map<endpoint *, instance_t> > service_instances_;
+ // Routing info
- // Client endpoints for remote services
- std::map<boost::asio::ip::address,
- std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > > client_endpoints_;
- std::map<service_t,
- std::map<instance_t, std::map<bool, std::shared_ptr<endpoint> > > > remote_services_;
+ // Local
+ std::map<client_t, std::shared_ptr<endpoint> > local_clients_;
+ std::map<service_t, std::map<instance_t, client_t> > local_services_;
- // Servicegroups
- std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_;
- std::map<service_t, std::map<instance_t, std::shared_ptr<serviceinfo> > > services_;
+ // Server endpoints for local services
+ std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > server_endpoints_;
+ std::map<service_t, std::map<endpoint *, instance_t> > service_instances_;
- // Eventgroups
- std::map<service_t,
- std::map<instance_t,
- std::map<eventgroup_t, std::shared_ptr<eventgroupinfo> > > > eventgroups_;
- std::map<service_t,
- std::map<instance_t, std::map<event_t, std::shared_ptr<event> > > > events_;
- std::map<service_t,
- std::map<instance_t, std::map<eventgroup_t, std::set<client_t> > > > eventgroup_clients_;
+ // Client endpoints for remote services
+ std::map<boost::asio::ip::address,
+ std::map<uint16_t, std::map<client_t, std::map<bool, std::shared_ptr<endpoint> > > > > client_endpoints_;
+ std::map<service_t,
+ std::map<instance_t, std::map<client_t, std::map<bool, std::shared_ptr<endpoint> > > > >remote_services_;
- // Mutexes
- mutable std::recursive_mutex endpoint_mutex_;
- std::mutex serialize_mutex_;
+ // Servicegroups
+ std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_;
+ std::map<service_t, std::map<instance_t, std::shared_ptr<serviceinfo> > > services_;
+
+ // Eventgroups
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<eventgroup_t, std::shared_ptr<eventgroupinfo> > > > eventgroups_;
+ std::map<service_t,
+ std::map<instance_t, std::map<event_t, std::shared_ptr<event> > > > events_;
+ std::map<service_t,
+ std::map<instance_t, std::map<eventgroup_t, std::set<client_t> > > > eventgroup_clients_;
+
+ // Mutexes
+ mutable std::recursive_mutex endpoint_mutex_;
+ mutable std::mutex local_mutex_;
+ std::mutex serialize_mutex_;
+
+ std::map<client_t, std::shared_ptr<endpoint_definition>> remote_subscriber_map_;
+
+ std::unordered_set<client_t> specific_endpoint_clients;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp
index ea9c0e0..a142db8 100644
--- a/implementation/routing/include/routing_manager_proxy.hpp
+++ b/implementation/routing/include/routing_manager_proxy.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,96 +24,146 @@ class routing_manager_host;
// and "routing_manager_proxy" into a base class.
class routing_manager_proxy: public routing_manager,
- public endpoint_host,
- public std::enable_shared_from_this<routing_manager_proxy> {
+ public endpoint_host,
+ public std::enable_shared_from_this<routing_manager_proxy> {
public:
- routing_manager_proxy(routing_manager_host *_host);
- virtual ~routing_manager_proxy();
+ routing_manager_proxy(routing_manager_host *_host);
+ virtual ~routing_manager_proxy();
- boost::asio::io_service & get_io();
- client_t get_client() const;
+ boost::asio::io_service & get_io();
+ client_t get_client() const;
- void init();
- void start();
- void stop();
+ void init();
+ void start();
+ void stop();
- void offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
+ void offer_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl);
- void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance);
+ void stop_offer_service(client_t _client, service_t _service,
+ instance_t _instance);
- void request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
+ void request_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl, bool _has_selective);
- void release_service(client_t _client, service_t _service,
- instance_t _instance);
+ void release_service(client_t _client, service_t _service,
+ instance_t _instance);
- void subscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
+ void subscribe(client_t _client, service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
- void unsubscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup);
+ void unsubscribe(client_t _client, service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup);
- bool send(client_t _client, std::shared_ptr<message> _message, bool _flush,
- bool _reliable);
+ bool send(client_t _client, std::shared_ptr<message> _message, bool _flush);
- bool send(client_t _client, const byte_t *_data, uint32_t _size,
- instance_t _instance, bool _flush = true, bool _reliable = false);
+ bool send(client_t _client, const byte_t *_data, uint32_t _size,
+ instance_t _instance, bool _flush = true, bool _reliable = false);
- bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message);
+ bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message> _message);
- bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size);
+ bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ const byte_t *_data, uint32_t _size);
- void notify(service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload);
+ void notify(service_t _service, instance_t _instance, event_t _event,
+ std::shared_ptr<payload> _payload);
- void on_connect(std::shared_ptr<endpoint> _endpoint);
- void on_disconnect(std::shared_ptr<endpoint> _endpoint);
- void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
+ void notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload, client_t _client);
- void on_routing_info(const byte_t *_data, uint32_t _size);
+ void on_connect(std::shared_ptr<endpoint> _endpoint);
+ void on_disconnect(std::shared_ptr<endpoint> _endpoint);
+ void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
- bool is_available(service_t _service, instance_t _instance) const;
+ void on_routing_info(const byte_t *_data, uint32_t _size);
- std::shared_ptr<endpoint> find_local(client_t _client);
- std::shared_ptr<endpoint> find_local(service_t _service,
- instance_t _instance);
- std::shared_ptr<endpoint> find_or_create_local(client_t _client);
- void remove_local(client_t _client);
+ std::shared_ptr<endpoint> find_local(client_t _client);
+ std::shared_ptr<endpoint> find_local(service_t _service,
+ instance_t _instance);
+ std::shared_ptr<endpoint> find_or_create_local(client_t _client);
+ void remove_local(client_t _client);
private:
- void register_application();
- void deregister_application();
+ void register_application();
+ void deregister_application();
- std::shared_ptr<endpoint> create_local(client_t _client);
+ std::shared_ptr<endpoint> create_local(client_t _client);
- void send_pong() const;
+ void send_pong() const;
+ void send_offer_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl);
+ void send_subscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl);
-private:
- boost::asio::io_service &io_;
- bool is_connected_;
- bool is_started_;
- event_type_e state_;
- routing_manager_host *host_;
- client_t client_; // store locally as it is needed in each message
-
- std::shared_ptr<serializer> serializer_;
- std::shared_ptr<deserializer> deserializer_;
-
- std::shared_ptr<endpoint> sender_; // --> stub
- std::shared_ptr<endpoint> receiver_; // --> from everybody
+ void send_request_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl, bool _is_selective);
- std::map<client_t, std::shared_ptr<endpoint> > local_endpoints_;
- std::map<service_t, std::map<instance_t, client_t> > local_services_;
-
- std::mutex send_mutex_;
- std::mutex serialize_mutex_;
- std::mutex deserialize_mutex_;
+private:
+ boost::asio::io_service &io_;bool is_connected_;bool is_started_;
+ event_type_e state_;
+ routing_manager_host *host_;
+ client_t client_; // store locally as it is needed in each message
+
+ std::shared_ptr<serializer> serializer_;
+ std::shared_ptr<deserializer> deserializer_;
+
+ std::shared_ptr<endpoint> sender_; // --> stub
+ std::shared_ptr<endpoint> receiver_; // --> from everybody
+
+ std::map<client_t, std::shared_ptr<endpoint> > local_endpoints_;
+ std::map<service_t, std::map<instance_t, client_t> > local_services_;
+
+ struct service_data_t {
+ service_t service_;
+ instance_t instance_;
+ major_version_t major_;
+ minor_version_t minor_;
+ ttl_t ttl_;
+
+ bool operator<(const service_data_t &_other) const {
+ return (service_ < _other.service_
+ || (service_ == _other.service_
+ && instance_ < _other.instance_));
+ }
+ };
+ std::set<service_data_t> pending_offers_;
+ std::set<service_data_t> pending_requests_;
+
+ struct eventgroup_data_t {
+ service_t service_;
+ instance_t instance_;
+ eventgroup_t eventgroup_;
+ major_version_t major_;
+ ttl_t ttl_;
+
+ bool operator<(const eventgroup_data_t &_other) const {
+ return (service_ < _other.service_
+ || (service_ == _other.service_
+ && instance_ < _other.instance_)
+ || (service_ == _other.service_
+ && instance_ == _other.instance_
+ && eventgroup_ < _other.eventgroup_));
+ }
+ };
+ std::set<eventgroup_data_t> pending_subscriptions_;
+
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<event_t,
+ std::shared_ptr<message> > > > pending_notifications_;
+
+ std::mutex send_mutex_;
+ std::mutex serialize_mutex_;
+ std::mutex deserialize_mutex_;
+ std::mutex pending_mutex_;
+
+ bool is_selective_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp
index aef8992..c261303 100644
--- a/implementation/routing/include/routing_manager_stub.hpp
+++ b/implementation/routing/include/routing_manager_stub.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014-2015 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -22,59 +21,55 @@ namespace vsomeip {
class routing_manager_stub_host;
-class routing_manager_stub:
- public endpoint_host,
- public std::enable_shared_from_this< routing_manager_stub > {
+class routing_manager_stub: public endpoint_host,
+ public std::enable_shared_from_this<routing_manager_stub> {
public:
- routing_manager_stub(routing_manager_stub_host *_host);
- virtual ~routing_manager_stub();
+ routing_manager_stub(routing_manager_stub_host *_host);
+ virtual ~routing_manager_stub();
- void init();
- void start();
- void stop();
+ void init();
+ void start();
+ void stop();
- void on_connect(std::shared_ptr< endpoint > _endpoint);
- void on_disconnect(std::shared_ptr< endpoint > _endpoint);
- void on_message(const byte_t *_data, const length_t _length, endpoint *_receiver);
+ void on_connect(std::shared_ptr<endpoint> _endpoint);
+ void on_disconnect(std::shared_ptr<endpoint> _endpoint);
+ void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
- void on_offer_service(client_t _client, service_t _service, instance_t _instance);
- void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance);
+ void on_offer_service(client_t _client, service_t _service,
+ instance_t _instance);
+ void on_stop_offer_service(client_t _client, service_t _service,
+ instance_t _instance);
private:
- void broadcast(std::vector< byte_t > &_command) const;
+ void broadcast(std::vector<byte_t> &_command) const;
- void on_register_application(client_t _client);
- void on_deregister_application(client_t _client);
+ void on_register_application(client_t _client);
+ void on_deregister_application(client_t _client);
- void broadcast_routing_info();
- void send_routing_info(client_t _client);
+ void broadcast_routing_info();
+ void send_routing_info(client_t _client);
- void broadcast_ping() const;
- void on_pong(client_t _client);
- void start_watchdog();
- void check_watchdog();
- void send_application_lost(std::list< client_t > &_lost);
+ void broadcast_ping() const;
+ void on_pong(client_t _client);
+ void start_watchdog();
+ void check_watchdog();
+ void send_application_lost(std::list<client_t> &_lost);
private:
- boost::asio::io_service &io_;
- boost::asio::system_timer watchdog_timer_;
+ boost::asio::io_service &io_;
+ boost::asio::system_timer watchdog_timer_;
- routing_manager_stub_host *host_;
+ routing_manager_stub_host *host_;
- std::string endpoint_path_;
- std::shared_ptr< endpoint > endpoint_;
+ std::string endpoint_path_;
+ std::shared_ptr<endpoint> endpoint_;
- std::map< client_t,
- std::pair< uint8_t,
- std::map< service_t,
- std::set< instance_t > > > > routing_info_;
- mutable std::mutex routing_info_mutex_;
+ std::map<client_t,
+ std::pair<uint8_t, std::map<service_t, std::set<instance_t> > > > routing_info_;
+ mutable std::mutex routing_info_mutex_;
};
} // namespace vsomeip
#endif // VSOMEIP_ROUTING_MANAGER_STUB
-
-
-
diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp
index e214d63..049bc13 100644
--- a/implementation/routing/include/routing_manager_stub_host.hpp
+++ b/implementation/routing/include/routing_manager_stub_host.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,44 +12,45 @@ namespace vsomeip {
class routing_manager_stub_host {
public:
- virtual ~routing_manager_stub_host() {};
+ virtual ~routing_manager_stub_host() {
+ }
- virtual void offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) = 0;
+ virtual void offer_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl) = 0;
- virtual void stop_offer_service(client_t _client, service_t _service,
- instance_t _instance) = 0;
+ virtual void stop_offer_service(client_t _client, service_t _service,
+ instance_t _instance) = 0;
- virtual void request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) = 0;
+ virtual void request_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl, bool _has_selective) = 0;
- virtual void release_service(client_t _client, service_t _service,
- instance_t _instance) = 0;
+ virtual void release_service(client_t _client, service_t _service,
+ instance_t _instance) = 0;
- virtual void subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl) = 0;
+ virtual void subscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl) = 0;
- virtual void unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) = 0;
+ virtual void unsubscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) = 0;
- virtual void on_message(service_t _service, instance_t _instance,
- const byte_t *_data, length_t _size) = 0;
+ virtual void on_message(service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _size, bool _reliable) = 0;
- virtual void on_stop_offer_service(service_t _service,
- instance_t _instance) = 0;
+ virtual void on_stop_offer_service(service_t _service,
+ instance_t _instance) = 0;
- virtual std::shared_ptr<endpoint> find_local(client_t _client) = 0;
- virtual std::shared_ptr<endpoint> find_local(service_t _service,
- instance_t _instance) = 0;
- virtual std::shared_ptr<endpoint> find_or_create_local(
- client_t _client) = 0;
- virtual void remove_local(client_t _client) = 0;
+ virtual std::shared_ptr<endpoint> find_local(client_t _client) = 0;
+ virtual std::shared_ptr<endpoint> find_local(service_t _service,
+ instance_t _instance) = 0;
+ virtual std::shared_ptr<endpoint> find_or_create_local(
+ client_t _client) = 0;
+ virtual void remove_local(client_t _client) = 0;
- virtual boost::asio::io_service & get_io() = 0;
- virtual client_t get_client() const = 0;
+ virtual boost::asio::io_service & get_io() = 0;
+ virtual client_t get_client() const = 0;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/servicegroup.hpp b/implementation/routing/include/servicegroup.hpp
index a59be62..6014df1 100644
--- a/implementation/routing/include/servicegroup.hpp
+++ b/implementation/routing/include/servicegroup.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,19 +18,22 @@ class serviceinfo;
class servicegroup {
public:
- servicegroup(const std::string &_name);
- virtual ~servicegroup();
+ servicegroup(const std::string &_name, bool _is_local);
+ virtual ~servicegroup();
- std::string get_name() const;
+ std::string get_name() const;
+ bool is_local() const;
- bool add_service(service_t _service, instance_t _instance, std::shared_ptr< serviceinfo > _info);
- bool remove_service(service_t _service, instance_t _instance);
+ bool add_service(service_t _service, instance_t _instance,
+ std::shared_ptr<serviceinfo> _info);
+ bool remove_service(service_t _service, instance_t _instance);
- services_t get_services() const;
+ services_t get_services() const;
private:
- std::string name_;
- services_t services_;
+ std::string name_;
+ bool is_local_;
+ services_t services_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp
index 09b5486..a98127e 100644
--- a/implementation/routing/include/serviceinfo.hpp
+++ b/implementation/routing/include/serviceinfo.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -11,6 +10,7 @@
#include <set>
#include <string>
+#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
namespace vsomeip {
@@ -20,48 +20,50 @@ class servicegroup;
class serviceinfo {
public:
- serviceinfo(major_version_t _major, minor_version_t _minor, ttl_t _ttl);
- ~serviceinfo();
+ VSOMEIP_EXPORT serviceinfo(major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl);
+ VSOMEIP_EXPORT ~serviceinfo();
- servicegroup * get_group() const;
- void set_group(servicegroup *_group);
+ VSOMEIP_EXPORT servicegroup * get_group() const;
+ VSOMEIP_EXPORT void set_group(servicegroup *_group);
- major_version_t get_major() const;
- minor_version_t get_minor() const;
+ VSOMEIP_EXPORT major_version_t get_major() const;
+ VSOMEIP_EXPORT minor_version_t get_minor() const;
- ttl_t get_ttl() const;
- void set_ttl(ttl_t _ttl);
+ VSOMEIP_EXPORT ttl_t get_ttl() const;
+ VSOMEIP_EXPORT void set_ttl(ttl_t _ttl);
- std::shared_ptr<endpoint> get_endpoint(bool _reliable) const;
- void set_endpoint(std::shared_ptr<endpoint> _endpoint, bool _reliable);
+ VSOMEIP_EXPORT std::shared_ptr<endpoint> get_endpoint(bool _reliable) const;
+ VSOMEIP_EXPORT void set_endpoint(std::shared_ptr<endpoint> _endpoint,
+ bool _reliable);
- const std::string & get_multicast_address() const;
- void set_multicast_address(const std::string &_multicast);
+ VSOMEIP_EXPORT const std::string & get_multicast_address() const;
+ VSOMEIP_EXPORT void set_multicast_address(const std::string &_multicast);
- uint16_t get_multicast_port() const;
- void set_multicast_port(uint16_t _port);
+ VSOMEIP_EXPORT uint16_t get_multicast_port() const;
+ VSOMEIP_EXPORT void set_multicast_port(uint16_t _port);
- eventgroup_t get_multicast_group() const;
- void set_multicast_group(eventgroup_t _multicast_group);
+ VSOMEIP_EXPORT eventgroup_t get_multicast_group() const;
+ VSOMEIP_EXPORT void set_multicast_group(eventgroup_t _multicast_group);
- void add_client(client_t _client);
- void remove_client(client_t _client);
+ VSOMEIP_EXPORT void add_client(client_t _client);
+ VSOMEIP_EXPORT void remove_client(client_t _client);
private:
- servicegroup *group_;
+ servicegroup *group_;
- major_version_t major_;
- minor_version_t minor_;
- ttl_t ttl_;
+ major_version_t major_;
+ minor_version_t minor_;
+ ttl_t ttl_;
- std::shared_ptr<endpoint> reliable_;
- std::shared_ptr<endpoint> unreliable_;
+ std::shared_ptr<endpoint> reliable_;
+ std::shared_ptr<endpoint> unreliable_;
- std::string multicast_address_;
- uint16_t multicast_port_;
- eventgroup_t multicast_group_;
+ std::string multicast_address_;
+ uint16_t multicast_port_;
+ eventgroup_t multicast_group_;
- std::set<client_t> requesters_;
+ std::set<client_t> requesters_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/types.hpp b/implementation/routing/include/types.hpp
index ad28c01..60b97bc 100644
--- a/implementation/routing/include/types.hpp
+++ b/implementation/routing/include/types.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,15 +16,16 @@ namespace vsomeip {
class serviceinfo;
typedef std::map<service_t,
- std::map<instance_t,
- std::shared_ptr<serviceinfo> > > services_t;
+ std::map<instance_t,
+ std::shared_ptr<serviceinfo> > > services_t;
class eventgroupinfo;
typedef std::map<service_t,
- std::map<instance_t,
- std::map<eventgroup_t,
- std::shared_ptr<eventgroupinfo> > > > eventgroups_t;
+ std::map<instance_t,
+ std::map<eventgroup_t,
+ std::shared_ptr<
+ eventgroupinfo> > > > eventgroups_t;
}
// namespace vsomeip
diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp
index ffaec8a..c3dc258 100644
--- a/implementation/routing/src/event.cpp
+++ b/implementation/routing/src/event.cpp
@@ -1,11 +1,8 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <iomanip>
-
#include <vsomeip/defines.hpp>
#include <vsomeip/logger.hpp>
#include <vsomeip/message.hpp>
@@ -15,75 +12,68 @@
#include "../include/event.hpp"
#include "../include/routing_manager.hpp"
#include "../../configuration/include/internal.hpp"
+#include "../../message/include/payload_impl.hpp"
namespace vsomeip {
event::event(routing_manager *_routing) :
- routing_(_routing), message_(runtime::get()->create_notification()), cycle_timer_(
- _routing->get_io()), is_updating_on_change_(true) {
+ routing_(_routing),
+ message_(runtime::get()->create_notification()),
+ cycle_timer_(_routing->get_io()),
+ is_updating_on_change_(true),
+ is_set_(false) {
}
service_t event::get_service() const {
- return (message_->get_service());
+ return (message_->get_service());
}
void event::set_service(service_t _service) {
- message_->set_service(_service);
+ message_->set_service(_service);
}
instance_t event::get_instance() const {
- return (message_->get_instance());
+ return (message_->get_instance());
}
void event::set_instance(instance_t _instance) {
- message_->set_instance(_instance);
+ message_->set_instance(_instance);
}
event_t event::get_event() const {
- return (message_->get_method());
+ return (message_->get_method());
}
void event::set_event(event_t _event) {
- message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit
+ message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit
}
bool event::is_field() const {
- return (is_field_);
+ return (is_field_);
}
void event::set_field(bool _is_field) {
- is_field_ = _is_field;
+ is_field_ = _is_field;
}
bool event::is_reliable() const {
- return is_reliable_;
+ return message_->is_reliable();
}
void event::set_reliable(bool _is_reliable) {
- is_reliable_ = _is_reliable;
+ message_->set_reliable(_is_reliable);
}
const std::shared_ptr<payload> event::get_payload() const {
- return (message_->get_payload());
+ return (message_->get_payload());
}
void event::set_payload(std::shared_ptr<payload> _payload) {
- std::shared_ptr<payload> its_payload = message_->get_payload();
- bool is_change = (its_payload->get_length() != _payload->get_length());
- if (!is_change) {
- std::size_t its_pos = 0;
- const byte_t *its_old_data = its_payload->get_data();
- const byte_t *its_new_data = _payload->get_data();
- while (!is_change && its_pos < its_payload->get_length()) {
- is_change = (*its_old_data++ != *its_new_data++);
- its_pos++;
- }
- }
-
- if (is_change) {
+ if (set_payload_helper(_payload)) {
std::shared_ptr<payload> its_new_payload
= runtime::get()->create_payload(
_payload->get_data(), _payload->get_length());
+
message_->set_payload(its_new_payload);
if (is_updating_on_change_) {
notify();
@@ -91,52 +81,109 @@ void event::set_payload(std::shared_ptr<payload> _payload) {
}
}
+void event::set_payload(std::shared_ptr<payload> _payload, client_t _client) {
+ set_payload_helper(_payload);
+ std::shared_ptr<payload> its_new_payload
+ = runtime::get()->create_payload(
+ _payload->get_data(), _payload->get_length());
+
+ message_->set_payload(its_new_payload);
+ if (is_updating_on_change_) {
+ notify_one(_client);
+ }
+}
+
+void event::set_payload(std::shared_ptr<payload> _payload,
+ const std::shared_ptr<endpoint_definition> _target) {
+
+ set_payload_helper(_payload);
+ std::shared_ptr<payload> its_new_payload
+ = runtime::get()->create_payload(
+ _payload->get_data(), _payload->get_length());
+
+ message_->set_payload(its_new_payload);
+ if (is_updating_on_change_) {
+ notify_one(_target);
+ }
+}
+
+void event::unset_payload() {
+ is_set_ = false;
+ message_->set_payload(std::make_shared<payload_impl>());
+}
+
void event::set_update_on_change(bool _is_active) {
- is_updating_on_change_ = _is_active;
+ is_updating_on_change_ = _is_active;
}
void event::set_update_cycle(std::chrono::milliseconds &_cycle) {
- cycle_ = _cycle;
- cycle_timer_.cancel();
-
- if (std::chrono::milliseconds::zero() != _cycle) {
- cycle_timer_.expires_from_now(cycle_);
- std::function<void(boost::system::error_code const &)> its_handler =
- std::bind(&event::update_cbk, shared_from_this(),
- std::placeholders::_1);
- cycle_timer_.async_wait(its_handler);
- }
+ cycle_ = _cycle;
+
+ cycle_timer_.cancel();
+
+ if (std::chrono::milliseconds::zero() != _cycle) {
+ cycle_timer_.expires_from_now(cycle_);
+ std::function<void(boost::system::error_code const &)> its_handler =
+ std::bind(&event::update_cbk, shared_from_this(),
+ std::placeholders::_1);
+ cycle_timer_.async_wait(its_handler);
+ }
}
const std::set<eventgroup_t> & event::get_eventgroups() const {
- return (eventgroups_);
+ return (eventgroups_);
}
void event::add_eventgroup(eventgroup_t _eventgroup) {
- eventgroups_.insert(_eventgroup);
+ eventgroups_.insert(_eventgroup);
}
void event::set_eventgroups(const std::set<eventgroup_t> &_eventgroups) {
- eventgroups_ = _eventgroups;
+ eventgroups_ = _eventgroups;
}
void event::update_cbk(boost::system::error_code const &_error) {
- if (!_error) {
- cycle_timer_.expires_from_now(cycle_);
- notify();
- std::function<void(boost::system::error_code const &)> its_handler =
- std::bind(&event::update_cbk, shared_from_this(),
- std::placeholders::_1);
- cycle_timer_.async_wait(its_handler);
- }
+ if (!_error) {
+ cycle_timer_.expires_from_now(cycle_);
+ notify();
+ std::function<void(boost::system::error_code const &)> its_handler =
+ std::bind(&event::update_cbk, shared_from_this(),
+ std::placeholders::_1);
+ cycle_timer_.async_wait(its_handler);
+ }
}
void event::notify() {
- routing_->send(VSOMEIP_ROUTING_CLIENT, message_, true, is_reliable_);
+ if (is_set_) {
+ routing_->send(VSOMEIP_ROUTING_CLIENT, message_, true);
+ }
}
void event::notify_one(const std::shared_ptr<endpoint_definition> &_target) {
- routing_->send_to(_target, message_);
+ if (is_set_)
+ routing_->send_to(_target, message_);
+}
+
+void event::notify_one(client_t _client) {
+ if (is_set_)
+ routing_->send(_client, message_, true);
+}
+
+bool event::set_payload_helper(std::shared_ptr<payload> _payload) {
+ std::shared_ptr<payload> its_payload = message_->get_payload();
+ bool is_change = (its_payload->get_length() != _payload->get_length());
+ if (!is_change) {
+ std::size_t its_pos = 0;
+ const byte_t *its_old_data = its_payload->get_data();
+ const byte_t *its_new_data = _payload->get_data();
+ while (!is_change && its_pos < its_payload->get_length()) {
+ is_change = (*its_old_data++ != *its_new_data++);
+ its_pos++;
+ }
+ }
+ is_set_ = true;
+
+ return is_change;
}
} // namespace vsomeip
diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp
index 1838d8e..64d9b6b 100644
--- a/implementation/routing/src/eventgroupinfo.cpp
+++ b/implementation/routing/src/eventgroupinfo.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp
index e81bfe8..254cab4 100644
--- a/implementation/routing/src/routing_manager_impl.cpp
+++ b/implementation/routing/src/routing_manager_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -31,6 +30,7 @@
#include "../../endpoints/include/udp_server_endpoint_impl.hpp"
#include "../../message/include/deserializer.hpp"
#include "../../message/include/serializer.hpp"
+#include "../../service_discovery/include/constants.hpp"
#include "../../service_discovery/include/defines.hpp"
#include "../../service_discovery/include/runtime.hpp"
#include "../../service_discovery/include/service_discovery_impl.hpp"
@@ -40,1174 +40,1531 @@
namespace vsomeip {
routing_manager_impl::routing_manager_impl(routing_manager_host *_host) :
- host_(_host), io_(_host->get_io()), deserializer_(
- std::make_shared<deserializer>()), serializer_(
- std::make_shared<serializer>()), configuration_(
- host_->get_configuration()) {
+ host_(_host), io_(_host->get_io()), deserializer_(
+ std::make_shared<deserializer>()), serializer_(
+ std::make_shared<serializer>()), configuration_(
+ host_->get_configuration()) {
}
routing_manager_impl::~routing_manager_impl() {
}
boost::asio::io_service & routing_manager_impl::get_io() {
- return (io_);
+ return (io_);
}
client_t routing_manager_impl::get_client() const {
- return host_->get_client();
+ return host_->get_client();
}
void routing_manager_impl::init() {
- uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
- if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
-
- serializer_->create_data(its_max_message_size);
-
- // TODO: Only instantiate the stub if needed
- stub_ = std::make_shared<routing_manager_stub>(this);
- stub_->init();
-
- if (configuration_->is_service_discovery_enabled()) {
- VSOMEIP_INFO<< "Service Discovery enabled.";
- sd::runtime **its_runtime =
- static_cast<sd::runtime **>(utility::load_library(
- VSOMEIP_SD_LIBRARY,
- VSOMEIP_SD_RUNTIME_SYMBOL_STRING));
-
- if (0 != its_runtime && 0 != (*its_runtime)) {
- VSOMEIP_INFO << "Service Discovery module loaded.";
- discovery_ = (*its_runtime)->create_service_discovery(this);
- discovery_->init();
- }
-
- init_event_routing_info();
- } else {
- init_routing_info();
- }
+ uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size)
+ its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+ if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size)
+ its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
+
+ serializer_->create_data(its_max_message_size);
+
+ // TODO: Only instantiate the stub if needed
+ stub_ = std::make_shared<routing_manager_stub>(this);
+ stub_->init();
+
+ // We need to be able to send messages to ourself (for delivering events)
+ (void)create_local(VSOMEIP_ROUTING_CLIENT);
+
+ if (configuration_->is_service_discovery_enabled()) {
+ VSOMEIP_INFO<< "Service Discovery enabled. Trying to load module.";
+ std::shared_ptr<sd::runtime> *its_runtime =
+ static_cast<std::shared_ptr<sd::runtime> *>(utility::load_library(
+ VSOMEIP_SD_LIBRARY,
+ VSOMEIP_SD_RUNTIME_SYMBOL_STRING));
+
+ if (its_runtime && (*its_runtime)) {
+ VSOMEIP_INFO << "Service Discovery module loaded.";
+ discovery_ = (*its_runtime)->create_service_discovery(this);
+ discovery_->init();
+ }
+
+ init_event_routing_info();
+ } else {
+ init_routing_info();
+ }
}
void routing_manager_impl::start() {
- stub_->start();
- if (discovery_)
- discovery_->start();
+ stub_->start();
+ if (discovery_)
+ discovery_->start();
- host_->on_event(event_type_e::REGISTERED);
+ host_->on_event(event_type_e::ET_REGISTERED);
}
void routing_manager_impl::stop() {
- host_->on_event(event_type_e::DEREGISTERED);
+ host_->on_event(event_type_e::ET_DEREGISTERED);
- if (discovery_)
- discovery_->stop();
- stub_->stop();
+ if (discovery_)
+ discovery_->stop();
+ stub_->stop();
}
void routing_manager_impl::offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl) {
- local_services_[_service][_instance] = _client;
-
- // Remote route (incoming only)
- std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if (its_info) {
- if (its_info->get_major() == _major
- && its_info->get_minor() == _minor) {
- its_info->set_ttl(_ttl);
- if (discovery_) {
- discovery_->on_offer_change(its_info->get_group()->get_name());
- }
- } else {
- host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
- }
- } else {
- (void) create_service(_service, _instance, _major, _minor, _ttl);
- }
-
- stub_->on_offer_service(_client, _service, _instance);
- host_->on_availability(_service, _instance, true);
+ instance_t _instance, major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl) {
+ std::shared_ptr<serviceinfo> its_info;
+ {
+ std::lock_guard<std::mutex> its_lock(local_mutex_);
+ local_services_[_service][_instance] = _client;
+
+ // Remote route (incoming only)
+ its_info = find_service(_service, _instance);
+ if (its_info) {
+ if (its_info->get_major() == _major
+ && its_info->get_minor() == _minor) {
+ its_info->set_ttl(_ttl);
+ } else {
+ host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
+ }
+ } else {
+ its_info = create_service(_service, _instance, _major, _minor, _ttl);
+ }
+ }
+
+ if (discovery_ && its_info) {
+ std::string group_name("default");
+ if (its_info->get_group())
+ group_name = its_info->get_group()->get_name();
+ discovery_->on_offer_change(group_name);
+ }
+
+ stub_->on_offer_service(_client, _service, _instance);
+ host_->on_availability(_service, _instance, true);
}
void routing_manager_impl::stop_offer_service(client_t _client,
- service_t _service, instance_t _instance) {
- on_stop_offer_service(_service, _instance);
- stub_->on_stop_offer_service(_client, _service, _instance);
+ service_t _service, instance_t _instance) {
+ on_stop_offer_service(_service, _instance);
+ stub_->on_stop_offer_service(_client, _service, _instance);
}
void routing_manager_impl::request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl) {
-
- std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if (its_info) {
- if ((_major < ANY_MAJOR && _major > its_info->get_major())
- || (_major == its_info->get_major()
- && _minor < ANY_MINOR && _minor > its_info->get_minor())
- || (_ttl > its_info->get_ttl())) {
- host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
- } else {
- its_info->add_client(_client);
- }
- } else {
- if (discovery_)
- discovery_->request_service(_service, _instance, _major, _minor,
- _ttl);
- }
+ instance_t _instance, major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl, bool _has_selective) {
+
+ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
+ if (its_info) {
+ if ((_major < ANY_MAJOR && _major > its_info->get_major())
+ || (_major == its_info->get_major()
+ && _minor < ANY_MINOR && _minor > its_info->get_minor())
+ || (_ttl > its_info->get_ttl())) {
+ host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
+ } else {
+ its_info->add_client(_client);
+ }
+ } else {
+ if (discovery_)
+ discovery_->request_service(_service, _instance, _major, _minor,
+ _ttl);
+ }
+
+ // TODO: Mutex?!
+ if (_has_selective) {
+ specific_endpoint_clients.insert(_client);
+ }
}
void routing_manager_impl::release_service(client_t _client, service_t _service,
- instance_t _instance) {
- std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if (its_info) {
- its_info->remove_client(_client);
- } else {
- if (discovery_)
- discovery_->release_service(_service, _instance);
- }
+ instance_t _instance) {
+ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
+ if (its_info) {
+ its_info->remove_client(_client);
+ } else {
+ if (discovery_)
+ discovery_->release_service(_service, _instance);
+ }
}
void routing_manager_impl::subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- ttl_t _ttl) {
- if (discovery_) {
- eventgroup_clients_[_service][_instance][_eventgroup].insert(_client);
- if (0 == find_local_client(_service, _instance)) {
- discovery_->subscribe(_service, _instance, _eventgroup, _major,
- _ttl);
- }
- } else {
- VSOMEIP_ERROR<< "SOME/IP eventgroups require SD to be enabled!";
- }
+ instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
+ ttl_t _ttl) {
+ if (discovery_) {
+ if (!host_->on_subscription(_service, _instance, _eventgroup, _client, true)) {
+ VSOMEIP_INFO << "Subscription request for eventgroup " << _eventgroup
+ << " rejected from application handler";
+ return;
+ }
+ eventgroup_clients_[_service][_instance][_eventgroup].insert(_client);
+ if (0 == find_local_client(_service, _instance)) {
+ client_t subscriber = VSOMEIP_ROUTING_CLIENT;
+ // subscriber != VSOMEIP_ROUTING_CLIENT implies to use its own endpoint
+ auto its_selective = specific_endpoint_clients.find(_client);
+ if (its_selective != specific_endpoint_clients.end()) {
+ subscriber = _client;
+ }
+ discovery_->subscribe(_service, _instance, _eventgroup, _major,
+ _ttl, subscriber);
+ } else {
+ send_subscribe(_client, _service, _instance, _eventgroup, _major, _ttl);
+
+ std::shared_ptr<eventgroupinfo> its_eventgroup
+ = find_eventgroup(_service, _instance, _eventgroup);
+ if (its_eventgroup) {
+ std::set<std::shared_ptr<event> > its_events
+ = its_eventgroup->get_events();
+ for (auto e : its_events) {
+ if (e->is_field())
+ e->notify_one(_client);
+ }
+ }
+ }
+ } else {
+ VSOMEIP_ERROR<< "SOME/IP eventgroups require SD to be enabled!";
+ }
}
void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) {
- if (discovery_) {
- auto found_service = eventgroup_clients_.find(_service);
- if (found_service != eventgroup_clients_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_eventgroup = found_instance->second.find(
- _eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- found_eventgroup->second.erase(_client);
- if (0 == found_eventgroup->second.size()) {
- eventgroup_clients_.erase(_eventgroup);
- }
- }
- }
- }
- discovery_->unsubscribe(_service, _instance, _eventgroup);
- } else {
- VSOMEIP_ERROR<< "SOME/IP eventgroups require SD to be enabled!";
- }
+ instance_t _instance, eventgroup_t _eventgroup) {
+ if (discovery_) {
+ auto found_service = eventgroup_clients_.find(_service);
+ if (found_service != eventgroup_clients_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(
+ _eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ found_eventgroup->second.erase(_client);
+ if (0 == found_eventgroup->second.size()) {
+ eventgroup_clients_.erase(_eventgroup);
+ }
+ }
+ }
+ }
+ host_->on_subscription(_service, _instance, _eventgroup, _client, false);
+
+ if (0 == find_local_client(_service, _instance)) {
+ discovery_->unsubscribe(_service, _instance, _eventgroup);
+ } else {
+ send_unsubscribe(_client, _service, _instance, _eventgroup);
+ }
+ } else {
+ VSOMEIP_ERROR<< "SOME/IP eventgroups require SD to be enabled!";
+ }
}
bool routing_manager_impl::send(client_t its_client,
- std::shared_ptr<message> _message,
- bool _reliable,
- bool _flush) {
- bool is_sent(false);
-
- if (utility::is_request(_message->get_message_type())) {
- _message->set_client(its_client);
- }
-
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(_message.get())) {
- is_sent = send(its_client, serializer_->get_data(),
- serializer_->get_size(), _message->get_instance(), _reliable,
- _flush);
- serializer_->reset();
- }
-
- return (is_sent);
+ std::shared_ptr<message> _message, bool _flush) {
+ bool is_sent(false);
+
+ if (utility::is_request(_message->get_message_type())) {
+ _message->set_client(its_client);
+ }
+
+ std::lock_guard<std::mutex> its_lock(serialize_mutex_);
+ if (serializer_->serialize(_message.get())) {
+ is_sent = send(its_client, serializer_->get_data(),
+ serializer_->get_size(), _message->get_instance(),
+ _flush, _message->is_reliable());
+ serializer_->reset();
+ }
+
+ return (is_sent);
}
bool routing_manager_impl::send(client_t _client, const byte_t *_data,
- length_t _size, instance_t _instance,
- bool _flush,
- bool _reliable) {
- bool is_sent(false);
-
- std::shared_ptr<endpoint> its_target;
- bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]);
- bool is_notification = utility::is_notification(_data);
-
- 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]);
-
- if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
- if (is_request) {
- its_target = find_local(its_service, _instance);
- } else {
- its_target = find_local(its_client);
- }
-
- if (its_target) {
- is_sent = send_local(its_target, _client, _data, _size, _instance, _flush, _reliable);
- } else {
- // Check whether hosting application should get the message
- // If not, check routes to external
- if ((its_client == host_->get_client() && !is_request)
- || (find_local_client(its_service, _instance)
- == host_->get_client() && is_request)) {
- // TODO: find out how to handle session id here
- is_sent = deliver_message(_data, _size, _instance);
- } else {
- if (is_request) {
- its_target = find_remote_client(its_service, _instance,
- _reliable);
- if (its_target) {
- is_sent = its_target->send(_data, _size, _flush);
- } else {
- VSOMEIP_ERROR<< "Routing error. Client from remote service could not be found!";
- }
- } else {
- std::shared_ptr<serviceinfo> its_info(
- find_service(its_service, _instance));
- if (its_info) {
- its_target = its_info->get_endpoint(_reliable);
- if (its_target) {
- if (is_notification) {
- method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
- _data[VSOMEIP_METHOD_POS_MAX]);
- std::shared_ptr<event> its_event = find_event(its_service, _instance, its_method);
- if (its_event) {
- std::vector< byte_t > its_data;
-
- for (auto its_group : its_event->get_eventgroups()) {
- // local
- auto its_local_clients = find_local_clients(its_service, _instance, its_group);
- for (auto its_local_client : its_local_clients) {
- std::shared_ptr<endpoint> its_local_target = find_local(its_local_client);
- if (its_target) {
- send_local(its_local_target, _client, _data, _size, _instance, _flush, _reliable);
- }
- }
-
- // remote
- auto its_eventgroup = find_eventgroup(its_service, _instance, its_group);
- if (its_eventgroup) {
- for (auto its_remote : its_eventgroup->get_targets()) {
- its_target->send_to(its_remote, _data, _size);
- }
- }
- }
- }
- } else {
- is_sent = its_target->send(_data, _size, _flush);
- }
- } else {
- VSOMEIP_ERROR << "Routing error. Service endpoint could not be found!";
- }
- } else {
- VSOMEIP_ERROR << "Routing error. Service could not be found!";
- }
- }
- }
- }
- }
-
- return (is_sent);
+ length_t _size, instance_t _instance,
+ bool _flush, bool _reliable) {
+ bool is_sent(false);
+
+ std::shared_ptr<endpoint> its_target;
+ bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]);
+ bool is_notification = utility::is_notification(_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]);
+
+ bool is_service_discovery = (its_service == vsomeip::sd::service
+ && its_method == vsomeip::sd::method);
+
+ if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
+ if (is_request) {
+ its_target = find_local(its_service, _instance);
+ } else if (!is_notification) {
+ its_target = find_local(its_client);
+ } else if (is_notification && _client) {
+ // Selective notifications!
+ its_target = find_local(_client);
+ }
+
+ if (its_target) {
+ is_sent = send_local(its_target, _client, _data, _size, _instance, _flush, _reliable);
+ } else {
+ // Check whether hosting application should get the message
+ // If not, check routes to external
+ if ((its_client == host_->get_client() && !is_request)
+ || (find_local_client(its_service, _instance)
+ == host_->get_client() && is_request)) {
+ // TODO: find out how to handle session id here
+ is_sent = deliver_message(_data, _size, _instance, _reliable);
+ } else {
+ if (is_request) {
+ client_t client = VSOMEIP_ROUTING_CLIENT;
+ if (specific_endpoint_clients.find(its_client) != specific_endpoint_clients.end()) {
+ client = its_client;
+ }
+ its_target = find_or_create_remote_client(its_service, _instance, _reliable, client);
+ if (its_target) {
+ is_sent = its_target->send(_data, _size, _flush);
+ } else {
+ VSOMEIP_ERROR<< "Routing error. Client from remote service could not be found!";
+ }
+ } else {
+ std::shared_ptr<serviceinfo> its_info(find_service(its_service, _instance));
+ if (its_info) {
+ its_target = its_info->get_endpoint(_reliable);
+ if (is_notification && !is_service_discovery) {
+ method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
+ _data[VSOMEIP_METHOD_POS_MAX]);
+ std::shared_ptr<event> its_event = find_event(its_service, _instance, its_method);
+ if (its_event) {
+ std::vector< byte_t > its_data;
+
+ for (auto its_group : its_event->get_eventgroups()) {
+ // local
+ auto its_local_clients = find_local_clients(its_service, _instance, its_group);
+ for (auto its_local_client : its_local_clients) {
+ // If we also want to receive the message, send it to the routing manager
+ // We cannot call deliver_message in this case as this would end in receiving
+ // an answer before the call to send has finished.
+ if (its_local_client == host_->get_client()) {
+ its_local_client = VSOMEIP_ROUTING_CLIENT;
+ }
+
+ std::shared_ptr<endpoint> its_local_target = find_local(its_local_client);
+ if (its_local_target) {
+ send_local(its_local_target, _client, _data, _size, _instance, _flush, _reliable);
+ }
+ }
+
+ if (its_target) {
+ // remote
+ auto its_eventgroup = find_eventgroup(its_service, _instance, its_group);
+ if (its_eventgroup) {
+ for (auto its_remote : its_eventgroup->get_targets()) {
+ its_target->send_to(its_remote, _data, _size);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if (its_target) {
+ is_sent = its_target->send(_data, _size, _flush);
+ } else {
+ VSOMEIP_ERROR << "Routing error. Endpoint for service ["
+ << std::hex << its_service << "." << _instance
+ << "] could not be found!";
+ }
+ }
+ } else {
+ if (!is_notification) {
+ VSOMEIP_ERROR << "Routing error. Not hosting service ["
+ << std::hex << its_service << "." << _instance
+ << "]";
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return (is_sent);
}
bool routing_manager_impl::send_local(
- std::shared_ptr<endpoint>& _target, client_t _client,
- const byte_t *_data, uint32_t _size,
- instance_t _instance,
- bool _flush, bool _reliable) const {
-
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
-
- if (_target) {
- std::vector<byte_t> its_command(
- VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t)
- + sizeof(bool) + sizeof(bool));
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SEND;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
- sizeof(client_t));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size,
- sizeof(_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], _data,
- _size);
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size],
- &_instance, sizeof(instance_t));
- std::memcpy(
- &its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size
- + sizeof(instance_t)], &_reliable, sizeof(bool));
- std::memcpy(
- &its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size
- + sizeof(instance_t) + sizeof(bool)], &_flush,
- sizeof(bool));
-
- return _target->send(&its_command[0], its_command.size(),_flush);
- }
-
- return false;
+ std::shared_ptr<endpoint>& _target, client_t _client,
+ const byte_t *_data, uint32_t _size,
+ instance_t _instance,
+ bool _flush, bool _reliable) const {
+
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+
+ std::vector<byte_t> its_command(
+ VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t)
+ + sizeof(bool) + sizeof(bool));
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SEND;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
+ sizeof(client_t));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size,
+ sizeof(_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], _data,
+ _size);
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size],
+ &_instance, sizeof(instance_t));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size
+ + sizeof(instance_t)], &_flush, sizeof(bool));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size
+ + sizeof(instance_t) + sizeof(bool)], &_reliable, sizeof(bool));
+
+ return _target->send(&its_command[0], its_command.size(), _flush);
}
bool routing_manager_impl::send_to(
- const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message) {
- bool is_sent(false);
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(_message.get())) {
- is_sent = send_to(_target,
- serializer_->get_data(), serializer_->get_size());
- serializer_->reset();
- } else {
- VSOMEIP_ERROR<< "routing_manager_impl::send_to: serialization failed.";
- }
- return (is_sent);
+ const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message> _message) {
+ bool is_sent(false);
+ std::lock_guard<std::mutex> its_lock(serialize_mutex_);
+ if (serializer_->serialize(_message.get())) {
+ is_sent = send_to(_target,
+ serializer_->get_data(), serializer_->get_size());
+ serializer_->reset();
+ } else {
+ VSOMEIP_ERROR<< "routing_manager_impl::send_to: serialization failed.";
+ }
+ return (is_sent);
}
bool routing_manager_impl::send_to(
- const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size) {
- std::shared_ptr<endpoint> its_endpoint = find_or_create_server_endpoint(
- _target->get_port(), _target->is_reliable());
+ const std::shared_ptr<endpoint_definition> &_target,
+ const byte_t *_data, uint32_t _size) {
+ std::shared_ptr<endpoint> its_endpoint = find_or_create_server_endpoint(
+ _target->get_remote_port(), _target->is_reliable());
- return (its_endpoint && its_endpoint->send_to(_target, _data, _size));
+ return (its_endpoint && its_endpoint->send_to(_target, _data, _size));
}
void routing_manager_impl::notify(
- service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload) {
- std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
- if (its_event) {
- its_event->set_payload(_payload);
- } else {
- VSOMEIP_ERROR << "routing_manager_impl::notify: event ["
- << std::hex << _service << "." << _instance << "." << _event
- << "] is unknown.";
- }
+ service_t _service, instance_t _instance, event_t _event,
+ std::shared_ptr<payload> _payload) {
+ std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
+ if (its_event) {
+ its_event->set_payload(_payload);
+ } else {
+ VSOMEIP_ERROR << "routing_manager_impl::notify: event ["
+ << std::hex << _service << "." << _instance << "." << _event
+ << "] is unknown.";
+ }
+}
+
+void routing_manager_impl::notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload, client_t _client) {
+
+ std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
+ if (its_event) {
+ for (auto its_group : its_event->get_eventgroups()) {
+ auto its_eventgroup = find_eventgroup(_service, _instance, its_group);
+ if (its_eventgroup) {
+ auto its_subscriber = remote_subscriber_map_.find(_client);
+ if (its_subscriber != remote_subscriber_map_.end()) {
+ its_event->set_payload(_payload, its_subscriber->second);
+ } else {
+ its_event->set_payload(_payload, _client);
+ }
+ }
+ }
+ } else {
+ VSOMEIP_ERROR << "routing_manager_impl::notify: event ["
+ << std::hex << _service << "." << _instance << "." << _event
+ << "] is unknown.";
+ }
}
void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
- endpoint *_receiver) {
+ endpoint *_receiver) {
#if 0
- std::stringstream msg;
- msg << "rmi::on_message: ";
- for (uint32_t i = 0; i < _size; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "rmi::on_message: ";
+ for (uint32_t i = 0; i < _size; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- service_t its_service;
- instance_t its_instance;
-
- if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) {
- its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN],
- _data[VSOMEIP_SERVICE_POS_MAX]);
- if (its_service == VSOMEIP_SD_SERVICE) {
- if (discovery_)
- discovery_->on_message(_data, _size);
- } else {
- its_instance = find_instance(its_service, _receiver);
- on_message(its_service, its_instance, _data, _size);
- }
- }
+ service_t its_service;
+ instance_t its_instance;
+ message_type_e its_message_type;
+
+ if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) {
+ its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN],
+ _data[VSOMEIP_SERVICE_POS_MAX]);
+ if (its_service == VSOMEIP_SD_SERVICE) {
+ if (discovery_)
+ discovery_->on_message(_data, _size);
+ } else {
+ its_instance = find_instance(its_service, _receiver);
+ its_message_type = static_cast<message_type_e>(_data[VSOMEIP_MESSAGE_TYPE_POS]);
+ if (its_instance == 0xFFFF) {
+ VSOMEIP_WARNING << "Receiving endpoint is not configured for service 0x"
+ << std::hex << its_service;
+ return;
+ }
+
+ // TODO: move specific endpoint handling to to a method!
+ auto found_service = remote_services_.find(its_service);
+ if (found_service != remote_services_.end()) {
+ auto found_instance = found_service->second.find(its_instance);
+ if (found_instance != found_service->second.end()) {
+ for (auto client_entry : found_instance->second) {
+ client_t client = client_entry.first;
+ if (!client) {
+ continue;
+ }
+ auto found_reliability = client_entry.second.find(_receiver->is_reliable());
+ if (found_reliability != client_entry.second.end()) {
+ auto found_enpoint = found_reliability->second;
+ if (found_enpoint.get() == _receiver) {
+ auto local_endpoint = find_local(client);
+ if (client != get_client()) {
+ send_local(local_endpoint, client, _data, _size, its_instance, true, _receiver->is_reliable());
+ } else {
+ deliver_message(_data, _size, its_instance, _receiver->is_reliable());
+ }
+ return;
+ }
+ }
+ }
+ }
+ }
+ on_message(its_service, its_instance, _data, _size, _receiver->is_reliable());
+ }
+ }
}
-void routing_manager_impl::on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size) {
- method_t its_method;
- client_t its_client;
- session_t its_session;
-
- if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
- if (utility::is_event(_data[VSOMEIP_METHOD_POS_MIN])) {
- its_method = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_METHOD_POS_MIN],
- _data[VSOMEIP_METHOD_POS_MAX]);
- std::shared_ptr<event> its_event
- = find_event(_service, _instance, its_method);
- if (its_event) {
- if (its_event->is_field()) {
- uint32_t its_length = utility::get_payload_size(_data, _size);
- if (its_length > 0) { // set
- std::shared_ptr<payload> its_payload =
- runtime::get()->create_payload(
- &_data[VSOMEIP_PAYLOAD_POS],
- its_length);
- its_event->set_payload(its_payload);
- }
- }
-
- if (!utility::is_request_no_return(
- _data[VSOMEIP_RETURN_CODE_POS])) {
- std::shared_ptr<message> its_response =
- runtime::get()->create_message();
- 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_response->set_service(_service);
- its_response->set_method(its_method);
- its_response->set_client(its_client);
- its_response->set_session(its_session);
-
- if (its_event->is_field()) {
- its_response->set_message_type(
- message_type_e::RESPONSE);
- its_response->set_payload(its_event->get_payload());
- } else {
- its_response->set_message_type(message_type_e::ERROR);
- }
-
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(its_response.get())) {
- send(its_client,
- serializer_->get_data(), serializer_->get_size(),
- _instance,
- true, its_event->is_reliable());
- } else {
- VSOMEIP_ERROR << "routing_manager_impl::on_message: serialization error.";
- }
- serializer_->reset();
- }
- } else {
- its_client = VSOMEIP_ROUTING_CLIENT;
- }
- } else {
- its_client = find_local_client(_service, _instance);
- }
- } else {
- its_client = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_CLIENT_POS_MIN],
- _data[VSOMEIP_CLIENT_POS_MAX]);
- }
-
- if (its_client == host_->get_client()
- || its_client == VSOMEIP_ROUTING_CLIENT
- || utility::is_notification(_data)) {
- deliver_message(_data, _size, _instance);
- } else {
- send(its_client, _data, _size, _instance, true, false);
- }
+void routing_manager_impl::on_message(
+ service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _size,
+ bool _reliable) {
+ method_t its_method;
+ client_t its_client;
+ session_t its_session;
+
+ its_client = 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]);
+
+ if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && its_client) {
+ // targeted notification
+ // reset client_id/subscriber/target field
+ const_cast<byte_t *>(_data)[VSOMEIP_CLIENT_POS_MIN] = 0;
+ const_cast<byte_t *>(_data)[VSOMEIP_CLIENT_POS_MAX] = 0;
+
+ its_method = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_METHOD_POS_MIN],
+ _data[VSOMEIP_METHOD_POS_MAX]);
+
+ auto it_subscriber = remote_subscriber_map_.find(its_client);
+ if (it_subscriber != remote_subscriber_map_.end()) {
+ send_to(it_subscriber->second, _data, _size);
+ } else {
+ if (its_client == host_->get_client()) {
+ deliver_message(_data, _size, _instance, _reliable);
+ } else {
+ send(its_client, _data, _size, _instance, true, _reliable);
+ }
+ }
+ return;
+ }
+
+ if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
+ std::shared_ptr<event> its_event
+ = find_event(_service, _instance, its_method);
+ if (its_event) {
+ uint32_t its_length = utility::get_payload_size(_data, _size);
+ if (its_length > 0) { // set
+ std::shared_ptr<payload> its_payload =
+ runtime::get()->create_payload(
+ &_data[VSOMEIP_PAYLOAD_POS],
+ its_length);
+ its_event->set_payload(its_payload);
+ }
+
+ if (!utility::is_request_no_return(
+ _data[VSOMEIP_MESSAGE_TYPE_POS])) {
+ std::shared_ptr<message> its_response =
+ runtime::get()->create_message();
+ its_session = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_SESSION_POS_MIN],
+ _data[VSOMEIP_SESSION_POS_MAX]);
+
+ its_response->set_service(_service);
+ its_response->set_method(its_method);
+ its_response->set_client(its_client);
+ its_response->set_session(its_session);
+
+ if (its_event->is_field()) {
+ its_response->set_message_type(
+ message_type_e::MT_RESPONSE);
+ its_response->set_payload(its_event->get_payload());
+ } else {
+ its_response->set_message_type(message_type_e::MT_ERROR);
+ }
+
+ std::lock_guard<std::mutex> its_lock(serialize_mutex_);
+ if (serializer_->serialize(its_response.get())) {
+ send(its_client,
+ serializer_->get_data(), serializer_->get_size(),
+ _instance,
+ true, its_event->is_reliable());
+ } else {
+ VSOMEIP_ERROR << "routing_manager_impl::on_message: serialization error.";
+ }
+ serializer_->reset();
+ }
+ return;
+ } else {
+ its_client = find_local_client(_service, _instance);
+ }
+ } else {
+ its_client = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_CLIENT_POS_MIN],
+ _data[VSOMEIP_CLIENT_POS_MAX]);
+ }
+
+ if ((its_client == VSOMEIP_ROUTING_CLIENT
+ && utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]))
+ || its_client == host_->get_client()) {
+ deliver_message(_data, _size, _instance, _reliable);
+ } else {
+ send(its_client, _data, _size, _instance, true, _reliable);
+ }
}
void routing_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) {
- for (auto &its_service : remote_services_) {
- for (auto &its_instance : its_service.second) {
- auto found_endpoint = its_instance.second.find(false);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first, its_instance.first,
- true);
- } else {
- found_endpoint = its_instance.second.find(true);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first,
- its_instance.first, true);
- }
- }
- }
- }
+ for (auto &its_service : remote_services_) {
+ for (auto &its_instance : its_service.second) {
+ auto found_endpoint = its_instance.second.find(false);
+ if (found_endpoint != its_instance.second.end()) {
+ host_->on_availability(its_service.first, its_instance.first,
+ true);
+ } else {
+ found_endpoint = its_instance.second.find(true);
+ if (found_endpoint != its_instance.second.end()) {
+ host_->on_availability(its_service.first,
+ its_instance.first, true);
+ }
+ }
+ }
+ }
}
void routing_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
- for (auto &its_service : remote_services_) {
- for (auto &its_instance : its_service.second) {
- auto found_endpoint = its_instance.second.find(false);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first, its_instance.first,
- false);
- } else {
- found_endpoint = its_instance.second.find(true);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first,
- its_instance.first, false);
- }
- }
- }
- }
+ for (auto &its_service : remote_services_) {
+ for (auto &its_instance : its_service.second) {
+ auto found_endpoint = its_instance.second.find(false);
+ if (found_endpoint != its_instance.second.end()) {
+ host_->on_availability(its_service.first, its_instance.first,
+ false);
+ } else {
+ found_endpoint = its_instance.second.find(true);
+ if (found_endpoint != its_instance.second.end()) {
+ host_->on_availability(its_service.first,
+ its_instance.first, false);
+ }
+ }
+ }
+ }
}
void routing_manager_impl::on_stop_offer_service(service_t _service,
- instance_t _instance) {
- host_->on_availability(_service, _instance, false);
-
- if (discovery_) {
- auto found_service = services_.find(_service);
- if (found_service != services_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- found_instance->second->set_ttl(0);
- discovery_->on_offer_change(
- found_instance->second->get_group()->get_name());
- }
- }
- } else {
- // TODO: allow to withdraw a service on one endpoint only
- del_routing_info(_service, _instance, false);
- del_routing_info(_service, _instance, true);
- }
+ instance_t _instance) {
+
+ for (auto &s : events_)
+ for (auto &i : s.second)
+ for (auto &e : i.second)
+ e.second->unset_payload();
+
+ host_->on_availability(_service, _instance, false);
+
+ if (discovery_) {
+ auto found_service = services_.find(_service);
+ if (found_service != services_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ found_instance->second->set_ttl(0);
+ discovery_->on_offer_change(
+ found_instance->second->get_group()->get_name());
+ }
+ }
+ } else {
+ // TODO: allow to withdraw a service on one endpoint only
+ del_routing_info(_service, _instance, false);
+ del_routing_info(_service, _instance, true);
+ }
}
bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
- instance_t _instance) {
- bool is_sent(false);
- deserializer_->set_data(_data, _size);
- std::shared_ptr<message> its_message(deserializer_->deserialize_message());
- if (its_message) {
- its_message->set_instance(_instance);
- host_->on_message(its_message);
- is_sent = true;
- } else {
- // TODO: send error "Malformed Message"
- //send_error();
- }
- return (is_sent);
-}
-
-bool routing_manager_impl::is_available(service_t _service,
- instance_t _instance) const {
- auto find_local_service = local_services_.find(_service);
- if (find_local_service != local_services_.end()) {
- auto find_local_instance = find_local_service->second.find(_instance);
- if (find_local_instance != find_local_service->second.end()) {
- return (true);
- }
- }
-
- auto find_remote_service = remote_services_.find(_service);
- if (find_remote_service != remote_services_.end()) {
- auto find_remote_instance = find_remote_service->second.find(_instance);
- if (find_remote_instance != find_remote_service->second.end()) {
- return (true);
- }
- }
-
- return (false);
+ instance_t _instance, bool _reliable) {
+ bool is_sent(false);
+ deserializer_->set_data(_data, _size);
+ std::shared_ptr<message> its_message(deserializer_->deserialize_message());
+ if (its_message) {
+ its_message->set_instance(_instance);
+ its_message->set_reliable(_reliable);
+ host_->on_message(its_message);
+ is_sent = true;
+ } else {
+ // TODO: send error "Malformed Message"
+ //send_error();
+ }
+ return (is_sent);
}
const std::map<std::string, std::shared_ptr<servicegroup> > &
routing_manager_impl::get_servicegroups() const {
- return (servicegroups_);
+ return (servicegroups_);
}
std::shared_ptr<eventgroupinfo> routing_manager_impl::find_eventgroup(
- service_t _service, instance_t _instance,
- eventgroup_t _eventgroup) const {
- std::shared_ptr<eventgroupinfo> its_info(nullptr);
- 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()) {
- auto found_eventgroup = found_instance->second.find(_eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- its_info = found_eventgroup->second;
- std::shared_ptr<serviceinfo> its_service_info
- = find_service(_service, _instance);
- if (its_service_info) {
- if (_eventgroup
- == its_service_info->get_multicast_group()) {
- try {
- boost::asio::ip::address its_multicast_address =
- boost::asio::ip::address::from_string(
- its_service_info->get_multicast_address());
- uint16_t its_multicast_port =
- its_service_info->get_multicast_port();
- its_info->set_multicast(its_multicast_address,
- its_multicast_port);
- }
- catch (...) {
- VSOMEIP_ERROR << "Eventgroup ["
- << std::hex << std::setw(4) << std::setfill('0')
- << _service << "." << _instance << "." << _eventgroup
- << "] is configured as multicast, but no valid "
- "multicast address is configured!";
- }
- }
- its_info->set_major(its_service_info->get_major());
- its_info->set_ttl(its_service_info->get_ttl());
- }
- }
- }
- }
- return (its_info);
+ service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup) const {
+ std::shared_ptr<eventgroupinfo> its_info(nullptr);
+ 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()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ its_info = found_eventgroup->second;
+ std::shared_ptr<serviceinfo> its_service_info
+ = find_service(_service, _instance);
+ if (its_service_info) {
+ if (_eventgroup
+ == its_service_info->get_multicast_group()) {
+ try {
+ boost::asio::ip::address its_multicast_address =
+ boost::asio::ip::address::from_string(
+ its_service_info->get_multicast_address());
+ uint16_t its_multicast_port =
+ its_service_info->get_multicast_port();
+ its_info->set_multicast(its_multicast_address,
+ its_multicast_port);
+ }
+ catch (...) {
+ VSOMEIP_ERROR << "Eventgroup ["
+ << std::hex << std::setw(4) << std::setfill('0')
+ << _service << "." << _instance << "." << _eventgroup
+ << "] is configured as multicast, but no valid "
+ "multicast address is configured!";
+ }
+ }
+ its_info->set_major(its_service_info->get_major());
+ its_info->set_ttl(its_service_info->get_ttl());
+ }
+ }
+ }
+ }
+ return (its_info);
}
std::shared_ptr<configuration> routing_manager_impl::get_configuration() const {
- return (host_->get_configuration());
+ return (host_->get_configuration());
}
void routing_manager_impl::create_service_discovery_endpoint(
- const std::string &_address, uint16_t _port, bool _reliable) {
- std::shared_ptr<endpoint> its_service_endpoint = find_server_endpoint(_port,
- _reliable);
- if (!its_service_endpoint) {
- its_service_endpoint = create_server_endpoint(_port, _reliable);
-
- std::shared_ptr<serviceinfo> its_info(
- std::make_shared<serviceinfo>(ANY_MAJOR, ANY_MINOR, ANY_TTL));
- its_info->set_endpoint(its_service_endpoint, _reliable);
-
- // routing info
- services_[VSOMEIP_SD_SERVICE][VSOMEIP_SD_INSTANCE] = its_info;
-
- its_service_endpoint->add_multicast(VSOMEIP_SD_SERVICE,
- VSOMEIP_SD_METHOD, _address, _port);
- its_service_endpoint->join(_address);
- its_service_endpoint->start();
- }
+ const std::string &_address, uint16_t _port, bool _reliable) {
+ std::shared_ptr<endpoint> its_service_endpoint = find_server_endpoint(_port,
+ _reliable);
+ if (!its_service_endpoint) {
+ its_service_endpoint = create_server_endpoint(_port, _reliable);
+
+ if (its_service_endpoint) {
+ std::shared_ptr<serviceinfo> its_info(
+ std::make_shared<serviceinfo>(ANY_MAJOR, ANY_MINOR, ANY_TTL));
+ its_info->set_endpoint(its_service_endpoint, _reliable);
+
+ // routing info
+ services_[VSOMEIP_SD_SERVICE][VSOMEIP_SD_INSTANCE] = its_info;
+
+ its_service_endpoint->add_multicast(VSOMEIP_SD_SERVICE,
+ VSOMEIP_SD_METHOD, _address, _port);
+ its_service_endpoint->join(_address);
+ its_service_endpoint->start();
+ } else {
+ VSOMEIP_ERROR << "Service Discovery endpoint could not be created. "
+ "Please check your network configuration.";
+ }
+ }
}
services_t routing_manager_impl::get_offered_services(
- const std::string &_name) const {
- services_t its_offers;
- auto find_servicegroup = servicegroups_.find(_name);
- if (find_servicegroup != servicegroups_.end()) {
- return (find_servicegroup->second->get_services());
- }
+ const std::string &_name) const {
+ services_t its_offers;
+ auto find_servicegroup = servicegroups_.find(_name);
+ if (find_servicegroup != servicegroups_.end()) {
+ if (find_servicegroup->second->is_local()) {
+ return (find_servicegroup->second->get_services());
+ }
+ }
+
+ return (its_offers);
+}
- return (its_offers);}
+std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client(
+ service_t _service, instance_t _instance, bool _reliable, client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint = find_remote_client(_service, _instance,
+ _reliable, _client);
+ // Create specific IP-client-endpoint for selective clients
+ if (!its_endpoint &&
+ specific_endpoint_clients.find(_client) != specific_endpoint_clients.end()) {
+
+ its_endpoint = create_remote_client(_service, _instance, _reliable, _client);
+ }
+ return its_endpoint;
+}
///////////////////////////////////////////////////////////////////////////////
// PRIVATE
///////////////////////////////////////////////////////////////////////////////
std::shared_ptr<serviceinfo> routing_manager_impl::find_service(
- service_t _service, instance_t _instance) const {
- std::shared_ptr<serviceinfo> its_info;
- auto found_service = services_.find(_service);
- if (found_service != services_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- its_info = found_instance->second;
- }
- }
- return (its_info);
+ service_t _service, instance_t _instance) const {
+ std::shared_ptr<serviceinfo> its_info;
+ auto found_service = services_.find(_service);
+ if (found_service != services_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ its_info = found_instance->second;
+ }
+ }
+ return (its_info);
}
std::shared_ptr<serviceinfo> routing_manager_impl::create_service(
- service_t _service, instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) {
- std::shared_ptr<serviceinfo> its_info;
- if (configuration_) {
- its_info = std::make_shared<serviceinfo>(_major, _minor, _ttl);
-
- uint16_t its_reliable_port = configuration_->get_reliable_port(_service,
- _instance);
- uint16_t its_unreliable_port = configuration_->get_unreliable_port(
- _service, _instance);
-
- its_info->set_multicast_address(
- configuration_->get_multicast_address(_service, _instance));
- its_info->set_multicast_port(
- configuration_->get_multicast_port(_service, _instance));
- its_info->set_multicast_group(
- configuration_->get_multicast_group(_service, _instance));
-
- std::shared_ptr<endpoint> its_reliable_endpoint;
- std::shared_ptr<endpoint> its_unreliable_endpoint;
-
- if (ILLEGAL_PORT != its_reliable_port) {
- its_reliable_endpoint = find_or_create_server_endpoint(
- its_reliable_port,
- true);
- its_info->set_endpoint(its_reliable_endpoint, true);
-
- // TODO: put this in a method and check whether an assignment already exists!
- service_instances_[_service][its_reliable_endpoint.get()] =
- _instance;
- }
-
- if (ILLEGAL_PORT != its_unreliable_port) {
- its_unreliable_endpoint = find_or_create_server_endpoint(
- its_unreliable_port, false);
- its_info->set_endpoint(its_unreliable_endpoint, false);
-
- service_instances_[_service][its_unreliable_endpoint.get()] =
- _instance;
- }
-
- if (ILLEGAL_PORT != its_reliable_port
- || ILLEGAL_PORT != its_unreliable_port) {
- std::string its_servicegroup = configuration_->get_group(_service,
- _instance);
- auto found_servicegroup = servicegroups_.find(its_servicegroup);
- if (found_servicegroup == servicegroups_.end()) {
- servicegroups_[its_servicegroup] =
- std::make_shared<servicegroup>(its_servicegroup);
- }
- servicegroups_[its_servicegroup]->add_service(_service, _instance,
- its_info);
- services_[_service][_instance] = its_info;
- } else {
- host_->on_error(error_code_e::PORT_CONFIGURATION_MISSING);
- }
- } else {
- host_->on_error(error_code_e::CONFIGURATION_MISSING);
- }
-
- return (its_info);
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl) {
+
+ std::shared_ptr<serviceinfo> its_info;
+ if (configuration_) {
+ its_info = std::make_shared<serviceinfo>(_major, _minor, _ttl);
+
+ uint16_t its_reliable_port = configuration_->get_reliable_port(_service,
+ _instance);
+ uint16_t its_unreliable_port = configuration_->get_unreliable_port(
+ _service, _instance);
+
+ its_info->set_multicast_address(
+ configuration_->get_multicast_address(_service, _instance));
+ its_info->set_multicast_port(
+ configuration_->get_multicast_port(_service, _instance));
+ its_info->set_multicast_group(
+ configuration_->get_multicast_group(_service, _instance));
+
+ std::shared_ptr<endpoint> its_reliable_endpoint;
+ std::shared_ptr<endpoint> its_unreliable_endpoint;
+
+ if (ILLEGAL_PORT != its_reliable_port) {
+ its_reliable_endpoint = find_or_create_server_endpoint(
+ its_reliable_port,
+ true);
+ its_info->set_endpoint(its_reliable_endpoint, true);
+
+ // TODO: put this in a method and check whether an assignment already exists!
+ service_instances_[_service][its_reliable_endpoint.get()] =
+ _instance;
+ }
+
+ if (ILLEGAL_PORT != its_unreliable_port) {
+ its_unreliable_endpoint = find_or_create_server_endpoint(
+ its_unreliable_port, false);
+ its_info->set_endpoint(its_unreliable_endpoint, false);
+
+ service_instances_[_service][its_unreliable_endpoint.get()] =
+ _instance;
+ }
+
+ if (ILLEGAL_PORT != its_reliable_port
+ || ILLEGAL_PORT != its_unreliable_port) {
+ std::string its_servicegroup = configuration_->get_group(_service,
+ _instance);
+ auto found_servicegroup = servicegroups_.find(its_servicegroup);
+ if (found_servicegroup == servicegroups_.end()) {
+ servicegroups_[its_servicegroup] =
+ std::make_shared<servicegroup>(its_servicegroup,
+ configuration_->is_local_servicegroup(its_servicegroup));
+ }
+ servicegroups_[its_servicegroup]->add_service(_service, _instance,
+ its_info);
+ services_[_service][_instance] = its_info;
+ } else {
+ VSOMEIP_DEBUG << "Port configuration missing. Assuming internal service.";
+ }
+ } else {
+ host_->on_error(error_code_e::CONFIGURATION_MISSING);
+ }
+
+ return (its_info);
}
std::shared_ptr<endpoint> routing_manager_impl::create_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) {
- std::shared_ptr<endpoint> its_endpoint;
- try {
- if (_reliable) {
- its_endpoint = std::make_shared<tcp_client_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::tcp::endpoint(_address, _port), io_);
-
- if (configuration_->has_enabled_magic_cookies(_address.to_string(),
- _port)) {
- its_endpoint->enable_magic_cookies();
- }
- } else {
- its_endpoint = std::make_shared<udp_client_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::udp::endpoint(_address, _port), io_);
- }
-
- client_endpoints_[_address][_port][_reliable] = its_endpoint;
- its_endpoint->start();
- } catch (std::exception &e) {
- host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED);
- }
-
- return (its_endpoint);
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable, client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint;
+ try {
+ if (_reliable) {
+ its_endpoint = std::make_shared<tcp_client_endpoint_impl>(
+ shared_from_this(),
+ boost::asio::ip::tcp::endpoint(_address, _port), io_);
+
+ if (configuration_->has_enabled_magic_cookies(_address.to_string(),
+ _port)) {
+ its_endpoint->enable_magic_cookies();
+ }
+ } else {
+ its_endpoint = std::make_shared<udp_client_endpoint_impl>(
+ shared_from_this(),
+ boost::asio::ip::udp::endpoint(_address, _port), io_);
+ }
+
+ client_endpoints_[_address][_port][_client][_reliable] = its_endpoint;
+ its_endpoint->start();
+ } catch (...) {
+ host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED);
+ }
+
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::find_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) {
- std::shared_ptr<endpoint> its_endpoint;
- auto found_address = client_endpoints_.find(_address);
- if (found_address != client_endpoints_.end()) {
- auto found_port = found_address->second.find(_port);
- if (found_port != found_address->second.end()) {
- auto found_endpoint = found_port->second.find(_reliable);
- if (found_endpoint != found_port->second.end()) {
- its_endpoint = found_endpoint->second;
- }
- }
- }
- return (its_endpoint);
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable, client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint;
+ auto found_address = client_endpoints_.find(_address);
+ if (found_address != client_endpoints_.end()) {
+ auto found_port = found_address->second.find(_port);
+ if (found_port != found_address->second.end()) {
+ auto found_client = found_port->second.find(_client);
+ if (found_client != found_port->second.end()) {
+ auto found_endpoint = found_client->second.find(_reliable);
+ if (found_endpoint != found_client->second.end()) {
+ its_endpoint = found_endpoint->second;
+ }
+ }
+ }
+ }
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::find_or_create_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- std::shared_ptr<endpoint> its_endpoint = find_client_endpoint(_address,
- _port, _reliable);
- if (0 == its_endpoint) {
- its_endpoint = create_client_endpoint(_address, _port, _reliable);
- }
- return (its_endpoint);
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable, client_t _client) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ std::shared_ptr<endpoint> its_endpoint = find_client_endpoint(_address,
+ _port, _reliable, _client);
+ if (0 == its_endpoint) {
+ its_endpoint = create_client_endpoint(_address, _port, _reliable, _client);
+ }
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::create_server_endpoint(
- uint16_t _port, bool _reliable) {
- std::shared_ptr<endpoint> its_endpoint;
-
- try {
- boost::asio::ip::address its_unicast = configuration_->get_unicast();
- if (_reliable) {
- its_endpoint = std::make_shared<tcp_server_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::tcp::endpoint(its_unicast, _port), io_);
- if (configuration_->has_enabled_magic_cookies(
- its_unicast.to_string(), _port)) {
- its_endpoint->enable_magic_cookies();
- }
- } else {
- if (its_unicast.is_v4()) {
- its_unicast = boost::asio::ip::address_v4::any();
- } else {
- // TODO: how is "ANY" specified in IPv6?
- }
- its_endpoint = std::make_shared<udp_server_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::udp::endpoint(its_unicast, _port), io_);
- }
-
- server_endpoints_[_port][_reliable] = its_endpoint;
- its_endpoint->start();
- } catch (std::exception &e) {
- host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
- }
-
- return (its_endpoint);
+ uint16_t _port, bool _reliable) {
+ std::shared_ptr<endpoint> its_endpoint;
+
+ try {
+ boost::asio::ip::address its_unicast = configuration_->get_unicast();
+ if (_reliable) {
+ its_endpoint = std::make_shared<tcp_server_endpoint_impl>(
+ shared_from_this(),
+ boost::asio::ip::tcp::endpoint(its_unicast, _port), io_);
+ if (configuration_->has_enabled_magic_cookies(
+ its_unicast.to_string(), _port)) {
+ its_endpoint->enable_magic_cookies();
+ }
+ } else {
+ // TODO: this should be more specific.
+ if (its_unicast.is_v4()) {
+ its_unicast = boost::asio::ip::address_v4::any();
+ } else {
+ // TODO: how is "ANY" specified in IPv6?
+ }
+ boost::asio::ip::udp::endpoint ep(its_unicast, _port);
+ its_endpoint = std::make_shared<udp_server_endpoint_impl>(
+ shared_from_this(),
+ ep, io_);
+ }
+
+ if (its_endpoint) {
+ server_endpoints_[_port][_reliable] = its_endpoint;
+ its_endpoint->start();
+ }
+ } catch (std::exception &e) {
+ host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED);
+ VSOMEIP_ERROR << e.what();
+ }
+
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::find_server_endpoint(
- uint16_t _port, bool _reliable) {
- std::shared_ptr<endpoint> its_endpoint;
- auto found_port = server_endpoints_.find(_port);
- if (found_port != server_endpoints_.end()) {
- auto found_endpoint = found_port->second.find(_reliable);
- if (found_endpoint != found_port->second.end()) {
- its_endpoint = found_endpoint->second;
- }
- }
- return (its_endpoint);
+ uint16_t _port, bool _reliable) {
+ std::shared_ptr<endpoint> its_endpoint;
+ auto found_port = server_endpoints_.find(_port);
+ if (found_port != server_endpoints_.end()) {
+ auto found_endpoint = found_port->second.find(_reliable);
+ if (found_endpoint != found_port->second.end()) {
+ its_endpoint = found_endpoint->second;
+ }
+ }
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::find_or_create_server_endpoint(
- uint16_t _port, bool _reliable) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(_port,
- _reliable);
- if (0 == its_endpoint) {
- its_endpoint = create_server_endpoint(_port, _reliable);
- }
- return (its_endpoint);
+ uint16_t _port, bool _reliable) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(_port,
+ _reliable);
+ if (0 == its_endpoint) {
+ its_endpoint = create_server_endpoint(_port, _reliable);
+ }
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::find_local(client_t _client) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- std::shared_ptr<endpoint> its_endpoint;
- auto found_endpoint = local_clients_.find(_client);
- if (found_endpoint != local_clients_.end()) {
- its_endpoint = found_endpoint->second;
- }
- return (its_endpoint);
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ std::shared_ptr<endpoint> its_endpoint;
+ auto found_endpoint = local_clients_.find(_client);
+ if (found_endpoint != local_clients_.end()) {
+ its_endpoint = found_endpoint->second;
+ }
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::create_local(client_t _client) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+
+ std::stringstream its_path;
+ its_path << VSOMEIP_BASE_PATH << std::hex << _client;
- std::stringstream its_path;
- its_path << BASE_PATH << std::hex << _client;
+#ifdef WIN32
+ boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
+ int port = 51235 + _client;
+#endif
- std::shared_ptr<endpoint> its_endpoint = std::make_shared<
- local_client_endpoint_impl>(shared_from_this(),
- boost::asio::local::stream_protocol::endpoint(its_path.str()), io_);
- local_clients_[_client] = its_endpoint;
- its_endpoint->start();
- return (its_endpoint);
+ std::shared_ptr<endpoint> its_endpoint = std::make_shared<
+ local_client_endpoint_impl>(shared_from_this(),
+#ifdef WIN32
+ boost::asio::ip::tcp::endpoint(address, port)
+#else
+ boost::asio::local::stream_protocol::endpoint(its_path.str())
+#endif
+ , io_);
+ local_clients_[_client] = its_endpoint;
+ its_endpoint->start();
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_impl::find_or_create_local(
- client_t _client) {
- std::shared_ptr<endpoint> its_endpoint(find_local(_client));
- if (!its_endpoint) {
- its_endpoint = create_local(_client);
- }
- return (its_endpoint);
+ client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint(find_local(_client));
+ if (!its_endpoint) {
+ its_endpoint = create_local(_client);
+ }
+ return (its_endpoint);
}
void routing_manager_impl::remove_local(client_t _client) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- std::shared_ptr<endpoint> its_endpoint = find_local(_client);
- its_endpoint->stop();
- local_clients_.erase(_client);
+ {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ std::shared_ptr<endpoint> its_endpoint = find_local(_client);
+ its_endpoint->stop();
+ local_clients_.erase(_client);
+ }
+ {
+ std::lock_guard<std::mutex> its_lock(local_mutex_);
+ // Finally remove all services that are implemented by the client.
+ std::set<std::pair<service_t, instance_t>> its_services;
+ for (auto& s : local_services_) {
+ for (auto& i : s.second) {
+ if (i.second == _client)
+ its_services.insert({ s.first, i.first });
+ }
+ }
+
+ for (auto& si : its_services) {
+ local_services_[si.first].erase(si.second);
+ if (local_services_[si.first].size() == 0)
+ local_services_.erase(si.first);
+ }
+ }
}
std::shared_ptr<endpoint> routing_manager_impl::find_local(service_t _service,
- instance_t _instance) {
- return (find_local(find_local_client(_service, _instance)));
+ instance_t _instance) {
+ client_t client = find_local_client(_service, _instance);
+ if (client) {
+ return find_local(client);
+ }
+ return nullptr;
}
client_t routing_manager_impl::find_local_client(service_t _service,
- instance_t _instance) {
- client_t its_client(0);
- auto found_service = local_services_.find(_service);
- if (found_service != local_services_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- its_client = found_instance->second;
- }
- }
- return (its_client);
+ instance_t _instance) {
+ std::lock_guard<std::mutex> its_lock(local_mutex_);
+ client_t its_client(0);
+ auto found_service = local_services_.find(_service);
+ if (found_service != local_services_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ its_client = found_instance->second;
+ }
+ }
+ return (its_client);
}
std::set<client_t> routing_manager_impl::find_local_clients(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) {
- std::set<client_t> its_clients;
- auto found_service = eventgroup_clients_.find(_service);
- if (found_service != eventgroup_clients_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_eventgroup = found_instance->second.find(_eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- its_clients = found_eventgroup->second;
- }
- }
- }
- return (its_clients);
+ instance_t _instance, eventgroup_t _eventgroup) {
+ std::set<client_t> its_clients;
+ auto found_service = eventgroup_clients_.find(_service);
+ if (found_service != eventgroup_clients_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ its_clients = found_eventgroup->second;
+ }
+ }
+ }
+ return (its_clients);
}
instance_t routing_manager_impl::find_instance(service_t _service,
- endpoint * _endpoint) {
- instance_t its_instance(0xFFFF);
- auto found_service = service_instances_.find(_service);
- if (found_service != service_instances_.end()) {
- auto found_endpoint = found_service->second.find(_endpoint);
- if (found_endpoint != found_service->second.end()) {
- its_instance = found_endpoint->second;
- }
- }
- return (its_instance);
+ endpoint * _endpoint) {
+ instance_t its_instance(0xFFFF);
+ auto found_service = service_instances_.find(_service);
+ if (found_service != service_instances_.end()) {
+ auto found_endpoint = found_service->second.find(_endpoint);
+ if (found_endpoint != found_service->second.end()) {
+ its_instance = found_endpoint->second;
+ }
+ }
+ return (its_instance);
}
+std::shared_ptr<endpoint> routing_manager_impl::create_remote_client(
+ service_t _service, instance_t _instance, bool _reliable, client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint;
+ auto found_service = remote_services_.find(_service);
+ if (found_service != remote_services_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ for (auto its_client : found_instance->second) {
+ auto found_reliability = its_client.second.find(_reliable);
+ if (found_reliability != its_client.second.end()) {
+ std::shared_ptr<endpoint> endpoint = found_reliability->second;
+ boost::asio::ip::address address;
+ endpoint->get_remote_address(address);
+ its_endpoint = find_or_create_client_endpoint(address,
+ endpoint->get_remote_port(), _reliable, _client);
+ break;
+ }
+ }
+ }
+ }
+ if (its_endpoint) {
+ remote_services_[_service][_instance][_client][_reliable] = its_endpoint;
+ service_instances_[_service][its_endpoint.get()] = _instance;
+ }
+ return its_endpoint;
+}
+
+
std::shared_ptr<endpoint> routing_manager_impl::find_remote_client(
- service_t _service, instance_t _instance, bool _reliable) {
- std::shared_ptr<endpoint> its_endpoint;
- auto found_service = remote_services_.find(_service);
- if (found_service != remote_services_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_reliability = found_instance->second.find(_reliable);
- if (found_reliability != found_instance->second.end()) {
- its_endpoint = found_reliability->second;
- }
- }
- }
- return (its_endpoint);
+ service_t _service, instance_t _instance, bool _reliable, client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint;
+ auto found_service = remote_services_.find(_service);
+ if (found_service != remote_services_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_client = found_instance->second.find(_client);
+ if (found_client != found_instance->second.end()) {
+ auto found_reliability = found_client->second.find(_reliable);
+ if (found_reliability != found_client->second.end()) {
+ its_endpoint = found_reliability->second;
+ }
+ }
+ }
+ }
+ return its_endpoint;
}
std::shared_ptr<event> routing_manager_impl::find_event(service_t _service,
- instance_t _instance, event_t _event) const {
- std::shared_ptr<event> its_event;
- auto find_service = events_.find(_service);
- if (find_service != events_.end()) {
- auto find_instance = find_service->second.find(_instance);
- if (find_instance != find_service->second.end()) {
- auto find_event = find_instance->second.find(_event);
- if (find_event != find_instance->second.end()) {
- its_event = find_event->second;
- }
- }
- }
- return (its_event);
+ instance_t _instance, event_t _event) const {
+ std::shared_ptr<event> its_event;
+ auto find_service = events_.find(_service);
+ if (find_service != events_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end()) {
+ auto find_event = find_instance->second.find(_event);
+ if (find_event != find_instance->second.end()) {
+ its_event = find_event->second;
+ }
+ }
+ }
+ return (its_event);
}
std::set<std::shared_ptr<event> > routing_manager_impl::find_events(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup) {
- std::set<std::shared_ptr<event> > its_events;
- 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()) {
- auto found_eventgroup = found_instance->second.find(_eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- return (found_eventgroup->second->get_events());
- }
- }
- }
- return (its_events);
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup) {
+ std::set<std::shared_ptr<event> > its_events;
+ 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()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ return (found_eventgroup->second->get_events());
+ }
+ }
+ }
+ return (its_events);
}
void routing_manager_impl::add_routing_info(service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl, const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) {
- std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if (!its_info) {
- its_info = create_service(_service, _instance, _major, _minor, _ttl);
- services_[_service][_instance] = its_info;
- }
-
- std::shared_ptr<endpoint> its_endpoint(
- find_or_create_client_endpoint(_address, _port, _reliable));
- its_info->set_endpoint(its_endpoint, _reliable);
-
- remote_services_[_service][_instance][_reliable] = its_endpoint;
- service_instances_[_service][its_endpoint.get()] = _instance;
- stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance);
-
- if (its_endpoint->is_connected())
- host_->on_availability(_service, _instance, true);
+ instance_t _instance, major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl, const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable) {
+ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
+ if (!its_info) {
+ its_info = create_service(_service, _instance, _major, _minor, _ttl);
+ services_[_service][_instance] = its_info;
+ }
+
+ // If host doesn't have a specific endpoint we create it here
+ if (specific_endpoint_clients.find(get_client()) == specific_endpoint_clients.end()) {
+ std::shared_ptr<endpoint> its_endpoint(
+ find_or_create_client_endpoint(_address, _port, _reliable, VSOMEIP_ROUTING_CLIENT));
+ its_info->set_endpoint(its_endpoint, _reliable);
+
+ remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT][_reliable] = its_endpoint;
+ service_instances_[_service][its_endpoint.get()] = _instance;
+
+ if (its_endpoint->is_connected()) {
+ host_->on_availability(_service, _instance, true);
+ }
+ }
+
+ // Create all specific endpoints for proxies probably like them
+ for (client_t client : specific_endpoint_clients) {
+ std::shared_ptr<endpoint> its_endpoint(
+ find_or_create_client_endpoint(_address, _port, _reliable, client));
+
+ if (client == get_client()) {
+ its_info->set_endpoint(its_endpoint, _reliable);
+ }
+
+ remote_services_[_service][_instance][client][_reliable] = its_endpoint;
+ service_instances_[_service][its_endpoint.get()] = _instance;
+
+ if (its_endpoint->is_connected()) {
+ host_->on_availability(_service, _instance, true);
+ }
+ }
+
+ stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance);
}
void routing_manager_impl::del_routing_info(service_t _service,
- instance_t _instance,
- bool _reliable) {
- std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if (its_info) {
- std::shared_ptr<endpoint> its_empty_endpoint;
-
- // TODO: only tell the application if the service is completely gone
- host_->on_availability(_service, _instance, false);
- stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service,
- _instance);
-
- // Implicit unsubscribe
- 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 (auto &its_eventgroup : found_instance->second) {
- its_eventgroup.second->clear_targets();
- }
- }
- }
-
- std::shared_ptr<endpoint> its_endpoint = its_info->get_endpoint(
- _reliable);
- if (its_endpoint) {
- if (1 >= service_instances_[_service].size()) {
- service_instances_.erase(_service);
- } else {
- service_instances_[_service].erase(its_endpoint.get());
- }
-
- remote_services_[_service][_instance].erase(_reliable);
- auto found_endpoint = remote_services_[_service][_instance].find(
- !_reliable);
- if (found_endpoint == remote_services_[_service][_instance].end()) {
- remote_services_[_service].erase(_instance);
- }
- if (1 >= remote_services_[_service].size()) {
- remote_services_.erase(_service);
- }
- }
-
- if (!its_info->get_endpoint(!_reliable)) {
- if (its_info->get_group()) {
- its_info->get_group()->remove_service(_service, _instance);
- if (1 >= services_[_service].size()) {
- services_.erase(_service);
- } else {
- services_[_service].erase(_instance);
- }
- }
- } else {
- its_info->set_endpoint(its_empty_endpoint, _reliable);
- }
- }
+ instance_t _instance,
+ bool _reliable) {
+ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
+ if (its_info) {
+ std::shared_ptr<endpoint> its_empty_endpoint;
+
+ // TODO: only tell the application if the service is completely gone
+ host_->on_availability(_service, _instance, false);
+ stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service,
+ _instance);
+
+ // Implicit unsubscribe
+ 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 (auto &its_eventgroup : found_instance->second) {
+ its_eventgroup.second->clear_targets();
+ }
+ }
+ }
+
+ std::shared_ptr<endpoint> its_endpoint = its_info->get_endpoint(
+ _reliable);
+ if (its_endpoint) {
+ if (1 >= service_instances_[_service].size()) {
+ service_instances_.erase(_service);
+ } else {
+ service_instances_[_service].erase(its_endpoint.get());
+ }
+
+ remote_services_[_service][_instance].erase(_reliable);
+ auto found_endpoint = remote_services_[_service][_instance].find(
+ !_reliable);
+ if (found_endpoint == remote_services_[_service][_instance].end()) {
+ remote_services_[_service].erase(_instance);
+ }
+ if (1 >= remote_services_[_service].size()) {
+ remote_services_.erase(_service);
+ }
+ }
+
+ if (!its_info->get_endpoint(!_reliable)) {
+ if (its_info->get_group()) {
+ its_info->get_group()->remove_service(_service, _instance);
+ if (1 >= services_[_service].size()) {
+ services_.erase(_service);
+ } else {
+ services_[_service].erase(_instance);
+ }
+ }
+ } else {
+ its_info->set_endpoint(its_empty_endpoint, _reliable);
+ }
+ }
}
void routing_manager_impl::init_routing_info() {
- VSOMEIP_INFO<< "Service Discovery disabled. Using static routing information.";
- for (auto i : configuration_->get_remote_services()) {
- std::string its_address = configuration_->get_unicast(i.first, i.second);
- uint16_t its_reliable = configuration_->get_reliable_port(i.first,
- i.second);
- uint16_t its_unreliable = configuration_->get_unreliable_port(i.first,
- i.second);
-
- if (VSOMEIP_INVALID_PORT != its_reliable) {
- VSOMEIP_DEBUG << "Initializing route to service ["
- << std::hex << i.first << "." << i.second << "]";
- add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR,
- DEFAULT_TTL,
- boost::asio::ip::address::from_string(its_address),
- its_reliable, true);
- }
-
- if (VSOMEIP_INVALID_PORT != its_unreliable) {
- add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR,
- DEFAULT_TTL,
- boost::asio::ip::address::from_string(its_address),
- its_unreliable, false);
- }
- }
+ VSOMEIP_INFO<< "Service Discovery disabled. Using static routing information.";
+ for (auto i : configuration_->get_remote_services()) {
+ std::string its_address = configuration_->get_unicast(i.first, i.second);
+ uint16_t its_reliable = configuration_->get_reliable_port(i.first,
+ i.second);
+ uint16_t its_unreliable = configuration_->get_unreliable_port(i.first,
+ i.second);
+
+ if (VSOMEIP_INVALID_PORT != its_reliable) {
+ VSOMEIP_DEBUG << "Initializing route to service ["
+ << std::hex << i.first << "." << i.second << "]";
+ add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR,
+ DEFAULT_TTL,
+ boost::asio::ip::address::from_string(its_address),
+ its_reliable, true);
+ }
+
+ if (VSOMEIP_INVALID_PORT != its_unreliable) {
+ add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR,
+ DEFAULT_TTL,
+ boost::asio::ip::address::from_string(its_address),
+ its_unreliable, false);
+ }
+ }
}
void routing_manager_impl::init_event_routing_info() {
- // TODO: the following should be done before(!) initializing
- // the configuration object to allow the configuration to
- // directly write to the target structure!
- std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events =
- configuration_->get_events();
- for (auto i : its_events) {
- for (auto j : i.second) {
- for (auto k : j.second) {
- std::shared_ptr<event> its_event(std::make_shared<event>(this));
- its_event->set_service(i.first);
- its_event->set_instance(j.first);
- its_event->set_event(k);
- configuration_->set_event(its_event); // sets is_field/is_reliable
- events_[i.first][j.first][k] = its_event;
- }
- }
- }
-
- std::map<service_t,
- std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups =
- configuration_->get_eventgroups();
- for (auto i : its_eventgroups) {
- for (auto j : i.second) {
- for (auto k : j.second) {
- eventgroups_[i.first][j.first][k.first] = std::make_shared<
- eventgroupinfo>();
- for (auto l : k.second) {
- std::shared_ptr<event> its_event = find_event(i.first,
- j.first, l);
- if (its_event) {
- eventgroups_[i.first][j.first][k.first]->add_event(
- its_event);
- its_event->add_eventgroup(k.first);
- }
- }
- }
- }
- }
-
-#if 1
- for (auto i : eventgroups_) {
- for (auto j : i.second) {
- for (auto k : j.second) {
- VSOMEIP_DEBUG<< "Eventgroup [" << std::hex << std::setw(4)
- << std::setfill('0') << i.first << "." << j.first << "." << k.first
- << "]";
- for (auto l : k.second->get_events()) {
- VSOMEIP_DEBUG << " Event " << std::hex << std::setw(4)
- << std::setfill('0') << l->get_event();
- }
- }
- }
- }
+ // TODO: the following should be done before(!) initializing
+ // the configuration object to allow the configuration to
+ // directly write to the target structure!
+ std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events =
+ configuration_->get_events();
+ for (auto i : its_events) {
+ for (auto j : i.second) {
+ for (auto k : j.second) {
+ std::shared_ptr<event> its_event(std::make_shared<event>(this));
+ its_event->set_service(i.first);
+ its_event->set_instance(j.first);
+ its_event->set_event(k);
+ configuration_->set_event(its_event); // sets is_field/is_reliable
+ events_[i.first][j.first][k] = its_event;
+ }
+ }
+ }
+
+ std::map<service_t,
+ std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups =
+ configuration_->get_eventgroups();
+ for (auto i : its_eventgroups) {
+ for (auto j : i.second) {
+ for (auto k : j.second) {
+ eventgroups_[i.first][j.first][k.first] = std::make_shared<
+ eventgroupinfo>();
+ for (auto l : k.second) {
+ std::shared_ptr<event> its_event = find_event(i.first,
+ j.first, l);
+ if (its_event) {
+ eventgroups_[i.first][j.first][k.first]->add_event(
+ its_event);
+ its_event->add_eventgroup(k.first);
+ }
+ }
+ }
+ }
+ }
+
+#if 0
+ for (auto i : eventgroups_) {
+ for (auto j : i.second) {
+ for (auto k : j.second) {
+ VSOMEIP_DEBUG<< "Eventgroup [" << std::hex << std::setw(4)
+ << std::setfill('0') << i.first << "." << j.first << "." << k.first
+ << "]";
+ for (auto l : k.second->get_events()) {
+ VSOMEIP_DEBUG << " Event " << std::hex << std::setw(4)
+ << std::setfill('0') << l->get_event();
+ }
+ }
+ }
+ }
#endif
}
void routing_manager_impl::on_subscribe(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _subscriber,
- std::shared_ptr<endpoint_definition> _target) {
- std::shared_ptr<eventgroupinfo> its_eventgroup
- = find_eventgroup(_service, _instance, _eventgroup);
- if (its_eventgroup) {
- its_eventgroup->add_target(_target); // unicast or multicast
- for (auto its_event : its_eventgroup->get_events()) {
- if (its_event->is_field()) {
- its_event->notify_one(_subscriber); // unicast
- }
- }
- } else {
- VSOMEIP_ERROR<< "subscribe: attempt to subscribe to unknown eventgroup!";
- }
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<endpoint_definition> _subscriber,
+ std::shared_ptr<endpoint_definition> _target) {
+ std::shared_ptr<eventgroupinfo> its_eventgroup
+ = find_eventgroup(_service, _instance, _eventgroup);
+ if (its_eventgroup) {
+ std::shared_ptr < eventgroupinfo > its_info = find_eventgroup(
+ _service, _instance, _eventgroup);
+
+ client_t client = 0;
+ if (!its_info->is_multicast()) {
+ if (!_target->is_reliable()) {
+ uint16_t unreliable_port = configuration_->get_unreliable_port(_service, _instance);
+ auto endpoint = find_or_create_server_endpoint(unreliable_port, false);
+ client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->get_client(_target);
+ _target->set_remote_port(unreliable_port);
+ }
+ else {
+ uint16_t reliable_port = configuration_->get_reliable_port(_service, _instance);
+ auto endpoint = find_or_create_server_endpoint(reliable_port, true);
+ client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->get_client(_target);
+ _target->set_remote_port(reliable_port);
+ }
+ }
+
+ if(!host_->on_subscription(_service, _instance, _eventgroup, client, true)) {
+ VSOMEIP_INFO << "Subscription request for eventgroup " << _eventgroup
+ << " rejected from application handler";
+ return;
+ }
+
+ VSOMEIP_DEBUG << "on_subscribe: target=" << _target->get_address().to_string()
+ << ":" <<_target->get_port() << ":Client=" << std::hex << client;
+
+ send_subscribe(client, _service, _instance, _eventgroup, 0, 0);
+
+ remote_subscriber_map_[client] = _target;
+
+ its_eventgroup->add_target(_target); // unicast or multicast
+ for (auto its_event : its_eventgroup->get_events()) {
+ if (its_event->is_field()) {
+ its_event->notify_one(_subscriber); // unicast
+ }
+ }
+ } else {
+ VSOMEIP_ERROR<< "subscribe: attempt to subscribe to unknown eventgroup!";
+ }
}
void routing_manager_impl::on_unsubscribe(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _target) {
- std::shared_ptr<eventgroupinfo> its_eventgroup = find_eventgroup(_service,
- _instance, _eventgroup);
- if (its_eventgroup) {
- its_eventgroup->del_target(_target);
- } else {
- VSOMEIP_ERROR<<"unsubscribe: attempt to subscribe to unknown eventgroup!";
- }
+ instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<endpoint_definition> _target) {
+ std::shared_ptr<eventgroupinfo> its_eventgroup = find_eventgroup(_service,
+ _instance, _eventgroup);
+ if (its_eventgroup) {
+ std::shared_ptr < eventgroupinfo > its_info = find_eventgroup(
+ _service, _instance, _eventgroup);
+
+ client_t client = 0;
+ if (!its_info->is_multicast()) {
+ if (!_target->is_reliable()) {
+ uint16_t unreliable_port = _target->get_remote_port();
+ auto endpoint = find_or_create_server_endpoint(unreliable_port, false);
+ client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->
+ get_client(_target);
+ } else {
+ uint16_t reliable_port = _target->get_remote_port();
+ auto endpoint = find_or_create_server_endpoint(reliable_port, true);
+ client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->
+ get_client(_target);
+ }
+ }
+
+ VSOMEIP_DEBUG << "on_unsubscribe: target=" << _target->get_address().to_string()
+ << ":" <<_target->get_port() << ":Client=" << std::hex << client;
+
+ its_eventgroup->del_target(_target);
+
+ if (remote_subscriber_map_.find(client) != remote_subscriber_map_.end()) {
+ remote_subscriber_map_.erase(client);
+ }
+ host_->on_subscription(_service, _instance, _eventgroup, client, false);
+
+ } else {
+ VSOMEIP_ERROR<<"unsubscribe: attempt to subscribe to unknown eventgroup!";
+ }
}
void routing_manager_impl::on_subscribe_ack(service_t _service,
- instance_t _instance, const boost::asio::ip::address &_address,
- uint16_t _port) {
- // TODO: find a way of getting rid of the following endpoint in
- // case it used for multicast exclusively and the subscription
- // is withdrawn or the service got lost
- std::shared_ptr<endpoint> its_endpoint = find_or_create_server_endpoint(
- _port, false);
- if (its_endpoint) {
- service_instances_[_service][its_endpoint.get()] = _instance;
- its_endpoint->join(_address.to_string());
- } else {
- VSOMEIP_ERROR<<"Could not find/create multicast endpoint!";
- }
+ instance_t _instance, const boost::asio::ip::address &_address,
+ uint16_t _port) {
+ // TODO: find a way of getting rid of the following endpoint in
+ // case it is used for multicast exclusively and the subscription
+ // is withdrawn or the service got lost
+ std::shared_ptr<endpoint> its_endpoint = find_or_create_server_endpoint(
+ _port, false);
+ if (its_endpoint) {
+ service_instances_[_service][its_endpoint.get()] = _instance;
+ its_endpoint->join(_address.to_string());
+ } else {
+ VSOMEIP_ERROR<<"Could not find/create multicast endpoint!";
+ }
+}
+
+void routing_manager_impl::send_subscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl) {
+
+ byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
+ sizeof(_client));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
+ sizeof(_eventgroup));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_ttl,
+ sizeof(_ttl));
+
+ std::shared_ptr<vsomeip::endpoint> target = find_local(_service, _instance);
+ if (target) {
+ target->send(its_command, sizeof(its_command));
+ }
+}
+
+void routing_manager_impl::send_unsubscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) {
+
+ byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
+ sizeof(_client));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
+ sizeof(_eventgroup));
+
+ std::shared_ptr<vsomeip::endpoint> target = find_local(_service, _instance);
+ if (target) {
+ target->send(its_command, sizeof(its_command));
+ }
}
}
diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp
index 1415542..1df8b90 100644
--- a/implementation/routing/src/routing_manager_proxy.cpp
+++ b/implementation/routing/src/routing_manager_proxy.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -27,540 +26,726 @@
namespace vsomeip {
routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host) :
- io_(_host->get_io()), host_(_host), client_(_host->get_client()), sender_(
- 0), receiver_(0), serializer_(std::make_shared<serializer>()), deserializer_(
- std::make_shared<deserializer>()), is_connected_(false), is_started_(false),
- state_(event_type_e::DEREGISTERED) {
+ io_(_host->get_io()), host_(_host), client_(_host->get_client()), sender_(
+ 0), receiver_(0), serializer_(std::make_shared<serializer>()), deserializer_(
+ std::make_shared<deserializer>()), is_connected_(false), is_started_(false),
+ state_(event_type_e::ET_DEREGISTERED) {
}
routing_manager_proxy::~routing_manager_proxy() {
}
boost::asio::io_service & routing_manager_proxy::get_io() {
- return (io_);
+ return (io_);
}
client_t routing_manager_proxy::get_client() const {
- return client_;
+ return client_;
}
void routing_manager_proxy::init() {
- uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
- if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
-
- serializer_->create_data(its_max_message_size);
-
- std::stringstream its_sender_path;
- sender_ = create_local(VSOMEIP_ROUTING_CLIENT);
-
- std::stringstream its_client;
- its_client << BASE_PATH << std::hex << client_;
-
- ::unlink(its_client.str().c_str());
- receiver_ = std::make_shared<local_server_endpoint_impl>(shared_from_this(),
- boost::asio::local::stream_protocol::endpoint(its_client.str()),
- io_);
+ uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size)
+ its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+ if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size)
+ its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
+
+ serializer_->create_data(its_max_message_size);
+
+ std::stringstream its_sender_path;
+ sender_ = create_local(VSOMEIP_ROUTING_CLIENT);
+
+ std::stringstream its_client;
+ its_client << VSOMEIP_BASE_PATH << std::hex << client_;
+#ifdef WIN32
+ ::_unlink(its_client.str().c_str());
+ int port = 51235 + client_;
+#else
+ ::unlink(its_client.str().c_str());
+#endif
+ receiver_ = std::make_shared<local_server_endpoint_impl>(shared_from_this(),
+#ifdef WIN32
+ boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port),
+#else
+ boost::asio::local::stream_protocol::endpoint(its_client.str()),
+#endif
+ io_);
- VSOMEIP_DEBUG<< "Listening at " << its_client.str();
+#ifdef WIN32
+ VSOMEIP_DEBUG << "Listening at " << port;
+#else
+ VSOMEIP_DEBUG<< "Listening at " << its_client.str();
+#endif
}
void routing_manager_proxy::start() {
- if (sender_)
- sender_->start();
+ if (sender_)
+ sender_->start();
- if (receiver_)
- receiver_->start();
+ if (receiver_)
+ receiver_->start();
- if (is_connected_) {
- register_application();
- }
+ if (is_connected_) {
+ register_application();
+ }
- is_started_ = true;
+ is_started_ = true;
}
void routing_manager_proxy::stop() {
- deregister_application();
+ deregister_application();
- if (receiver_)
- receiver_->stop();
+ if (receiver_)
+ receiver_->stop();
- std::stringstream its_client;
- its_client << BASE_PATH << std::hex << client_;
- ::unlink(its_client.str().c_str());
+ std::stringstream its_client;
+ its_client << VSOMEIP_BASE_PATH << std::hex << client_;
+#ifdef WIN32
+ ::_unlink(its_client.str().c_str());
+#else
+ ::unlink(its_client.str().c_str());
+#endif
- is_started_ = false;
+ is_started_ = false;
}
void routing_manager_proxy::offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl) {
-
- byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE];
- uint32_t its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE
- - VSOMEIP_COMMAND_HEADER_SIZE;
-
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFER_SERVICE;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
- sizeof(_service));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
- sizeof(_instance));
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
- sizeof(_minor));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_ttl,
- sizeof(_ttl));
-
- if (sender_)
- sender_->send(its_command, sizeof(its_command));
+ instance_t _instance, major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl) {
+
+ if (is_connected_) {
+ send_offer_service(_client, _service, _instance, _major, _minor, _ttl);
+ } else {
+ service_data_t offer = { _service, _instance, _major, _minor, _ttl };
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ pending_offers_.insert(offer);
+ }
}
-void routing_manager_proxy::stop_offer_service(client_t _client,
- service_t _service, instance_t _instance) {
-
- byte_t its_command[VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE];
- uint32_t its_size = VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE
- - VSOMEIP_COMMAND_HEADER_SIZE;
-
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_STOP_OFFER_SERVICE;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
- sizeof(_service));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
- sizeof(_instance));
+void routing_manager_proxy::send_offer_service(client_t _client,
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl) {
+
+ byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFER_SERVICE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
+ sizeof(_minor));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_ttl,
+ sizeof(_ttl));
+
+ sender_->send(its_command, sizeof(its_command));
+}
- if (sender_)
- sender_->send(its_command, sizeof(its_command));
+void routing_manager_proxy::stop_offer_service(client_t _client,
+ service_t _service, instance_t _instance) {
+
+ if (is_connected_) {
+ byte_t its_command[VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_STOP_OFFER_SERVICE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+
+ sender_->send(its_command, sizeof(its_command));
+ } else {
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ auto it = pending_offers_.begin();
+ while (it != pending_offers_.end()) {
+ if (it->service_ == _service
+ && it->instance_ == _instance) {
+ break;
+ }
+ it++;
+ }
+
+ if (it != pending_offers_.end()) pending_offers_.erase(it);
+ }
}
void routing_manager_proxy::request_service(client_t _client,
- service_t _service, instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) {
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl, bool _has_selective) {
+
+ is_selective_ = _has_selective;
+ send_request_service(_client, _service, _instance, _major, _minor, _ttl, _has_selective);
}
void routing_manager_proxy::release_service(client_t _client,
- service_t _service, instance_t _instance) {
+ service_t _service, instance_t _instance) {
}
void routing_manager_proxy::subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- ttl_t _ttl) {
- byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
- uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
- - VSOMEIP_COMMAND_HEADER_SIZE;
-
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
- sizeof(_service));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
- sizeof(_instance));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
- sizeof(_eventgroup));
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major;
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_ttl,
- sizeof(_ttl));
-
- if (sender_)
- sender_->send(its_command, sizeof(its_command));
+ instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
+ ttl_t _ttl) {
+ if (is_connected_) {
+ send_subscribe(_client, _service, _instance, _eventgroup, _major, _ttl);
+ } else {
+ eventgroup_data_t subscription = { _service, _instance, _eventgroup, _major, _ttl };
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ pending_subscriptions_.insert(subscription);
+ }
+}
+
+void routing_manager_proxy::send_subscribe(client_t _client, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
+ ttl_t _ttl) {
+ byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
+ sizeof(_eventgroup));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_ttl,
+ sizeof(_ttl));
+
+ sender_->send(its_command, sizeof(its_command));
}
void routing_manager_proxy::unsubscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) {
- byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE];
- uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE
- - VSOMEIP_COMMAND_HEADER_SIZE;
-
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
- sizeof(_service));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
- sizeof(_instance));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
- sizeof(_eventgroup));
-
- if (sender_)
- sender_->send(its_command, sizeof(its_command));
+ instance_t _instance, eventgroup_t _eventgroup) {
+
+ if (is_connected_) {
+ byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup,
+ sizeof(_eventgroup));
+
+ sender_->send(its_command, sizeof(its_command));
+ } else {
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ auto it = pending_subscriptions_.begin();
+ while (it != pending_subscriptions_.end()) {
+ if (it->service_ == _service
+ && it->instance_ == _instance) {
+ break;
+ }
+ it++;
+ }
+
+ if (it != pending_subscriptions_.end()) pending_subscriptions_.erase(it);
+ }
}
bool routing_manager_proxy::send(client_t its_client,
- std::shared_ptr<message> _message,
- bool _flush,
- bool _reliable) {
- bool is_sent(false);
- std::lock_guard<std::mutex> its_lock(serialize_mutex_);
- if (serializer_->serialize(_message.get())) {
- is_sent = send(its_client, serializer_->get_data(),
- serializer_->get_size(), _message->get_instance(), _flush,
- _reliable);
- serializer_->reset();
- }
- return (is_sent);
+ std::shared_ptr<message> _message,
+ bool _flush) {
+ bool is_sent(false);
+
+ std::lock_guard<std::mutex> its_lock(serialize_mutex_);
+ if (serializer_->serialize(_message.get())) {
+ is_sent = send(its_client, serializer_->get_data(),
+ serializer_->get_size(), _message->get_instance(),
+ _flush, _message->is_reliable());
+ serializer_->reset();
+ }
+ return (is_sent);
}
bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
- length_t _size, instance_t _instance,
- bool _flush,
- bool _reliable) {
- bool is_sent(false);
- std::shared_ptr<endpoint> its_target;
- if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
- if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
- service_t its_service = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_SERVICE_POS_MIN],
- _data[VSOMEIP_SERVICE_POS_MAX]);
- std::lock_guard<std::mutex> its_lock(send_mutex_);
- its_target = find_local(its_service, _instance);
- } else {
- client_t its_client = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_CLIENT_POS_MIN],
- _data[VSOMEIP_CLIENT_POS_MAX]);
- std::lock_guard<std::mutex> its_lock(send_mutex_);
- its_target = find_local(its_client);
- }
-
- // If no direct endpoint could be found, route to stub
- if (!its_target)
- its_target = sender_;
-
- std::vector<byte_t> its_command(
- VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t)
- + sizeof(bool) + sizeof(bool));
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SEND;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
- sizeof(client_t));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size,
- sizeof(_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], _data, _size);
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size],
- &_instance, sizeof(instance_t));
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size + sizeof(instance_t)] =
- _flush;
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size + sizeof(instance_t)
- + sizeof(bool)] = _reliable;
+ length_t _size, instance_t _instance,
+ bool _flush,
+ bool _reliable) {
+ bool is_sent(false);
+
+ std::shared_ptr<endpoint> its_target;
+ if (_size > VSOMEIP_MESSAGE_TYPE_POS) {
+ if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
+ service_t its_service = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_SERVICE_POS_MIN],
+ _data[VSOMEIP_SERVICE_POS_MAX]);
+ std::lock_guard<std::mutex> its_lock(send_mutex_);
+ its_target = find_local(its_service, _instance);
+ } else {
+ client_t its_client = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_CLIENT_POS_MIN],
+ _data[VSOMEIP_CLIENT_POS_MAX]);
+ std::lock_guard<std::mutex> its_lock(send_mutex_);
+ its_target = find_local(its_client);
+ }
+
+ // If no direct endpoint could be found, route to stub
+ if (!its_target)
+ its_target = sender_;
+
+ std::vector<byte_t> its_command(
+ VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t)
+ + sizeof(bool) + sizeof(bool));
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SEND;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
+ sizeof(client_t));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size,
+ sizeof(_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], _data, _size);
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size],
+ &_instance, sizeof(instance_t));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size + sizeof(instance_t)] =
+ _flush;
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size + sizeof(instance_t)
+ + sizeof(bool)] = _reliable;
#if 0
- std::stringstream msg;
- msg << "rmp:send: ";
- for (int i = 0; i < its_command.size(); i++)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "rmp:send: ";
+ for (int i = 0; i < its_command.size(); i++)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- is_sent = its_target->send(&its_command[0], its_command.size());
- }
- return (is_sent);
+ is_sent = its_target->send(&its_command[0], its_command.size());
+ }
+ return (is_sent);
}
bool routing_manager_proxy::send_to(
- const std::shared_ptr<endpoint_definition> &_target,
- std::shared_ptr<message> _message) {
- return (false);
+ const std::shared_ptr<endpoint_definition> &_target,
+ std::shared_ptr<message> _message) {
+ return (false);
}
bool routing_manager_proxy::send_to(
- const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size) {
- return (false);
+ const std::shared_ptr<endpoint_definition> &_target,
+ const byte_t *_data, uint32_t _size) {
+ return (false);
}
void routing_manager_proxy::notify(
- service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload) {
- std::shared_ptr<message> its_notification = runtime::get()->create_notification();
- its_notification->set_service(_service);
- its_notification->set_instance(_instance);
- its_notification->set_method(_event);
- its_notification->set_payload(_payload);
- send(VSOMEIP_ROUTING_CLIENT, its_notification, true, true);
+ service_t _service, instance_t _instance, event_t _event,
+ std::shared_ptr<payload> _payload) {
+ std::shared_ptr<message> its_notification = runtime::get()->create_request();
+ its_notification->set_message_type(message_type_e::MT_REQUEST_NO_RETURN);
+ its_notification->set_service(_service);
+ its_notification->set_instance(_instance);
+ its_notification->set_method(_event);
+ its_notification->set_payload(_payload);
+ if (is_connected_) {
+ send(VSOMEIP_ROUTING_CLIENT, its_notification, true);
+ } else {
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ pending_notifications_[_service][_instance][_event] = its_notification;
+ }
+}
+
+void routing_manager_proxy::notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload, client_t _client) {
+
+ std::shared_ptr<message> its_notification = runtime::get()->create_notification();
+ its_notification->set_service(_service);
+ its_notification->set_instance(_instance);
+ its_notification->set_method(_event);
+ its_notification->set_payload(_payload);
+ its_notification->set_client(_client);
+ send(VSOMEIP_ROUTING_CLIENT, its_notification, true);
}
void routing_manager_proxy::on_connect(std::shared_ptr<endpoint> _endpoint) {
- is_connected_ = is_connected_ || (_endpoint == sender_);
- if (is_connected_ && is_started_) {
- register_application();
- }
+ is_connected_ = is_connected_ || (_endpoint == sender_);
+ if (is_connected_ && is_started_) {
+ register_application();
+ }
}
void routing_manager_proxy::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
- is_connected_ = !(_endpoint == sender_);
- if (!is_connected_) {
- host_->on_event(event_type_e::DEREGISTERED);
- }
+ is_connected_ = !(_endpoint == sender_);
+ if (!is_connected_) {
+ host_->on_event(event_type_e::ET_DEREGISTERED);
+ }
}
void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
- endpoint *_receiver) {
+ endpoint *_receiver) {
#if 0
- std::stringstream msg;
- msg << "rmp::on_message: ";
- for (int i = 0; i < _size; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "rmp::on_message: ";
+ for (int i = 0; i < _size; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- byte_t its_command;
- client_t its_client;
- length_t its_length;
-
- if (_size > VSOMEIP_COMMAND_SIZE_POS_MAX) {
- its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
- std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
- sizeof(its_client));
- std::memcpy(&its_length, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN],
- sizeof(its_length));
-
- switch (its_command) {
- case VSOMEIP_SEND: {
- instance_t its_instance;
- std::memcpy(&its_instance,
- &_data[_size - sizeof(instance_t) - sizeof(bool)
- - sizeof(bool)], sizeof(instance_t));
- deserializer_->set_data(&_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- its_length);
- std::shared_ptr<message> its_message(
- deserializer_->deserialize_message());
- if (its_message) {
- its_message->set_instance(its_instance);
- host_->on_message(its_message);
- } else {
- // TODO: send_error(return_code_e::E_MALFORMED_MESSAGE);
- }
- deserializer_->reset();
- }
- break;
-
- case VSOMEIP_ROUTING_INFO:
- on_routing_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
- break;
-
- case VSOMEIP_PING:
- send_pong();
- break;
-
- default:
- break;
- }
- }
+ byte_t its_command;
+ client_t its_client;
+ length_t its_length;
+ service_t its_service;
+ instance_t its_instance;
+ eventgroup_t its_eventgroup;
+ //event_t its_event;
+ major_version_t its_major;
+ minor_version_t its_minor;
+ ttl_t its_ttl;
+
+ if (_size > VSOMEIP_COMMAND_SIZE_POS_MAX) {
+ its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
+ std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
+ sizeof(its_client));
+ std::memcpy(&its_length, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN],
+ sizeof(its_length));
+
+ switch (its_command) {
+ case VSOMEIP_SEND: {
+ instance_t its_instance;
+ std::memcpy(&its_instance,
+ &_data[_size - sizeof(instance_t) - sizeof(bool)
+ - sizeof(bool)], sizeof(instance_t));
+ deserializer_->set_data(&_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ its_length);
+ std::shared_ptr<message> its_message(
+ deserializer_->deserialize_message());
+ if (its_message) {
+ its_message->set_instance(its_instance);
+ host_->on_message(its_message);
+ } else {
+ // TODO: send_error(return_code_e::E_MALFORMED_MESSAGE);
+ }
+ deserializer_->reset();
+ }
+ break;
+
+ case VSOMEIP_ROUTING_INFO:
+ on_routing_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length);
+ break;
+
+ case VSOMEIP_PING:
+ send_pong();
+ break;
+
+ case VSOMEIP_SUBSCRIBE:
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_eventgroup));
+ std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
+ sizeof(its_major));
+ std::memcpy(&its_ttl, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
+ sizeof(its_ttl));
+
+ host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, true);
+ break;
+
+ case VSOMEIP_UNSUBSCRIBE:
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_eventgroup));
+ host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, false);
+ break;
+
+ default:
+ break;
+ }
+ }
}
void routing_manager_proxy::on_routing_info(const byte_t *_data,
- uint32_t _size) {
+ uint32_t _size) {
#if 0
- std::stringstream msg;
- msg << "rmp::on_routing_info: ";
- for (int i = 0; i < _size; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "rmp::on_routing_info(" << std::hex << client_ << "): ";
+ for (int i = 0; i < _size; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- event_type_e its_state(event_type_e::DEREGISTERED);
-
- std::map<service_t,
- std::map<instance_t, client_t> > old_local_services = local_services_;
- local_services_.clear();
-
- uint32_t i = 0;
- while (i + sizeof(uint32_t) <= _size) {
- uint32_t its_client_size;
- std::memcpy(&its_client_size, &_data[i], sizeof(uint32_t));
- i += sizeof(uint32_t);
-
- if (i + sizeof(client_t) <= _size) {
- client_t its_client;
- std::memcpy(&its_client, &_data[i], sizeof(client_t));
- i += sizeof(client_t);
-
- if (its_client != client_) {
- (void) find_or_create_local(its_client);
- } else {
- its_state = event_type_e::REGISTERED;
- }
-
- uint32_t j = 0;
- while (j + sizeof(uint32_t) <= its_client_size) {
- uint32_t its_services_size;
- std::memcpy(&its_services_size, &_data[i + j], sizeof(uint32_t));
- j += sizeof(uint32_t);
-
- if (its_services_size <= sizeof(service_t) + sizeof(instance_t)) {
- service_t its_service;
- std::memcpy(&its_service, &_data[i + j], sizeof(service_t));
- j += sizeof(service_t);
-
- instance_t its_instance;
- std::memcpy(&its_instance, &_data[i + j], sizeof(instance_t));
- j += sizeof(instance_t);
-
- if (its_client != client_)
- local_services_[its_service][its_instance] = its_client;
- }
- }
-
- i += j;
- }
- }
-
- // inform host about its own registration state changes
- if (state_ != its_state) {
- host_->on_event(its_state);
- state_ = its_state;
- }
-
- // Check for services that are no longer available
- for (auto i : old_local_services) {
- auto found_service = local_services_.find(i.first);
- if (found_service != local_services_.end()) {
- for (auto j : i.second) {
- auto found_instance = found_service->second.find(j.first);
- if (found_instance == found_service->second.end()) {
- host_->on_availability(i.first, j.first, false);
- }
- }
- } else {
- for (auto j : i.second) {
- host_->on_availability(i.first, j.first, false);
- }
- }
- }
-
- // Check for services that are newly available
- for (auto i : local_services_) {
- auto found_service = old_local_services.find(i.first);
- if (found_service != old_local_services.end()) {
- for (auto j : i.second) {
- auto found_instance = found_service->second.find(j.first);
- if (found_instance == found_service->second.end()) {
- host_->on_availability(i.first, j.first, true);
- }
- }
- } else {
- for (auto j : i.second) {
- host_->on_availability(i.first, j.first, true);
- }
- }
- }
-}
-
-bool routing_manager_proxy::is_available(service_t _service,
- instance_t _instance) const {
- auto found_local_service = local_services_.find(_service);
- if (found_local_service != local_services_.end()) {
- auto found_local_instance = found_local_service->second.find(_instance);
- if (found_local_instance != found_local_service->second.end()) {
- return (true);
- }
- }
-
- // TODO: ask routing manager for external services
- return (false);
+ event_type_e its_state(event_type_e::ET_DEREGISTERED);
+
+ std::map<service_t,
+ std::map<instance_t, client_t> > old_local_services = local_services_;
+ local_services_.clear();
+
+ uint32_t i = 0;
+ while (i + sizeof(uint32_t) <= _size) {
+ uint32_t its_client_size;
+ std::memcpy(&its_client_size, &_data[i], sizeof(uint32_t));
+ i += sizeof(uint32_t);
+
+ if (i + sizeof(client_t) <= _size) {
+ client_t its_client;
+ std::memcpy(&its_client, &_data[i], sizeof(client_t));
+ i += sizeof(client_t);
+
+ if (its_client != client_) {
+ (void) find_or_create_local(its_client);
+ } else {
+ its_state = event_type_e::ET_REGISTERED;
+ }
+
+ uint32_t j = 0;
+ while (j + sizeof(uint32_t) <= its_client_size) {
+ uint32_t its_services_size;
+ std::memcpy(&its_services_size, &_data[i + j], sizeof(uint32_t));
+ j += sizeof(uint32_t);
+
+ if (its_services_size >= sizeof(service_t) + sizeof(instance_t)) {
+ its_services_size -= sizeof(service_t);
+
+ service_t its_service;
+ std::memcpy(&its_service, &_data[i + j], sizeof(service_t));
+ j += sizeof(service_t);
+
+ while (its_services_size >= sizeof(instance_t)) {
+ instance_t its_instance;
+ std::memcpy(&its_instance, &_data[i + j], sizeof(instance_t));
+ j += sizeof(instance_t);
+
+ if (its_client != client_)
+ local_services_[its_service][its_instance] = its_client;
+
+ its_services_size -= sizeof(instance_t);
+ }
+ }
+ }
+
+ i += j;
+ }
+ }
+
+ // inform host about its own registration state changes
+ if (state_ != its_state) {
+ host_->on_event(its_state);
+ state_ = its_state;
+ }
+
+ // Check for services that are no longer available
+ for (auto i : old_local_services) {
+ auto found_service = local_services_.find(i.first);
+ if (found_service != local_services_.end()) {
+ for (auto j : i.second) {
+ auto found_instance = found_service->second.find(j.first);
+ if (found_instance == found_service->second.end()) {
+ host_->on_availability(i.first, j.first, false);
+ }
+ }
+ } else {
+ for (auto j : i.second) {
+ host_->on_availability(i.first, j.first, false);
+ }
+ }
+ }
+
+ // Check for services that are newly available
+ for (auto i : local_services_) {
+ auto found_service = old_local_services.find(i.first);
+ if (found_service != old_local_services.end()) {
+ for (auto j : i.second) {
+ auto found_instance = found_service->second.find(j.first);
+ if (found_instance == found_service->second.end()) {
+ host_->on_availability(i.first, j.first, true);
+ }
+ }
+ } else {
+ for (auto j : i.second) {
+ host_->on_availability(i.first, j.first, true);
+ }
+ }
+ }
}
void routing_manager_proxy::register_application() {
- byte_t its_command[] = {
- VSOMEIP_REGISTER_APPLICATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memset(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], 0,
- sizeof(uint32_t));
-
- if (is_connected_)
- (void)sender_->send(its_command, sizeof(its_command));
+ byte_t its_command[] = {
+ VSOMEIP_REGISTER_APPLICATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memset(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], 0,
+ sizeof(uint32_t));
+
+ if (is_connected_) {
+ (void)sender_->send(its_command, sizeof(its_command));
+
+ for (auto &po : pending_offers_)
+ send_offer_service(client_, po.service_, po.instance_,
+ po.major_, po.minor_, po.ttl_);
+
+ for (auto &s : pending_notifications_) {
+ for (auto &i : s.second) {
+ for (auto &pn : i.second) {
+ send(VSOMEIP_ROUTING_CLIENT, pn.second, true);
+ }
+ }
+ }
+
+ for (auto &po : pending_requests_) {
+ send_request_service(client_, po.service_, po.instance_,
+ po.major_, po.minor_, po.ttl_, is_selective_);
+ }
+
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ for (auto &ps : pending_subscriptions_)
+ send_subscribe(client_, ps.service_, ps.instance_,
+ ps.eventgroup_, ps.major_, ps.ttl_);
+
+ pending_offers_.clear();
+ pending_requests_.clear();
+ pending_notifications_.clear();
+ pending_subscriptions_.clear();
+ }
}
void routing_manager_proxy::deregister_application() {
- uint32_t its_size = sizeof(client_);
-
- std::vector<byte_t> its_command(VSOMEIP_COMMAND_HEADER_SIZE + its_size);
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_DEREGISTER_APPLICATION;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- if (is_connected_)
- (void)sender_->send(&its_command[0], its_command.size());
+ uint32_t its_size = sizeof(client_);
+
+ std::vector<byte_t> its_command(VSOMEIP_COMMAND_HEADER_SIZE + its_size);
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_DEREGISTER_APPLICATION;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ if (is_connected_)
+ (void)sender_->send(&its_command[0], its_command.size());
}
std::shared_ptr<endpoint> routing_manager_proxy::find_local(client_t _client) {
- std::shared_ptr<endpoint> its_endpoint;
- auto found_endpoint = local_endpoints_.find(_client);
- if (found_endpoint != local_endpoints_.end()) {
- its_endpoint = found_endpoint->second;
- }
- return (its_endpoint);
+ std::shared_ptr<endpoint> its_endpoint;
+ auto found_endpoint = local_endpoints_.find(_client);
+ if (found_endpoint != local_endpoints_.end()) {
+ its_endpoint = found_endpoint->second;
+ }
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_proxy::create_local(
- client_t _client) {
- std::stringstream its_path;
- its_path << BASE_PATH << std::hex << _client;
-
- VSOMEIP_DEBUG<< "Connecting to ["
- << std::hex << _client << "] at " << its_path.str();
+ client_t _client) {
+ std::stringstream its_path;
+ its_path << VSOMEIP_BASE_PATH << std::hex << _client;
+
+#ifdef WIN32
+ boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
+ int port = 51234;
+ VSOMEIP_DEBUG<< "Connecting to ["
+ << std::hex << _client << "] at " << port;
+#else
+ VSOMEIP_DEBUG<< "Connecting to ["
+ << std::hex << _client << "] at " << its_path.str();
+#endif
- std::shared_ptr<endpoint> its_endpoint = std::make_shared<
- local_client_endpoint_impl>(shared_from_this(),
- boost::asio::local::stream_protocol::endpoint(its_path.str()), io_);
+ std::shared_ptr<endpoint> its_endpoint = std::make_shared<
+ local_client_endpoint_impl>(shared_from_this(),
+#ifdef WIN32
+ boost::asio::ip::tcp::endpoint(address, port),
+#else
+ boost::asio::local::stream_protocol::endpoint(its_path.str()),
+#endif
+ io_);
- local_endpoints_[_client] = its_endpoint;
+ local_endpoints_[_client] = its_endpoint;
- return (its_endpoint);
+ return (its_endpoint);
}
std::shared_ptr<endpoint> routing_manager_proxy::find_or_create_local(
- client_t _client) {
- std::shared_ptr<endpoint> its_endpoint(find_local(_client));
- if (0 == its_endpoint) {
- its_endpoint = create_local(_client);
- its_endpoint->start();
- }
- return (its_endpoint);
+ client_t _client) {
+ std::shared_ptr<endpoint> its_endpoint(find_local(_client));
+ if (0 == its_endpoint) {
+ its_endpoint = create_local(_client);
+ its_endpoint->start();
+ }
+ return (its_endpoint);
}
void routing_manager_proxy::remove_local(client_t _client) {
- std::shared_ptr<endpoint> its_endpoint(find_local(_client));
- if (its_endpoint)
- its_endpoint->stop();
- local_endpoints_.erase(_client);
+ std::shared_ptr<endpoint> its_endpoint(find_local(_client));
+ if (its_endpoint)
+ its_endpoint->stop();
+ local_endpoints_.erase(_client);
}
std::shared_ptr<endpoint> routing_manager_proxy::find_local(service_t _service,
- instance_t _instance) {
- client_t its_client(0);
- auto found_service = local_services_.find(_service);
- if (found_service != local_services_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- its_client = found_instance->second;
- }
- }
- return (find_local(its_client));
+ instance_t _instance) {
+ client_t its_client(0);
+ auto found_service = local_services_.find(_service);
+ if (found_service != local_services_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ its_client = found_instance->second;
+ }
+ }
+ return (find_local(its_client));
}
void routing_manager_proxy::send_pong() const {
- byte_t its_pong[] = {
- VSOMEIP_PONG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+ byte_t its_pong[] = {
+ VSOMEIP_PONG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+
+ std::memcpy(&its_pong[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_t));
- std::memcpy(&its_pong[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_t));
+ if (is_connected_)
+ sender_->send(its_pong, sizeof(its_pong));
+}
- if (is_connected_)
- sender_->send(its_pong, sizeof(its_pong));
+void routing_manager_proxy::send_request_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl, bool _is_selective) {
+
+ byte_t its_command[VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REQUEST_SERVICE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
+ sizeof(_minor));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_ttl,
+ sizeof(_ttl));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 13], &_is_selective,
+ sizeof(_is_selective));
+
+ if (is_connected_) {
+ sender_->send(its_command, sizeof(its_command));
+ } else {
+ service_data_t offer = { _service, _instance, _major, _minor, _ttl };
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ pending_requests_.insert(offer);
+ }
}
} // namespace vsomeip
diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp
index 839c8e7..1c3a53c 100644
--- a/implementation/routing/src/routing_manager_stub.cpp
+++ b/implementation/routing/src/routing_manager_stub.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -33,15 +32,26 @@ routing_manager_stub::~routing_manager_stub() {
void routing_manager_stub::init() {
std::stringstream its_endpoint_path;
- its_endpoint_path << BASE_PATH << VSOMEIP_ROUTING_CLIENT;
+ its_endpoint_path << VSOMEIP_BASE_PATH << VSOMEIP_ROUTING_CLIENT;
endpoint_path_ = its_endpoint_path.str();
+#if WIN32
+ ::_unlink(endpoint_path_.c_str());
+ int port = 51234;
+ VSOMEIP_DEBUG << "Routing endpoint at " << port;
+#else
::unlink(endpoint_path_.c_str());
-
VSOMEIP_DEBUG << "Routing endpoint at " << endpoint_path_;
+#endif
+
endpoint_ =
std::make_shared < local_server_endpoint_impl
- > (shared_from_this(), boost::asio::local::stream_protocol::endpoint(
- endpoint_path_), io_);
+ > (shared_from_this(),
+ #ifdef WIN32
+ boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port),
+ #else
+ boost::asio::local::stream_protocol::endpoint(endpoint_path_),
+ #endif
+ io_);
}
void routing_manager_stub::start() {
@@ -54,8 +64,11 @@ void routing_manager_stub::start() {
void routing_manager_stub::stop() {
watchdog_timer_.cancel();
endpoint_->stop();
-
+#ifdef WIN32
+ ::_unlink(endpoint_path_.c_str());
+#else
::unlink(endpoint_path_.c_str());
+#endif
}
void routing_manager_stub::on_connect(std::shared_ptr<endpoint> _endpoint) {
@@ -79,12 +92,12 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) {
byte_t its_command;
client_t its_client;
- session_t its_session;
+ //session_t its_session;
std::string its_client_endpoint;
service_t its_service;
instance_t its_instance;
eventgroup_t its_eventgroup;
- event_t its_event;
+ //event_t its_event;
major_version_t its_major;
minor_version_t its_minor;
ttl_t its_ttl;
@@ -180,11 +193,29 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
its_service = VSOMEIP_BYTES_TO_WORD(
its_data[VSOMEIP_SERVICE_POS_MIN],
its_data[VSOMEIP_SERVICE_POS_MAX]);
- its_flush = static_cast<bool>(_data[_size - 2]);
- its_reliable = static_cast<bool>(_data[_size - 1]);
std::memcpy(&its_instance, &_data[_size - 4], sizeof(its_instance));
- host_->on_message(its_service, its_instance, its_data, its_size);
+ std::memcpy(&its_reliable, &_data[_size - 1], sizeof(its_reliable));
+ host_->on_message(its_service, its_instance, its_data, its_size, its_reliable);
break;
+
+ case VSOMEIP_REQUEST_SERVICE:
+ bool its_selective;
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_major));
+ std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
+ sizeof(its_minor));
+ std::memcpy(&its_ttl, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
+ sizeof(its_ttl));
+ std::memcpy(&its_selective, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 13],
+ sizeof(its_selective));
+ host_->request_service(its_client, its_service, its_instance,
+ its_major, its_minor, its_ttl, its_selective);
+ break;
}
}
}
@@ -198,16 +229,20 @@ void routing_manager_stub::on_register_application(client_t _client) {
}
void routing_manager_stub::on_deregister_application(client_t _client) {
- std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
+ routing_info_mutex_.lock();
auto its_info = routing_info_.find(_client);
if (its_info != routing_info_.end()) {
for (auto &its_service : its_info->second.second) {
for (auto &its_instance : its_service.second) {
+ routing_info_mutex_.unlock();
host_->on_stop_offer_service(its_service.first, its_instance);
+ routing_info_mutex_.lock();
}
}
}
+ routing_info_mutex_.unlock();
+ std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
host_->remove_local(_client);
routing_info_.erase(_client);
broadcast_routing_info();
@@ -337,8 +372,7 @@ void routing_manager_stub::on_pong(client_t _client) {
if (found_info != routing_info_.end()) {
found_info->second.first = 0;
} else {
- std::cerr << "Received PONG from unregistered application!"
- << std::endl;
+ VSOMEIP_ERROR << "Received PONG from unregistered application!";
}
}
@@ -367,20 +401,21 @@ void routing_manager_stub::check_watchdog() {
std::function<void(boost::system::error_code const &)> its_callback =
[this](boost::system::error_code const &_error) {
std::list< client_t > lost;
-
- for (auto i : routing_info_) {
- if (i.first > 0 && i.first != host_->get_client()) {
- if (i.second.first > VSOMEIP_DEFAULT_MAX_MISSING_PONGS) { // TODO: use config variable
- VSOMEIP_WARNING << "Lost contact to application " << std::hex << (int)i.first;
- lost.push_back(i.first);
+ {
+ std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
+ for (auto i : routing_info_) {
+ if (i.first > 0 && i.first != host_->get_client()) {
+ if (i.second.first > VSOMEIP_DEFAULT_MAX_MISSING_PONGS) { // TODO: use config variable
+ VSOMEIP_WARNING << "Lost contact to application " << std::hex << (int)i.first;
+ lost.push_back(i.first);
+ }
}
}
- }
- for (auto i : lost) {
- routing_info_.erase(i);
+ for (auto i : lost) {
+ routing_info_.erase(i);
+ }
}
-
if (0 < lost.size())
send_application_lost(lost);
diff --git a/implementation/routing/src/servicegroup.cpp b/implementation/routing/src/servicegroup.cpp
index 8818c1b..ce4739e 100644
--- a/implementation/routing/src/servicegroup.cpp
+++ b/implementation/routing/src/servicegroup.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,8 +8,8 @@
namespace vsomeip {
-servicegroup::servicegroup(const std::string &_name)
- : name_(_name) {
+servicegroup::servicegroup(const std::string &_name, bool _is_local)
+ : name_(_name), is_local_(_is_local) {
}
servicegroup::~servicegroup() {
@@ -20,6 +19,10 @@ std::string servicegroup::get_name() const {
return name_;
}
+bool servicegroup::is_local() const {
+ return is_local_;
+}
+
bool servicegroup::add_service(
service_t _service, instance_t _instance,
std::shared_ptr< serviceinfo > _info) {
diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp
index 5fa932a..60704ad 100644
--- a/implementation/routing/src/serviceinfo.cpp
+++ b/implementation/routing/src/serviceinfo.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp
index dc144d6..3b37df0 100644
--- a/implementation/runtime/include/application_impl.hpp
+++ b/implementation/runtime/include/application_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,11 +6,19 @@
#ifndef VSOMEIP_APPLICATION_IMPL_HPP
#define VSOMEIP_APPLICATION_IMPL_HPP
+#include <atomic>
+#include <condition_variable>
+#include <deque>
#include <map>
+#include <mutex>
+#include <set>
#include <string>
+#include <thread>
+#include <vector>
#include <boost/asio/signal_set.hpp>
+#include <vsomeip/export.hpp>
#include <vsomeip/application.hpp>
#include "../../routing/include/routing_manager_host.hpp"
@@ -24,100 +31,144 @@ class routing_manager;
class routing_manager_stub;
class application_impl: public application,
- public routing_manager_host,
- public std::enable_shared_from_this<application_impl> {
+ public routing_manager_host,
+ public std::enable_shared_from_this<application_impl> {
public:
- application_impl(const std::string &_name);
- ~application_impl();
+ VSOMEIP_EXPORT application_impl(const std::string &_name);
+ VSOMEIP_EXPORT ~application_impl();
- bool init();
- void start();
- void stop();
+ VSOMEIP_EXPORT bool init();
+ VSOMEIP_EXPORT void start();
+ VSOMEIP_EXPORT void stop();
- void offer_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl);
+ VSOMEIP_EXPORT void offer_service(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl);
- void stop_offer_service(service_t _service, instance_t _instance);
+ VSOMEIP_EXPORT void stop_offer_service(service_t _service,
+ instance_t _instance);
- // Consume services
- void request_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl);
- void release_service(service_t _service, instance_t _instance);
+ // Consume services
+ VSOMEIP_EXPORT void request_service(service_t _service,
+ instance_t _instance, bool _has_selective, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl);
+ VSOMEIP_EXPORT void release_service(service_t _service,
+ instance_t _instance);
- void subscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
+ VSOMEIP_EXPORT void subscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
- void unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup);
+ VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup);
- bool is_available(service_t _service, instance_t _instance);
+ VSOMEIP_EXPORT bool is_available(service_t _service, instance_t _instance);
- void send(std::shared_ptr<message> _message, bool _flush, bool _reliable);
+ VSOMEIP_EXPORT void send(std::shared_ptr<message> _message, bool _flush);
- void notify(service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload) const;
+ VSOMEIP_EXPORT void notify(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload) const;
- void register_event_handler(event_handler_t _handler);
- void unregister_event_handler();
+ VSOMEIP_EXPORT void notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload, client_t _client) const;
- void register_message_handler(service_t _service, instance_t _instance,
- method_t _method, message_handler_t _handler);
- void unregister_message_handler(service_t _service, instance_t _instance,
- method_t _method);
+ VSOMEIP_EXPORT void register_event_handler(event_handler_t _handler);
+ VSOMEIP_EXPORT void unregister_event_handler();
- void register_availability_handler(service_t _service, instance_t _instance,
- availability_handler_t _handler);
- void unregister_availability_handler(service_t _service,
- instance_t _instance);
+ VSOMEIP_EXPORT void register_message_handler(service_t _service,
+ instance_t _instance, method_t _method, message_handler_t _handler);
+ VSOMEIP_EXPORT void unregister_message_handler(service_t _service,
+ instance_t _instance, method_t _method);
- // routing_manager_host
- const std::string & get_name() const;
- client_t get_client() const;
- std::shared_ptr<configuration> get_configuration() const;
- boost::asio::io_service & get_io();
+ VSOMEIP_EXPORT void register_availability_handler(service_t _service,
+ instance_t _instance, availability_handler_t _handler);
+ VSOMEIP_EXPORT void unregister_availability_handler(service_t _service,
+ instance_t _instance);
- void on_event(event_type_e _event);
- void on_availability(service_t _service, instance_t _instance,
- bool _is_available) const;
- void on_message(std::shared_ptr<message> _message);
- void on_error(error_code_e _error);
+ VSOMEIP_EXPORT void register_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup, subscription_handler_t _handler);
+ VSOMEIP_EXPORT void unregister_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup);
- // service_discovery_host
- routing_manager * get_routing_manager() const;
+ // routing_manager_host
+ VSOMEIP_EXPORT const std::string & get_name() const;
+ VSOMEIP_EXPORT client_t get_client() const;
+ VSOMEIP_EXPORT std::shared_ptr<configuration> get_configuration() const;
+ VSOMEIP_EXPORT boost::asio::io_service & get_io();
+
+ VSOMEIP_EXPORT void on_event(event_type_e _event);
+ VSOMEIP_EXPORT void on_availability(service_t _service,
+ instance_t _instance,
+ bool _is_available) const;
+ VSOMEIP_EXPORT void on_message(std::shared_ptr<message> _message);
+ VSOMEIP_EXPORT void on_error(error_code_e _error);
+ VSOMEIP_EXPORT bool on_subscription(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, client_t _client, bool _subscribed);
+
+ // service_discovery_host
+ VSOMEIP_EXPORT routing_manager * get_routing_manager() const;
private:
- void service();
- inline void update_session() {
- session_++;
- if (0 == session_) {
- session_++;
- }
- }
+ void service();
+ inline void update_session() {
+ session_++;
+ if (0 == session_) {
+ session_++;
+ }
+ }
+
+ void dispatch();
private:
- client_t client_; // unique application identifier
- session_t session_;
+ client_t client_; // unique application identifier
+ session_t session_;
+
+ std::mutex initialize_mutex_;
+ bool is_initialized_;
+
+ std::string name_;
+ std::shared_ptr<configuration> configuration_;
+
+ boost::asio::io_service io_;
+
+ // Proxy to or the Routing Manager itself
+ std::shared_ptr<routing_manager> routing_;
+
+ // (Non-SOME/IP) Event handler
+ event_handler_t handler_;
+
+ // Method/Event (=Member) handlers
+ std::map<service_t,
+ std::map<instance_t, std::map<method_t, message_handler_t> > > members_;
+ mutable std::mutex members_mutex_;
+
+ // Availability handlers
+ std::map<service_t, std::map<instance_t, availability_handler_t> > availability_;
+ mutable std::mutex availability_mutex_;
- std::string name_;
- std::shared_ptr<configuration> configuration_;
+ // Availability
+ mutable std::map<service_t, std::set<instance_t>> available_;
- boost::asio::io_service io_;
+ // Subscriptopn handlers
+ std::map<service_t, std::map<instance_t, std::map<eventgroup_t, subscription_handler_t>>>
+ subscription_;
+ mutable std::mutex subscription_mutex_;
- // Proxy to or the Routing Manager itself
- std::shared_ptr<routing_manager> routing_;
+ // Signals
+ boost::asio::signal_set signals_;
- // (Non-SOME/IP) Event handler
- event_handler_t handler_;
+ // Thread pool for dispatch handlers
+ std::size_t num_dispatchers_;
+ std::vector<std::thread> dispatchers_;
+ std::atomic_bool is_dispatching_;
- // Method/Event (=Member) handlers
- std::map<service_t,
- std::map<instance_t, std::map<method_t, message_handler_t> > > members_;
+ // Handlers
+ mutable std::deque<std::function<void()>> handlers_;
- // Availability handlers
- std::map<service_t, std::map<instance_t, availability_handler_t> > availability_;
+ // Condition to wake up
+ mutable std::mutex dispatch_mutex_;
+ mutable std::condition_variable dispatch_condition_;
- // Signals
- boost::asio::signal_set signals_;
+ // Workaround for destruction problem
+ std::shared_ptr<logger> logger_;
};
} // namespace vsomeip
diff --git a/implementation/runtime/include/runtime_impl.hpp b/implementation/runtime/include/runtime_impl.hpp
index 2040ffb..6240969 100644
--- a/implementation/runtime/include/runtime_impl.hpp
+++ b/implementation/runtime/include/runtime_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,24 +12,24 @@ namespace vsomeip {
class runtime_impl: public runtime {
public:
- static runtime * get();
+ static std::shared_ptr<runtime> get();
- virtual ~runtime_impl();
+ virtual ~runtime_impl();
- std::shared_ptr<application> create_application(
- const std::string &_name) const;
+ std::shared_ptr<application> create_application(
+ const std::string &_name) const;
- std::shared_ptr<message> create_message() const;
- std::shared_ptr<message> create_request() const;
- std::shared_ptr<message> create_response(
- const std::shared_ptr<message> &_request) const;
- std::shared_ptr<message> create_notification() const;
+ std::shared_ptr<message> create_message(bool _reliable) const;
+ std::shared_ptr<message> create_request(bool _reliable) const;
+ std::shared_ptr<message> create_response(
+ const std::shared_ptr<message> &_request) const;
+ std::shared_ptr<message> create_notification(bool _reliable) const;
- std::shared_ptr<payload> create_payload() const;
- std::shared_ptr<payload> create_payload(
- const byte_t *_data, uint32_t _size) const;
- std::shared_ptr<payload> create_payload(
- const std::vector<byte_t> &_data) const;
+ std::shared_ptr<payload> create_payload() const;
+ std::shared_ptr<payload> create_payload(const byte_t *_data,
+ uint32_t _size) const;
+ std::shared_ptr<payload> create_payload(
+ const std::vector<byte_t> &_data) const;
};
} // namespace vsomeip
diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp
index 514f286..77eef78 100644
--- a/implementation/runtime/src/application_impl.cpp
+++ b/implementation/runtime/src/application_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -20,284 +19,459 @@
namespace vsomeip {
-application_impl::application_impl(const std::string &_name) :
- name_(_name), routing_(0), signals_(io_, SIGINT, SIGTERM) {
+application_impl::application_impl(const std::string &_name)
+ : name_(_name), is_initialized_(false), routing_(0), signals_(io_,
+ SIGINT, SIGTERM), num_dispatchers_(0), logger_(logger::get()) {
}
application_impl::~application_impl() {
+#ifdef WIN32
+ // killemall
+ exit(0);
+#endif
}
bool application_impl::init() {
- bool is_initialized(false);
-
- // Application name
- if (name_ == "") {
- const char *its_name = getenv(VSOMEIP_ENV_APPLICATION_NAME);
- if (nullptr != its_name) {
- name_ = its_name;
- } else {
- VSOMEIP_ERROR << "Missing application name. "
- "Please set environment variable VSOMEIP_APPLICATION_NAME.";
- return false;
- }
- }
-
- // Set default path
- std::string its_path(VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH);
-
- // Override with path from environment
- const char *its_env_path = getenv(VSOMEIP_ENV_CONFIGURATION_FILE_PATH);
- if (nullptr != its_env_path && utility::exists(its_env_path))
- its_path = its_env_path;
-
- // Override with local path
- std::string its_local_path(VSOMEIP_LOCAL_CONFIGURATION_FILE_PATH);
- if (utility::exists(its_local_path))
- its_path = its_local_path;
-
- configuration_.reset(configuration::get(its_path));
- VSOMEIP_INFO << "Using configuration file: " << its_path;
-
- if (configuration_) {
- client_ = configuration_->get_id(name_);
-
- // Routing
- if (name_ == configuration_->get_routing_host()) {
- routing_ = std::make_shared < routing_manager_impl > (this);
- } else {
- routing_ = std::make_shared < routing_manager_proxy > (this);
- }
-
- routing_->init();
-
- // Smallest allowed session identifier
- session_ = 0x0001;
-
- VSOMEIP_DEBUG << "Application(" << name_ << ", " << std::hex << client_
- << ") is initialized.";
-
- is_initialized = true;
- }
-
- // Register signal handler
- std::function<void(boost::system::error_code const &, int)> its_signal_handler =
- [this] (boost::system::error_code const &_error, int _signal) {
- if (!_error) {
- switch (_signal) {
- case SIGTERM:
- case SIGINT:
- stop();
- exit(0);
- break;
- default:
- break;
- }
- }
- };
- signals_.async_wait(its_signal_handler);
-
- return is_initialized;
+ bool is_initialized(false);
+
+ // Application name
+ if (name_ == "") {
+ const char *its_name = getenv(VSOMEIP_ENV_APPLICATION_NAME);
+ if (nullptr != its_name) {
+ name_ = its_name;
+ } else {
+ VSOMEIP_ERROR<< "Missing application name. "
+ "Please set environment variable VSOMEIP_APPLICATION_NAME.";
+ return false;
+ }
+ }
+
+ // Set default path
+ std::string its_path(VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH);
+
+ // Override with path from environment
+ const char *its_env_path = getenv(VSOMEIP_ENV_CONFIGURATION_FILE_PATH);
+ if (nullptr != its_env_path && utility::exists(its_env_path))
+ its_path = its_env_path;
+
+ // Override with local path
+ std::string its_local_path(VSOMEIP_LOCAL_CONFIGURATION_FILE_PATH);
+ if (utility::exists(its_local_path))
+ its_path = its_local_path;
+
+ configuration_.reset(configuration::get(its_path));
+ VSOMEIP_INFO<< "Using configuration file: " << its_path;
+
+ if (configuration_) {
+ client_ = configuration_->get_id(name_);
+
+ // Routing
+ if (name_ == configuration_->get_routing_host()) {
+ routing_ = std::make_shared<routing_manager_impl>(this);
+ } else {
+ routing_ = std::make_shared<routing_manager_proxy>(this);
+ }
+
+ routing_->init();
+
+ num_dispatchers_ = configuration_->get_num_dispatchers(name_);
+
+ // Smallest allowed session identifier
+ session_ = 0x0001;
+
+ VSOMEIP_DEBUG<< "Application(" << name_ << ", "
+ << std::hex << client_ << ") is initialized (uses "
+ << std::dec << num_dispatchers_ << " dispatcher threads).";
+
+ is_initialized_ = true;
+ }
+
+ if (is_initialized_) {
+ // Register signal handler
+ std::function<void(boost::system::error_code const &, int)> its_signal_handler =
+ [this] (boost::system::error_code const &_error, int _signal) {
+ if (!_error) {
+ switch (_signal) {
+ case SIGTERM:
+ case SIGINT:
+ stop();
+ exit(0);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+ signals_.async_wait(its_signal_handler);
+ }
+
+ return is_initialized_;
}
void application_impl::start() {
- if (routing_)
- routing_->start();
+ is_dispatching_ = true;
- io_.run();
+ for (size_t i = 0; i < num_dispatchers_; i++)
+ dispatchers_.push_back(
+ std::thread(std::bind(&application_impl::dispatch, this)));
+
+ if (routing_)
+ routing_->start();
+
+ io_.run();
}
void application_impl::stop() {
- if (routing_)
- routing_->stop();
+ is_dispatching_ = false;
+ dispatch_condition_.notify_all();
+ for (auto &t : dispatchers_)
+ t.join();
- io_.stop();
+ if (routing_)
+ routing_->stop();
+
+ io_.stop();
}
void application_impl::offer_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl) {
- if (routing_)
- routing_->offer_service(client_, _service, _instance, _major, _minor,
- _ttl);
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl) {
+ if (routing_)
+ routing_->offer_service(client_, _service, _instance, _major, _minor,
+ _ttl);
}
void application_impl::stop_offer_service(service_t _service,
- instance_t _instance) {
- if (routing_)
- routing_->stop_offer_service(client_, _service, _instance);
+ instance_t _instance) {
+ if (routing_)
+ routing_->stop_offer_service(client_, _service, _instance);
}
void application_impl::request_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl) {
- if (routing_)
- routing_->request_service(client_, _service, _instance, _major, _minor,
- _ttl);
+ bool _has_selective, major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl) {
+ if (routing_)
+ routing_->request_service(client_, _service, _instance, _major, _minor,
+ _ttl, _has_selective);
}
void application_impl::release_service(service_t _service,
- instance_t _instance) {
- if (routing_)
- routing_->release_service(client_, _service, _instance);
+ instance_t _instance) {
+ if (routing_)
+ routing_->release_service(client_, _service, _instance);
}
void application_impl::subscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl) {
- if (routing_)
- routing_->subscribe(client_, _service, _instance, _eventgroup, _major,
- _ttl);
+ eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl) {
+ if (routing_)
+ routing_->subscribe(client_, _service, _instance, _eventgroup, _major,
+ _ttl);
}
void application_impl::unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup) {
- if (routing_)
- routing_->unsubscribe(client_, _service, _instance, _eventgroup);
+ eventgroup_t _eventgroup) {
+ if (routing_)
+ routing_->unsubscribe(client_, _service, _instance, _eventgroup);
}
bool application_impl::is_available(service_t _service, instance_t _instance) {
- return routing_ && routing_->is_available(_service, _instance);
+ auto found_available = available_.find(_service);
+ if (found_available == available_.end())
+ return false;
+
+ return (found_available->second.find(_instance)
+ != found_available->second.end());
}
-void application_impl::send(std::shared_ptr<message> _message, bool _flush,
- bool _reliable) {
- if (routing_) {
- // in case of requests set the request-id (client-id|session-id)
- bool is_request = utility::is_request(_message);
- if (is_request) {
- _message->set_client(client_);
- _message->set_session(session_);
- }
- // in case of successful sending, increment the session-id
- if (routing_->send(client_, _message, _flush, _reliable)) {
- if (is_request) {
- update_session();
- }
- }
- }
+void application_impl::send(std::shared_ptr<message> _message, bool _flush) {
+ if (routing_) {
+ // in case of requests set the request-id (client-id|session-id)
+ bool is_request = utility::is_request(_message);
+ if (is_request) {
+ _message->set_client(client_);
+ _message->set_session(session_);
+ }
+ // in case of successful sending, increment the session-id
+ if (routing_->send(client_, _message, _flush)) {
+ if (is_request) {
+ update_session();
+ }
+ }
+ }
}
-void application_impl::notify(service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload) const {
- if (routing_)
- routing_->notify(_service, _instance, _event, _payload);
+void application_impl::notify(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload) const {
+ if (routing_)
+ routing_->notify(_service, _instance, _event, _payload);
+}
+
+void application_impl::notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload,
+ client_t _client) const {
+
+ if (routing_) {
+ routing_->notify_one(_service, _instance, _event, _payload, _client);
+ }
}
void application_impl::register_event_handler(event_handler_t _handler) {
- handler_ = _handler;
+ handler_ = _handler;
}
void application_impl::unregister_event_handler() {
- handler_ = nullptr;
+ handler_ = nullptr;
}
void application_impl::register_availability_handler(service_t _service,
- instance_t _instance, availability_handler_t _handler) {
- availability_[_service][_instance] = _handler;
+ instance_t _instance, availability_handler_t _handler) {
+ std::unique_lock<std::mutex> its_lock(availability_mutex_);
+ availability_[_service][_instance] = _handler;
}
void application_impl::unregister_availability_handler(service_t _service,
- instance_t _instance) {
- 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()) {
- found_service->second.erase(_instance);
- }
- }
+ instance_t _instance) {
+ std::unique_lock<std::mutex> its_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()) {
+ found_service->second.erase(_instance);
+ }
+ }
+}
+
+bool application_impl::on_subscription(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, client_t _client, bool _subscribed) {
+
+ std::unique_lock<std::mutex> its_lock(subscription_mutex_);
+ auto found_service = subscription_.find(_service);
+ if (found_service != subscription_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ return found_eventgroup->second(_client, _subscribed);
+ }
+ }
+ }
+ return true;
+}
+
+void application_impl::register_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ subscription_handler_t _handler) {
+
+ std::unique_lock<std::mutex> its_lock(subscription_mutex_);
+ subscription_[_service][_instance][_eventgroup] = _handler;
+}
+
+void application_impl::unregister_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) {
+
+ std::unique_lock<std::mutex> its_lock(subscription_mutex_);
+ auto found_service = subscription_.find(_service);
+ if (found_service != subscription_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ found_instance->second.erase(_eventgroup);
+ }
+ }
+ }
}
void application_impl::register_message_handler(service_t _service,
- instance_t _instance, method_t _method, message_handler_t _handler) {
- members_[_service][_instance][_method] = _handler;
+ instance_t _instance, method_t _method, message_handler_t _handler) {
+ std::unique_lock<std::mutex> its_lock(members_mutex_);
+ members_[_service][_instance][_method] = _handler;
}
void application_impl::unregister_message_handler(service_t _service,
- instance_t _instance, method_t _method) {
- 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);
- }
- }
- }
+ instance_t _instance, method_t _method) {
+ std::unique_lock<std::mutex> 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);
+ }
+ }
+ }
}
// Interface "routing_manager_host"
const std::string & application_impl::get_name() const {
- return name_;
+ return name_;
}
client_t application_impl::get_client() const {
- return client_;
+ return client_;
}
std::shared_ptr<configuration> application_impl::get_configuration() const {
- return configuration_;
+ return configuration_;
}
boost::asio::io_service & application_impl::get_io() {
- return io_;
+ return io_;
}
void application_impl::on_event(event_type_e _event) {
- if (handler_)
- handler_(_event);
+ if (handler_) {
+ if (num_dispatchers_ > 0) {
+ std::unique_lock<std::mutex> its_lock(dispatch_mutex_);
+ handlers_.push_back([this, _event]() {
+ handler_(_event);
+ });
+ dispatch_condition_.notify_one();
+ } else {
+ handler_(_event);
+ }
+ }
}
void application_impl::on_availability(service_t _service, instance_t _instance,
- bool _is_available) const {
- 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()) {
- found_instance->second(_service, _instance, _is_available);
- }
- }
+ bool _is_available) const {
+
+ std::map<instance_t, availability_handler_t>::const_iterator found_instance;
+ availability_handler_t its_handler;
+ std::map<instance_t, availability_handler_t>::const_iterator found_wildcard_instance;
+ availability_handler_t its_wildcard_handler;
+ bool has_handler(false);
+ bool has_wildcard_handler(false);
+
+ {
+ std::unique_lock<std::mutex> its_lock(availability_mutex_);
+
+ if (_is_available) {
+ available_[_service].insert(_instance);
+ } else {
+ auto found_available_service = available_.find(_service);
+ if (found_available_service != available_.end())
+ found_available_service->second.erase(_instance);
+ }
+
+ auto found_service = availability_.find(_service);
+ if (found_service != availability_.end()) {
+ found_instance = found_service->second.find(_instance);
+ has_handler = (found_instance != found_service->second.end());
+ if (has_handler)
+ its_handler = found_instance->second;
+ found_wildcard_instance = found_service->second.find(ANY_INSTANCE);
+ has_wildcard_handler = (found_wildcard_instance != found_service->second.end());
+ if (has_wildcard_handler)
+ its_wildcard_handler = found_wildcard_instance->second;
+ }
+ }
+
+ if (num_dispatchers_ > 0) {
+ if (has_handler) {
+ std::unique_lock<std::mutex> its_lock(dispatch_mutex_);
+ handlers_.push_back(
+ [its_handler, _service, _instance, _is_available]() {
+ its_handler(_service, _instance, _is_available);
+ });
+ dispatch_condition_.notify_one();
+ }
+ if (has_wildcard_handler) {
+ std::unique_lock < std::mutex > its_lock(dispatch_mutex_);
+ handlers_.push_back(
+ [its_wildcard_handler, _service, _instance, _is_available]() {
+ its_wildcard_handler(_service, _instance, _is_available);
+ });
+ dispatch_condition_.notify_one();
+ }
+ } else {
+ if(has_handler) {
+ its_handler(_service, _instance, _is_available);
+ }
+ if(has_wildcard_handler) {
+ its_wildcard_handler(_service, _instance, _is_available);
+ }
+ }
}
void application_impl::on_message(std::shared_ptr<message> _message) {
- service_t its_service = _message->get_service();
- instance_t its_instance = _message->get_instance();
- method_t its_method = _message->get_method();
-
- // find list of handlers
- auto found_service = members_.find(its_service);
- if (found_service == members_.end()) {
- found_service = members_.find(ANY_SERVICE);
- }
- if (found_service != members_.end()) {
- auto found_instance = found_service->second.find(its_instance);
- if (found_instance == found_service->second.end()) {
- found_instance = found_service->second.find(ANY_INSTANCE);
- }
- if (found_instance != found_service->second.end()) {
- auto found_method = found_instance->second.find(its_method);
- if (found_method == found_instance->second.end()) {
- found_method = found_instance->second.find(ANY_METHOD);
- }
-
- if (found_method != found_instance->second.end()) {
- found_method->second(_message);
- }
- }
- }
+ service_t its_service = _message->get_service();
+ instance_t its_instance = _message->get_instance();
+ method_t its_method = _message->get_method();
+
+ std::map<method_t, message_handler_t>::iterator found_method;
+ message_handler_t its_handler;
+ bool has_handler(false);
+
+ {
+ std::unique_lock<std::mutex> its_lock(members_mutex_);
+
+ auto found_service = members_.find(its_service);
+ if (found_service == members_.end()) {
+ found_service = members_.find(ANY_SERVICE);
+ }
+ if (found_service != members_.end()) {
+ auto found_instance = found_service->second.find(its_instance);
+ if (found_instance == found_service->second.end()) {
+ found_instance = found_service->second.find(ANY_INSTANCE);
+ }
+ if (found_instance != found_service->second.end()) {
+ auto found_method = found_instance->second.find(its_method);
+ if (found_method == found_instance->second.end()) {
+ found_method = found_instance->second.find(ANY_METHOD);
+ }
+
+ if (found_method != found_instance->second.end()) {
+ its_handler = found_method->second;
+ has_handler = true;
+ }
+ }
+ }
+ }
+
+ if (has_handler) {
+ if (num_dispatchers_ > 0) {
+ std::unique_lock<std::mutex> its_lock(dispatch_mutex_);
+ handlers_.push_back([its_handler, _message]() {
+ its_handler(_message);
+ });
+ dispatch_condition_.notify_one();
+ } else {
+ its_handler(_message);
+ }
+ }
}
void application_impl::on_error(error_code_e _error) {
- VSOMEIP_ERROR << ERROR_INFO[static_cast<int>(_error)]
- << " (" << static_cast<int>(_error) << ")";
+ VSOMEIP_ERROR<< ERROR_INFO[static_cast<int>(_error)] << " ("
+ << static_cast<int>(_error) << ")";
}
// Interface "service_discovery_host"
routing_manager * application_impl::get_routing_manager() const {
- return routing_.get();
+ return routing_.get();
}
// Internal
void application_impl::service() {
- io_.run();
- std::cout << "Behind io.run()" << std::endl;
+ io_.run();
+}
+
+void application_impl::dispatch() {
+ std::function<void()> handler;
+ while (is_dispatching_) {
+ {
+ std::unique_lock<std::mutex> its_lock(dispatch_mutex_);
+ if (handlers_.empty()) {
+ dispatch_condition_.wait(its_lock);
+ continue;
+ } else {
+ handler = handlers_.front();
+ handlers_.pop_front();
+ }
+ }
+ handler();
+ }
}
} // namespace vsomeip
diff --git a/implementation/runtime/src/error.cpp b/implementation/runtime/src/error.cpp
index 19f54f5..e921227 100644
--- a/implementation/runtime/src/error.cpp
+++ b/implementation/runtime/src/error.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2015 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2015 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,15 +7,8 @@
namespace vsomeip {
-const char *ERROR_INFO[] = {
- "Missing vsomeip configuration",
- "Missing port configuration",
- "Client endpoint creation failed"
- "Server endpoint creation failed",
- "Service property mismatch"
-};
+const char *ERROR_INFO[] = { "Missing vsomeip configuration",
+ "Missing port configuration", "Client endpoint creation failed",
+ "Server endpoint creation failed", "Service property mismatch" };
} // namespace vsomeip
-
-
-
diff --git a/implementation/runtime/src/runtime.cpp b/implementation/runtime/src/runtime.cpp
index 33e62e2..68f6154 100644
--- a/implementation/runtime/src/runtime.cpp
+++ b/implementation/runtime/src/runtime.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -10,11 +9,8 @@
namespace vsomeip {
-runtime * runtime::get() {
- return runtime_impl::get();
+std::shared_ptr<runtime> runtime::get() {
+ return runtime_impl::get();
}
} // namespace vsomeip
-
-
-
diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp
index 7c8491a..896ed15 100644
--- a/implementation/runtime/src/runtime_impl.cpp
+++ b/implementation/runtime/src/runtime_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,72 +12,78 @@
namespace vsomeip {
-runtime * runtime_impl::get() {
- static runtime_impl the_runtime;
- return (&the_runtime);
+std::shared_ptr<runtime> runtime_impl::get() {
+ static std::shared_ptr<runtime> the_runtime =
+ std::make_shared<runtime_impl>();
+ return the_runtime;
}
runtime_impl::~runtime_impl() {
}
std::shared_ptr<application> runtime_impl::create_application(
- const std::string &_name) const {
- return (std::make_shared < application_impl > (_name));
+ const std::string &_name) const {
+ return (std::make_shared<application_impl>(_name));
}
-std::shared_ptr<message> runtime_impl::create_message() const {
- std::shared_ptr<message_impl> its_message =
- std::make_shared<message_impl>();
- its_message->set_protocol_version(VSOMEIP_PROTOCOL_VERSION);
- its_message->set_return_code(return_code_e::E_OK);
- return (its_message);
+std::shared_ptr<message> runtime_impl::create_message(bool _reliable) const {
+ std::shared_ptr<message_impl> its_message =
+ std::make_shared<message_impl>();
+ its_message->set_protocol_version(VSOMEIP_PROTOCOL_VERSION);
+ its_message->set_return_code(return_code_e::E_OK);
+ its_message->set_reliable(_reliable);
+ return (its_message);
}
-std::shared_ptr<message> runtime_impl::create_request() const {
- std::shared_ptr<message_impl> its_request =
- std::make_shared<message_impl>();
- its_request->set_protocol_version(VSOMEIP_PROTOCOL_VERSION);
- its_request->set_message_type(message_type_e::REQUEST);
- its_request->set_return_code(return_code_e::E_OK);
- return (its_request);
+std::shared_ptr<message> runtime_impl::create_request(bool _reliable) const {
+ std::shared_ptr<message_impl> its_request =
+ std::make_shared<message_impl>();
+ 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);
+ its_request->set_reliable(_reliable);
+ return (its_request);
}
std::shared_ptr<message> runtime_impl::create_response(
- const std::shared_ptr<message> &_request) const {
- std::shared_ptr<message_impl> its_response =
- std::make_shared<message_impl>();
- its_response->set_service(_request->get_service());
- its_response->set_instance(_request->get_instance());
- its_response->set_method(_request->get_method());
- its_response->set_client(_request->get_client());
- its_response->set_session(_request->get_session());
- its_response->set_interface_version(_request->get_interface_version());
- its_response->set_message_type(message_type_e::RESPONSE);
- its_response->set_return_code(return_code_e::E_OK);
- return (its_response);
+ const std::shared_ptr<message> &_request) const {
+ std::shared_ptr<message_impl> its_response =
+ std::make_shared<message_impl>();
+ its_response->set_service(_request->get_service());
+ its_response->set_instance(_request->get_instance());
+ its_response->set_method(_request->get_method());
+ its_response->set_client(_request->get_client());
+ its_response->set_session(_request->get_session());
+ its_response->set_interface_version(_request->get_interface_version());
+ its_response->set_message_type(message_type_e::MT_RESPONSE);
+ its_response->set_return_code(return_code_e::E_OK);
+ its_response->set_reliable(_request->is_reliable());
+ return (its_response);
}
-std::shared_ptr<message> runtime_impl::create_notification() const {
- std::shared_ptr<message_impl> its_notification =
- std::make_shared<message_impl>();
- its_notification->set_protocol_version(VSOMEIP_PROTOCOL_VERSION);
- its_notification->set_message_type(message_type_e::NOTIFICATION);
- its_notification->set_return_code(return_code_e::E_OK);
- return (its_notification);
+std::shared_ptr<message> runtime_impl::create_notification(
+ bool _reliable) const {
+ std::shared_ptr<message_impl> its_notification = std::make_shared<
+ message_impl>();
+ 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);
+ its_notification->set_reliable(_reliable);
+ return (its_notification);
}
std::shared_ptr<payload> runtime_impl::create_payload() const {
- return (std::make_shared<payload_impl>());
+ return (std::make_shared<payload_impl>());
}
-std::shared_ptr<payload> runtime_impl::create_payload(
- const byte_t *_data, uint32_t _size) const {
- return (std::make_shared<payload_impl>(_data, _size));
+std::shared_ptr<payload> runtime_impl::create_payload(const byte_t *_data,
+ uint32_t _size) const {
+ return (std::make_shared<payload_impl>(_data, _size));
}
std::shared_ptr<payload> runtime_impl::create_payload(
- const std::vector<byte_t> &_data) const {
- return (std::make_shared<payload_impl>(_data));
+ const std::vector<byte_t> &_data) const {
+ return (std::make_shared<payload_impl>(_data));
}
} // namespace vsomeip
diff --git a/implementation/service_discovery/include/configuration_option_impl.hpp b/implementation/service_discovery/include/configuration_option_impl.hpp
index de753a7..de8a97f 100644
--- a/implementation/service_discovery/include/configuration_option_impl.hpp
+++ b/implementation/service_discovery/include/configuration_option_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -23,22 +22,22 @@ namespace sd {
class configuration_option_impl: public option_impl {
public:
- configuration_option_impl();
- virtual ~configuration_option_impl();
- bool operator==(const option_impl &_other) const;
+ configuration_option_impl();
+ virtual ~configuration_option_impl();
+ bool operator==(const option_impl &_other) const;
- void add_item(const std::string &_key, const std::string &_value);
- void remove_item(const std::string &_key);
+ void add_item(const std::string &_key, const std::string &_value);
+ void remove_item(const std::string &_key);
- std::vector<std::string> get_keys() const;
- std::vector<std::string> get_values() const;
- std::string get_value(const std::string &_key) const;
+ std::vector<std::string> get_keys() const;
+ std::vector<std::string> get_values() const;
+ std::string get_value(const std::string &_key) const;
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
private:
- std::map< std::string, std::string > configuration_;
+ std::map<std::string, std::string> configuration_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/constants.hpp b/implementation/service_discovery/include/constants.hpp
index 598823e..cc476a7 100644
--- a/implementation/service_discovery/include/constants.hpp
+++ b/implementation/service_discovery/include/constants.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,11 +14,11 @@ namespace sd {
const service_t service = 0xFFFF;
const instance_t instance = 0x0000;
-const method_t method = 0x8100;
+const method_t method = 0x8100;
const client_t client = 0x0000;
const protocol_version_t protocol_version = 0x01;
const interface_version_t interface_version = 0x01;
-const message_type_e message_type = message_type_e::NOTIFICATION;
+const message_type_e message_type = message_type_e::MT_NOTIFICATION;
const return_code_e return_code = return_code_e::E_OK;
namespace protocol {
diff --git a/implementation/service_discovery/include/defines.hpp b/implementation/service_discovery/include/defines.hpp
index 3390940..a239f54 100644
--- a/implementation/service_discovery/include/defines.hpp
+++ b/implementation/service_discovery/include/defines.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,20 +6,20 @@
#ifndef VSOMEIP_SD_DEFINES_HPP
#define VSOMEIP_SD_DEFINES_HPP
-#define VSOMEIP_SOMEIP_SD_DATA_SIZE 12
-#define VSOMEIP_SOMEIP_SD_ENTRY_SIZE 16
-#define VSOMEIP_SOMEIP_SD_OPTION_HEADER_SIZE 3
+#define VSOMEIP_SOMEIP_SD_DATA_SIZE 12
+#define VSOMEIP_SOMEIP_SD_ENTRY_SIZE 16
+#define VSOMEIP_SOMEIP_SD_OPTION_HEADER_SIZE 3
-#define VSOMEIP_SD_SERVICE 0xFFFF
-#define VSOMEIP_SD_INSTANCE 0x0000
-#define VSOMEIP_SD_METHOD 0x8100
-#define VSOMEIP_SD_CLIENT 0x0000
+#define VSOMEIP_SD_SERVICE 0xFFFF
+#define VSOMEIP_SD_INSTANCE 0x0000
+#define VSOMEIP_SD_METHOD 0x8100
+#define VSOMEIP_SD_CLIENT 0x0000
-#define VSOMEIP_DEFAULT_MIN_INITIAL_DELAY 0
-#define VSOMEIP_DEFAULT_MAX_INITIAL_DELAY 3000
-#define VSOMEIP_DEFAULT_REPETITION_BASE_DELAY 10
-#define VSOMEIP_DEFAULT_REPETITION_MAX 5
-#define VSOMEIP_DEFAULT_CYCLIC_OFFER_DELAY 1000
-#define VSOMEIP_DEFAULT_CYCLIC_REQUEST_DELAY 2000
+#define VSOMEIP_SD_DEFAULT_MIN_INITIAL_DELAY 0
+#define VSOMEIP_SD_DEFAULT_MAX_INITIAL_DELAY 3000
+#define VSOMEIP_SD_DEFAULT_REPETITION_BASE_DELAY 10
+#define VSOMEIP_SD_DEFAULT_REPETITION_MAX 5
+#define VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY 1000
+#define VSOMEIP_SD_DEFAULT_CYCLIC_REQUEST_DELAY 2000
#endif // VSOMEIP_SD_DEFINES_HPP
diff --git a/implementation/service_discovery/include/deserializer.hpp b/implementation/service_discovery/include/deserializer.hpp
index d6f3312..1625e80 100755
--- a/implementation/service_discovery/include/deserializer.hpp
+++ b/implementation/service_discovery/include/deserializer.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,15 +13,14 @@ namespace sd {
class message_impl;
-class deserializer
- : public vsomeip::deserializer {
+class deserializer: public vsomeip::deserializer {
public:
- deserializer();
- deserializer(uint8_t *_data, std::size_t _length);
- deserializer(const deserializer &_other);
- virtual ~deserializer();
+ deserializer();
+ deserializer(uint8_t *_data, std::size_t _length);
+ deserializer(const deserializer &_other);
+ virtual ~deserializer();
- message_impl * deserialize_sd_message();
+ message_impl * deserialize_sd_message();
};
} // namespace sd
diff --git a/implementation/service_discovery/include/entry_impl.hpp b/implementation/service_discovery/include/entry_impl.hpp
index 6bb68c7..2da3a5f 100755
--- a/implementation/service_discovery/include/entry_impl.hpp
+++ b/implementation/service_discovery/include/entry_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -29,45 +28,46 @@ class message_impl;
class entry_impl: public message_element_impl {
public:
- virtual ~entry_impl();
+ virtual ~entry_impl();
- // public interface
- entry_type_e get_type() const;
+ // public interface
+ entry_type_e get_type() const;
- service_t get_service() const;
- void set_service(service_t _service);
+ service_t get_service() const;
+ void set_service(service_t _service);
- instance_t get_instance() const;
- void set_instance(instance_t _instance);
+ instance_t get_instance() const;
+ void set_instance(instance_t _instance);
- major_version_t get_major_version() const;
- void set_major_version(major_version_t _version);
+ major_version_t get_major_version() const;
+ void set_major_version(major_version_t _version);
- ttl_t get_ttl() const;
- void set_ttl(ttl_t _ttl);
+ ttl_t get_ttl() const;
+ void set_ttl(ttl_t _ttl);
- const std::vector< uint8_t > & get_options(uint8_t _run) const;
- void assign_option(const std::shared_ptr< option_impl > &_option, uint8_t _run);
+ const std::vector<uint8_t> & get_options(uint8_t _run) const;
+ void assign_option(const std::shared_ptr<option_impl> &_option,
+ uint8_t _run);
- bool is_service_entry() const;
- bool is_eventgroup_entry() const;
+ bool is_service_entry() const;
+ bool is_eventgroup_entry() const;
- void set_type(entry_type_e _type);
+ void set_type(entry_type_e _type);
- virtual bool serialize(vsomeip::serializer *_to) const;
- virtual bool deserialize(vsomeip::deserializer *_from);
+ virtual bool serialize(vsomeip::serializer *_to) const;
+ virtual bool deserialize(vsomeip::deserializer *_from);
protected:
- entry_type_e type_;
- service_t service_;
- instance_t instance_;
- major_version_t major_version_;
- ttl_t ttl_;
+ entry_type_e type_;
+ service_t service_;
+ instance_t instance_;
+ major_version_t major_version_;
+ ttl_t ttl_;
- std::vector< uint8_t > options_[VSOMEIP_MAX_OPTION_RUN];
+ std::vector<uint8_t> options_[VSOMEIP_MAX_OPTION_RUN];
- entry_impl();
- entry_impl(const entry_impl &entry_);
+ entry_impl();
+ entry_impl(const entry_impl &entry_);
};
} // namespace sd
diff --git a/implementation/service_discovery/include/enumeration_types.hpp b/implementation/service_discovery/include/enumeration_types.hpp
index b2f7414..8584bca 100644
--- a/implementation/service_discovery/include/enumeration_types.hpp
+++ b/implementation/service_discovery/include/enumeration_types.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,30 +11,32 @@
namespace vsomeip {
namespace sd {
-enum class option_type_e : uint8_t {
- CONFIGURATION = 0x1,
- LOAD_BALANCING = 0x2,
- PROTECTION = 0x3,
- IP4_ENDPOINT = 0x4,
- IP6_ENDPOINT = 0x6,
- IP4_MULTICAST = 0x14,
- IP6_MULTICAST = 0x16,
- UNKNOWN = 0xFF
+enum class option_type_e
+ : uint8_t {
+ CONFIGURATION = 0x1,
+ LOAD_BALANCING = 0x2,
+ PROTECTION = 0x3,
+ IP4_ENDPOINT = 0x4,
+ IP6_ENDPOINT = 0x6,
+ IP4_MULTICAST = 0x14,
+ IP6_MULTICAST = 0x16,
+ UNKNOWN = 0xFF
};
-enum class entry_type_e : uint8_t {
- FIND_SERVICE = 0x00,
- OFFER_SERVICE = 0x01,
- STOP_OFFER_SERVICE = 0x01,
- REQUEST_SERVICE = 0x2,
- FIND_EVENT_GROUP = 0x4,
- PUBLISH_EVENTGROUP = 0x5,
- STOP_PUBLISH_EVENTGROUP = 0x5,
- SUBSCRIBE_EVENTGROUP = 0x06,
- STOP_SUBSCRIBE_EVENTGROUP = 0x06,
- SUBSCRIBE_EVENTGROUP_ACK = 0x07,
- STOP_SUBSCRIBE_EVENTGROUP_ACK = 0x07,
- UNKNOWN = 0xFF
+enum class entry_type_e
+ : uint8_t {
+ FIND_SERVICE = 0x00,
+ OFFER_SERVICE = 0x01,
+ STOP_OFFER_SERVICE = 0x01,
+ REQUEST_SERVICE = 0x2,
+ FIND_EVENT_GROUP = 0x4,
+ PUBLISH_EVENTGROUP = 0x5,
+ STOP_PUBLISH_EVENTGROUP = 0x5,
+ SUBSCRIBE_EVENTGROUP = 0x06,
+ STOP_SUBSCRIBE_EVENTGROUP = 0x06,
+ SUBSCRIBE_EVENTGROUP_ACK = 0x07,
+ STOP_SUBSCRIBE_EVENTGROUP_ACK = 0x07,
+ UNKNOWN = 0xFF
};
} // namespace sd
diff --git a/implementation/service_discovery/include/eventgroupentry_impl.hpp b/implementation/service_discovery/include/eventgroupentry_impl.hpp
index 9f94cf9..cde7497 100755
--- a/implementation/service_discovery/include/eventgroupentry_impl.hpp
+++ b/implementation/service_discovery/include/eventgroupentry_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,18 +13,18 @@ namespace sd {
class eventgroupentry_impl: public entry_impl {
public:
- eventgroupentry_impl();
- eventgroupentry_impl(const eventgroupentry_impl &_entry);
- virtual ~eventgroupentry_impl();
+ eventgroupentry_impl();
+ eventgroupentry_impl(const eventgroupentry_impl &_entry);
+ virtual ~eventgroupentry_impl();
- eventgroup_t get_eventgroup() const;
- void set_eventgroup(eventgroup_t _eventgroup);
+ eventgroup_t get_eventgroup() const;
+ void set_eventgroup(eventgroup_t _eventgroup);
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
private:
- eventgroup_t eventgroup_;
+ eventgroup_t eventgroup_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/fsm_base.hpp b/implementation/service_discovery/include/fsm_base.hpp
index f82fde7..13b7158 100644
--- a/implementation/service_discovery/include/fsm_base.hpp
+++ b/implementation/service_discovery/include/fsm_base.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,20 +14,20 @@
namespace vsomeip {
namespace sd {
-class fsm_base: public std::enable_shared_from_this< fsm_base > {
+class fsm_base: public std::enable_shared_from_this<fsm_base> {
public:
- fsm_base(boost::asio::io_service &_io);
- virtual ~fsm_base();
+ fsm_base(boost::asio::io_service &_io);
+ virtual ~fsm_base();
- void start_timer(uint32_t _ms);
- void stop_timer();
+ void start_timer(uint32_t _ms);
+ void stop_timer();
- uint32_t expired_from_now();
+ uint32_t expired_from_now();
- virtual void timer_expired(const boost::system::error_code &_error) = 0;
+ virtual void timer_expired(const boost::system::error_code &_error) = 0;
private:
- boost::asio::system_timer timer_;
+ boost::asio::system_timer timer_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/fsm_events.hpp b/implementation/service_discovery/include/fsm_events.hpp
index 0d1dcc1..1624b00 100644
--- a/implementation/service_discovery/include/fsm_events.hpp
+++ b/implementation/service_discovery/include/fsm_events.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -16,39 +15,36 @@ namespace sc = boost::statechart;
namespace vsomeip {
namespace sd {
-struct ev_none : sc::event<ev_none> {
+struct ev_none: sc::event<ev_none> {
};
-struct ev_timeout : sc::event<ev_timeout> {
+struct ev_timeout: sc::event<ev_timeout> {
};
-struct ev_status_change : sc::event<ev_status_change> {
- ev_status_change(bool _is_up)
- : is_up_(_is_up) {
- }
+struct ev_status_change: sc::event<ev_status_change> {
+ ev_status_change(bool _is_up)
+ : is_up_(_is_up) {
+ }
- bool is_up_;
+ bool is_up_;
};
-struct ev_find_service : sc::event<ev_find_service> {
-
- ev_find_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl)
- : service_(_service),
- instance_(_instance),
- major_(_major),
- minor_(_minor),
- ttl_(_ttl) {
- }
-
- service_t service_;
- instance_t instance_;
- major_version_t major_;
- minor_version_t minor_;
- ttl_t ttl_;
+struct ev_find_service: sc::event<ev_find_service> {
+
+ ev_find_service(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl)
+ : service_(_service), instance_(_instance), major_(_major), minor_(
+ _minor), ttl_(_ttl) {
+ }
+
+ service_t service_;
+ instance_t instance_;
+ major_version_t major_;
+ minor_version_t minor_;
+ ttl_t ttl_;
};
-struct ev_offer_change : sc::event<ev_offer_change> {
+struct ev_offer_change: sc::event<ev_offer_change> {
};
} // namespace sd
diff --git a/implementation/service_discovery/include/ipv4_option_impl.hpp b/implementation/service_discovery/include/ipv4_option_impl.hpp
index 8184a23..179d82f 100644
--- a/implementation/service_discovery/include/ipv4_option_impl.hpp
+++ b/implementation/service_discovery/include/ipv4_option_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -16,28 +15,28 @@ namespace sd {
class ipv4_option_impl: public option_impl {
public:
- ipv4_option_impl(bool _is_multicast);
- virtual ~ipv4_option_impl();
- bool operator == (const option_impl &_option) const;
+ ipv4_option_impl(bool _is_multicast);
+ virtual ~ipv4_option_impl();
+ bool operator ==(const option_impl &_option) const;
- const ipv4_address_t & get_address() const;
- void set_address(const ipv4_address_t &_address);
+ const ipv4_address_t & get_address() const;
+ void set_address(const ipv4_address_t &_address);
- unsigned short get_port() const;
- void set_port(unsigned short _port);
+ unsigned short get_port() const;
+ void set_port(unsigned short _port);
- bool is_udp() const;
- void set_udp(bool _is_udp);
+ bool is_udp() const;
+ void set_udp(bool _is_udp);
- bool is_multicast() const;
+ bool is_multicast() const;
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
protected:
- ipv4_address_t address_;
- unsigned short port_;
- bool is_udp_;
+ ipv4_address_t address_;
+ unsigned short port_;
+ bool is_udp_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/ipv6_option_impl.hpp b/implementation/service_discovery/include/ipv6_option_impl.hpp
index e1aea29..f1a7a1c 100644
--- a/implementation/service_discovery/include/ipv6_option_impl.hpp
+++ b/implementation/service_discovery/include/ipv6_option_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -18,28 +17,28 @@ namespace sd {
class ipv6_option_impl: public option_impl {
public:
- ipv6_option_impl(bool _is_multicast);
- virtual ~ipv6_option_impl();
- bool operator == (const option_impl &_option) const;
+ ipv6_option_impl(bool _is_multicast);
+ virtual ~ipv6_option_impl();
+ bool operator ==(const option_impl &_option) const;
- const ipv6_address_t & get_address() const;
- void set_address(const ipv6_address_t &_address);
+ const ipv6_address_t & get_address() const;
+ void set_address(const ipv6_address_t &_address);
- unsigned short get_port() const;
- void set_port(unsigned short _port);
+ unsigned short get_port() const;
+ void set_port(unsigned short _port);
- bool is_udp() const;
- void set_udp(bool _is_udp);
+ bool is_udp() const;
+ void set_udp(bool _is_udp);
- bool is_multicast() const;
+ bool is_multicast() const;
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
protected:
- ipv6_address_t address_;
- unsigned short port_;
- bool is_udp_;
+ ipv6_address_t address_;
+ unsigned short port_;
+ bool is_udp_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/load_balancing_option_impl.hpp b/implementation/service_discovery/include/load_balancing_option_impl.hpp
index 4d43f43..0308a06 100755
--- a/implementation/service_discovery/include/load_balancing_option_impl.hpp
+++ b/implementation/service_discovery/include/load_balancing_option_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,22 +14,22 @@ namespace sd {
class load_balancing_option_impl: public option_impl {
public:
- load_balancing_option_impl();
- virtual ~load_balancing_option_impl();
- bool operator ==(const option_impl &_other) const;
+ load_balancing_option_impl();
+ virtual ~load_balancing_option_impl();
+ bool operator ==(const option_impl &_other) const;
- priority_t get_priority() const;
- void set_priority(priority_t _priority);
+ priority_t get_priority() const;
+ void set_priority(priority_t _priority);
- weight_t get_weight() const;
- void set_weight(weight_t _weight);
+ weight_t get_weight() const;
+ void set_weight(weight_t _weight);
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
private:
- priority_t priority_;
- weight_t weight_;
+ priority_t priority_;
+ weight_t weight_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/message_element_impl.hpp b/implementation/service_discovery/include/message_element_impl.hpp
index ee67563..39ae3a1 100755
--- a/implementation/service_discovery/include/message_element_impl.hpp
+++ b/implementation/service_discovery/include/message_element_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,13 +13,13 @@ class message_impl;
class message_element_impl {
public:
- message_element_impl();
+ message_element_impl();
- message_impl * get_owning_message() const;
- void set_owning_message(message_impl *_owner);
+ message_impl * get_owning_message() const;
+ void set_owning_message(message_impl *_owner);
protected:
- message_impl *owner_;
+ message_impl *owner_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/message_impl.hpp b/implementation/service_discovery/include/message_impl.hpp
index 788782a..e471ace 100755
--- a/implementation/service_discovery/include/message_impl.hpp
+++ b/implementation/service_discovery/include/message_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -29,51 +28,49 @@ class ipv6_option_impl;
class load_balancing_option_impl;
class protection_option_impl;
-class message_impl:
- public vsomeip::message,
- public vsomeip::message_base_impl {
+class message_impl: public vsomeip::message, public vsomeip::message_base_impl {
public:
- message_impl();
- virtual ~message_impl();
+ message_impl();
+ virtual ~message_impl();
- length_t get_length() const;
- void set_length(length_t _length);
+ length_t get_length() const;
+ void set_length(length_t _length);
- bool get_reboot_flag() const;
- void set_reboot_flag(bool _is_set);
+ bool get_reboot_flag() const;
+ void set_reboot_flag(bool _is_set);
- bool get_unicast_flag() const;
- void set_unicast_flag(bool _is_set);
+ bool get_unicast_flag() const;
+ void set_unicast_flag(bool _is_set);
- std::shared_ptr< eventgroupentry_impl > create_eventgroup_entry();
- std::shared_ptr< serviceentry_impl > create_service_entry();
+ std::shared_ptr<eventgroupentry_impl> create_eventgroup_entry();
+ std::shared_ptr<serviceentry_impl> create_service_entry();
- std::shared_ptr< configuration_option_impl > create_configuration_option();
- std::shared_ptr< ipv4_option_impl > create_ipv4_option(bool _is_multicast);
- std::shared_ptr< ipv6_option_impl > create_ipv6_option(bool _is_multicast);
- std::shared_ptr< load_balancing_option_impl > create_load_balancing_option();
- std::shared_ptr< protection_option_impl > create_protection_option();
+ std::shared_ptr<configuration_option_impl> create_configuration_option();
+ std::shared_ptr<ipv4_option_impl> create_ipv4_option(bool _is_multicast);
+ std::shared_ptr<ipv6_option_impl> create_ipv6_option(bool _is_multicast);
+ std::shared_ptr<load_balancing_option_impl> create_load_balancing_option();
+ std::shared_ptr<protection_option_impl> create_protection_option();
- const std::vector< std::shared_ptr< entry_impl > > & get_entries() const;
- const std::vector< std::shared_ptr< option_impl > > & get_options() const;
+ const std::vector<std::shared_ptr<entry_impl> > & get_entries() const;
+ const std::vector<std::shared_ptr<option_impl> > & get_options() const;
- int16_t get_option_index(const std::shared_ptr< option_impl > &_option) const;
+ int16_t get_option_index(const std::shared_ptr<option_impl> &_option) const;
- std::shared_ptr< payload > get_payload() const;
- void set_payload(std::shared_ptr< payload > _payload);
+ std::shared_ptr<payload> get_payload() const;
+ void set_payload(std::shared_ptr<payload> _payload);
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
private:
- entry_impl * deserialize_entry(vsomeip::deserializer *_from);
- option_impl * deserialize_option(vsomeip::deserializer *_from);
+ entry_impl * deserialize_entry(vsomeip::deserializer *_from);
+ option_impl * deserialize_option(vsomeip::deserializer *_from);
private:
- flags_t flags_;
+ flags_t flags_;
- std::vector< std::shared_ptr< entry_impl > > entries_;
- std::vector< std::shared_ptr< option_impl > > options_;
+ std::vector<std::shared_ptr<entry_impl> > entries_;
+ std::vector<std::shared_ptr<option_impl> > options_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/option_impl.hpp b/implementation/service_discovery/include/option_impl.hpp
index 09bc022..90a6a48 100644
--- a/implementation/service_discovery/include/option_impl.hpp
+++ b/implementation/service_discovery/include/option_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -23,20 +22,20 @@ class message_impl;
class option_impl: public message_element_impl {
public:
- option_impl();
- virtual ~option_impl();
+ option_impl();
+ virtual ~option_impl();
- virtual bool operator ==(const option_impl &_other) const;
+ virtual bool operator ==(const option_impl &_other) const;
- uint16_t get_length() const;
- option_type_e get_type() const;
+ uint16_t get_length() const;
+ option_type_e get_type() const;
- virtual bool serialize(vsomeip::serializer *_to) const;
- virtual bool deserialize(vsomeip::deserializer *_from);
+ virtual bool serialize(vsomeip::serializer *_to) const;
+ virtual bool deserialize(vsomeip::deserializer *_from);
protected:
- uint16_t length_;
- option_type_e type_;
+ uint16_t length_;
+ option_type_e type_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/primitive_types.hpp b/implementation/service_discovery/include/primitive_types.hpp
index 14b6549..fd12698 100644
--- a/implementation/service_discovery/include/primitive_types.hpp
+++ b/implementation/service_discovery/include/primitive_types.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/service_discovery/include/protection_option_impl.hpp b/implementation/service_discovery/include/protection_option_impl.hpp
index 5d2dd6b..565b22b 100755
--- a/implementation/service_discovery/include/protection_option_impl.hpp
+++ b/implementation/service_discovery/include/protection_option_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,22 +14,22 @@ namespace sd {
class protection_option_impl: public option_impl {
public:
- protection_option_impl();
- virtual ~protection_option_impl();
- virtual bool operator ==(const option_impl &_other) const;
+ protection_option_impl();
+ virtual ~protection_option_impl();
+ virtual bool operator ==(const option_impl &_other) const;
- alive_counter_t get_alive_counter() const;
- void set_alive_counter(alive_counter_t _counter);
+ alive_counter_t get_alive_counter() const;
+ void set_alive_counter(alive_counter_t _counter);
- crc_t get_crc() const;
- void set_crc(crc_t _crc);
+ crc_t get_crc() const;
+ void set_crc(crc_t _crc);
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
private:
- alive_counter_t counter_;
- crc_t crc_;
+ alive_counter_t counter_;
+ crc_t crc_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/request.hpp b/implementation/service_discovery/include/request.hpp
index 28d1fa8..9e62deb 100644
--- a/implementation/service_discovery/include/request.hpp
+++ b/implementation/service_discovery/include/request.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,21 +18,21 @@ namespace sd {
class request {
public:
- request(major_version_t _major, minor_version_t _minor, ttl_t _ttl);
+ request(major_version_t _major, minor_version_t _minor, ttl_t _ttl);
- major_version_t get_major() const;
- void set_major(major_version_t _major);
+ major_version_t get_major() const;
+ void set_major(major_version_t _major);
- minor_version_t get_minor() const;
- void set_minor(minor_version_t _minor);
+ minor_version_t get_minor() const;
+ void set_minor(minor_version_t _minor);
- ttl_t get_ttl() const;
- void set_ttl(ttl_t _ttl);
+ ttl_t get_ttl() const;
+ void set_ttl(ttl_t _ttl);
private:
- major_version_t major_;
- minor_version_t minor_;
- ttl_t ttl_;
+ major_version_t major_;
+ minor_version_t minor_;
+ ttl_t ttl_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/runtime.hpp b/implementation/service_discovery/include/runtime.hpp
index b2e0c8d..47255a2 100644
--- a/implementation/service_discovery/include/runtime.hpp
+++ b/implementation/service_discovery/include/runtime.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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 +18,13 @@ class service_discovery_host;
class runtime {
public:
- static runtime * get();
- virtual ~runtime() {};
+ static std::shared_ptr<runtime> get();
+ virtual ~runtime() {
+ }
- virtual std::shared_ptr< service_discovery > create_service_discovery(service_discovery_host *_host) const = 0;
- virtual std::shared_ptr< message_impl > create_message() const = 0;
+ virtual std::shared_ptr<service_discovery> create_service_discovery(
+ service_discovery_host *_host) const = 0;
+ virtual std::shared_ptr<message_impl> create_message() const = 0;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/runtime_impl.hpp b/implementation/service_discovery/include/runtime_impl.hpp
index 731c0be..cc0e14e 100644
--- a/implementation/service_discovery/include/runtime_impl.hpp
+++ b/implementation/service_discovery/include/runtime_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,11 +13,12 @@ namespace sd {
class runtime_impl: public runtime {
public:
- static runtime * get();
- virtual ~runtime_impl();
+ static std::shared_ptr<runtime> get();
+ virtual ~runtime_impl();
- std::shared_ptr< service_discovery > create_service_discovery(service_discovery_host *_host) const;
- std::shared_ptr< message_impl > create_message() const;
+ std::shared_ptr<service_discovery> create_service_discovery(
+ service_discovery_host *_host) const;
+ std::shared_ptr<message_impl> create_message() const;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp
index 6ab6460..0d10388 100644
--- a/implementation/service_discovery/include/service_discovery.hpp
+++ b/implementation/service_discovery/include/service_discovery.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,33 +18,33 @@ namespace sd {
class service_discovery {
public:
- virtual ~service_discovery() {};
+ virtual ~service_discovery() {
+ }
- virtual std::shared_ptr<configuration> get_configuration() const = 0;
- virtual boost::asio::io_service & get_io() = 0;
+ virtual std::shared_ptr<configuration> get_configuration() const = 0;
+ virtual boost::asio::io_service & get_io() = 0;
- virtual void init() = 0;
- virtual void start() = 0;
- virtual void stop() = 0;
+ virtual void init() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
- virtual void request_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl) = 0;
- virtual void release_service(service_t _service, instance_t _instance) = 0;
+ virtual void request_service(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl) = 0;
+ virtual void release_service(service_t _service, instance_t _instance) = 0;
- virtual void subscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl) = 0;
- virtual void unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup) = 0;
+ virtual void subscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client) = 0;
+ virtual void unsubscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup) = 0;
- virtual void send(const std::string &_name, bool _is_announcing) = 0;
+ virtual void send(const std::string &_name, bool _is_announcing) = 0;
- virtual void on_message(const byte_t *_data, length_t _length) = 0;
+ virtual void on_message(const byte_t *_data, length_t _length) = 0;
- virtual void on_offer_change(const std::string &_name) = 0;
+ virtual void on_offer_change(const std::string &_name) = 0;
};
} // namespace sd
} // namespace vsomeip
#endif // VSOMEIP_SERVICE_DISCOVERY_HPP
-
diff --git a/implementation/service_discovery/include/service_discovery_fsm.hpp b/implementation/service_discovery/include/service_discovery_fsm.hpp
index 54fd042..d731b0b 100644
--- a/implementation/service_discovery/include/service_discovery_fsm.hpp
+++ b/implementation/service_discovery/include/service_discovery_fsm.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,6 +6,7 @@
#ifndef VSOMEIP_SD_SERVICE_DISCOVERY_FSM_HPP
#define VSOMEIP_SD_SERVICE_DISCOVERY_FSM_HPP
+#include <mutex>
#include <string>
#include <boost/mpl/list.hpp>
@@ -33,84 +33,79 @@ namespace sc = boost::statechart;
namespace _sd {
struct inactive;
-struct fsm:
- sc::state_machine< fsm, inactive >, public fsm_base {
+struct fsm: sc::state_machine<fsm, inactive>, public fsm_base {
- fsm(service_discovery_fsm *_fsm);
- virtual ~fsm();
+ fsm(boost::asio::io_service &_io);
+ virtual ~fsm();
- void timer_expired(const boost::system::error_code &_error);
+ void set_fsm(std::shared_ptr<service_discovery_fsm> _fsm);
- service_discovery_fsm *fsm_;
+ void timer_expired(const boost::system::error_code &_error);
- uint32_t initial_delay_;
- uint32_t repetition_base_delay_;
- uint8_t repetition_max_;
- uint32_t cyclic_offer_delay_;
+ uint32_t initial_delay_;
+ uint32_t repetition_base_delay_;
+ uint8_t repetition_max_;
+ uint32_t cyclic_offer_delay_;
- bool is_up_;
- uint8_t run_;
+ bool is_up_;
+ uint8_t run_;
+
+ std::weak_ptr<service_discovery_fsm> fsm_;
};
-struct inactive:
- sc::state< inactive, fsm > {
+struct inactive: sc::state<inactive, fsm> {
- inactive(my_context context);
+ inactive(my_context context);
- typedef mpl::list<
- sc::custom_reaction< ev_none >,
- sc::custom_reaction< ev_status_change >
- > reactions;
+ typedef mpl::list<sc::custom_reaction<ev_none>,
+ sc::custom_reaction<ev_status_change> > reactions;
- sc::result react(const ev_none &_event);
- sc::result react(const ev_status_change &_event);
+ sc::result react(const ev_none &_event);
+ sc::result react(const ev_status_change &_event);
};
struct initial;
-struct active: sc::state< active, fsm, initial > {
+struct active: sc::state<active, fsm, initial> {
- active(my_context _context);
- ~active();
+ active(my_context _context);
+ ~active();
- typedef sc::custom_reaction< ev_status_change > reactions;
+ typedef sc::custom_reaction<ev_status_change> reactions;
- sc::result react(const ev_status_change &_event);
+ sc::result react(const ev_status_change &_event);
};
-struct initial: sc::state< initial, active > {
+struct initial: sc::state<initial, active> {
- initial(my_context _context);
+ initial(my_context _context);
- typedef sc::custom_reaction< ev_timeout > reactions;
+ typedef sc::custom_reaction<ev_timeout> reactions;
- sc::result react(const ev_timeout &_event);
+ sc::result react(const ev_timeout &_event);
};
-struct repeat: sc::state< repeat, active > {
+struct repeat: sc::state<repeat, active> {
- repeat(my_context _context);
+ repeat(my_context _context);
- typedef mpl::list<
- sc::custom_reaction< ev_timeout >,
- sc::custom_reaction< ev_find_service >
- > reactions;
+ typedef mpl::list<sc::custom_reaction<ev_timeout>,
+ sc::custom_reaction<ev_find_service> > reactions;
- sc::result react(const ev_timeout &_event);
- sc::result react(const ev_find_service &_event);
+ sc::result react(const ev_timeout &_event);
+ sc::result react(const ev_find_service &_event);
};
-struct announce: sc::state< announce, active > {
+struct announce: sc::state<announce, active> {
- announce(my_context _context);
+ announce(my_context _context);
- typedef mpl::list<
- sc::custom_reaction< ev_timeout >,
- sc::custom_reaction< ev_find_service >
- > reactions;
+ typedef mpl::list<sc::custom_reaction<ev_timeout>,
+ sc::custom_reaction<ev_find_service>,
+ sc::custom_reaction<ev_offer_change> > reactions;
- sc::result react(const ev_timeout &_event);
- sc::result react(const ev_find_service &_event);
- sc::result react(const ev_offer_change &_event);
+ sc::result react(const ev_timeout &_event);
+ sc::result react(const ev_find_service &_event);
+ sc::result react(const ev_offer_change &_event);
};
} // namespace _offer
@@ -118,27 +113,31 @@ struct announce: sc::state< announce, active > {
///////////////////////////////////////////////////////////////////////////////
// Interface
///////////////////////////////////////////////////////////////////////////////
-class service_discovery_fsm {
+class service_discovery_fsm: public std::enable_shared_from_this<
+ service_discovery_fsm> {
public:
- service_discovery_fsm(const std::string &_name, service_discovery *_discovery);
+ service_discovery_fsm(const std::string &_name,
+ std::shared_ptr<service_discovery> _discovery);
- const std::string & get_name() const;
- boost::asio::io_service & get_io();
+ const std::string & get_name() const;
- void start();
- void stop();
+ void start();
+ void stop();
- void send(bool _is_announcing);
+ void send(bool _is_announcing);
- inline void process(const sc::event_base &_event) {
- fsm_->process_event(_event);
- }
+ inline void process(const sc::event_base &_event) {
+ std::lock_guard<std::mutex> its_lock(lock_);
+ fsm_->process_event(_event);
+ }
private:
- std::string name_;
+ std::string name_;
+
+ std::weak_ptr<service_discovery> discovery_;
+ std::shared_ptr<_sd::fsm> fsm_;
- service_discovery *discovery_;
- std::shared_ptr< _sd::fsm > fsm_ ;
+ std::mutex lock_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp
index 24eecdb..f9ad9e5 100644
--- a/implementation/service_discovery/include/service_discovery_host.hpp
+++ b/implementation/service_discovery/include/service_discovery_host.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -24,49 +23,48 @@ class endpoint_definition;
namespace sd {
class service_discovery_host {
- public:
- virtual ~service_discovery_host() {};
+public:
+ virtual ~service_discovery_host() {
+ }
- virtual boost::asio::io_service & get_io() = 0;
- virtual std::shared_ptr<configuration> get_configuration() const = 0;
+ virtual boost::asio::io_service & get_io() = 0;
+ virtual std::shared_ptr<configuration> get_configuration() const = 0;
- virtual void create_service_discovery_endpoint(const std::string &_address,
- uint16_t _port,
- bool _reliable) = 0;
+ virtual void create_service_discovery_endpoint(const std::string &_address,
+ uint16_t _port, bool _reliable) = 0;
- virtual services_t get_offered_services(const std::string &_name) const = 0;
- virtual std::shared_ptr<eventgroupinfo> find_eventgroup(
- service_t _service, instance_t _instance,
- eventgroup_t _eventgroup) const = 0;
+ virtual services_t get_offered_services(const std::string &_name) const = 0;
+ virtual std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) const = 0;
- virtual bool send(client_t _client, std::shared_ptr<message> _message,
- bool _flush, bool _reliable) = 0;
+ virtual bool send(client_t _client, std::shared_ptr<message> _message,
+ bool _flush) = 0;
- virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
- const byte_t *_data, uint32_t _size) = 0;
+ virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
+ const byte_t *_data, uint32_t _size) = 0;
- virtual void add_routing_info(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor,
- ttl_t _ttl,
- const boost::asio::ip::address &_address,
- uint16_t _port, bool _reliable) = 0;
+ virtual void add_routing_info(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl,
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable) = 0;
- virtual void del_routing_info(service_t _service, instance_t _instance,
- bool _reliable) = 0;
+ virtual void del_routing_info(service_t _service, instance_t _instance,
+ bool _reliable) = 0;
- virtual void on_subscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _subscriber,
- std::shared_ptr<endpoint_definition> _target) = 0;
+ virtual void on_subscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup,
+ std::shared_ptr<endpoint_definition> _subscriber,
+ std::shared_ptr<endpoint_definition> _target) = 0;
- virtual void on_unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<endpoint_definition> _target) = 0;
+ virtual void on_unsubscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup,
+ std::shared_ptr<endpoint_definition> _target) = 0;
- virtual void on_subscribe_ack(service_t _service, instance_t _instance,
- const boost::asio::ip::address &_address, uint16_t _port) = 0;
+ virtual void on_subscribe_ack(service_t _service, instance_t _instance,
+ const boost::asio::ip::address &_address, uint16_t _port) = 0;
- virtual std::shared_ptr<endpoint> find_remote_client(service_t _service,
- instance_t _instance,
- bool _reliable) = 0;
+ virtual std::shared_ptr<endpoint> find_or_create_remote_client(service_t _service,
+ instance_t _instance, bool _reliable, client_t _client) = 0;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp
index 0013ac4..d07698e 100644
--- a/implementation/service_discovery/include/service_discovery_impl.hpp
+++ b/implementation/service_discovery/include/service_discovery_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,101 +34,99 @@ class subscription;
typedef std::map<service_t, std::map<instance_t, std::shared_ptr<request> > > requests_t;
-class service_discovery_impl : public service_discovery,
- public std::enable_shared_from_this<service_discovery_impl> {
- public:
- service_discovery_impl(service_discovery_host *_host);
- virtual ~service_discovery_impl();
-
- std::shared_ptr<configuration> get_configuration() const;
- boost::asio::io_service & get_io();
-
- void init();
- void start();
- void stop();
-
- void request_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor,
- ttl_t _ttl);
- void release_service(service_t _service, instance_t _instance);
-
- void subscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
- void unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup);
-
- void send(const std::string &_name, bool _is_announcing);
-
- void on_message(const byte_t *_data, length_t _length);
-
- void on_offer_change(const std::string &_name);
-
- private:
- session_t get_session(const boost::asio::ip::address &_address);
- void increment_session(const boost::asio::ip::address &_address);
-
- void insert_option(std::shared_ptr<message_impl> &_message,
- std::shared_ptr<entry_impl> _entry,
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _is_reliable);
- void insert_find_entries(std::shared_ptr<message_impl> &_message,
- requests_t &_requests);
- void insert_offer_entries(std::shared_ptr<message_impl> &_message,
- services_t &_services);
- void insert_subscription(std::shared_ptr<message_impl> &_message,
- service_t _service, instance_t _instance,
- eventgroup_t _eventgroup,
- std::shared_ptr<subscription> &_subscription);
- void insert_subscription_ack(std::shared_ptr<message_impl> &_message,
- service_t _service, instance_t _instance,
- eventgroup_t _eventgroup,
- std::shared_ptr<eventgroupinfo> &_info);
-
- void process_serviceentry(
- std::shared_ptr<serviceentry_impl> &_entry,
- const std::vector<std::shared_ptr<option_impl> > &_options);
- void process_eventgroupentry(
- std::shared_ptr<eventgroupentry_impl> &_entry,
- const std::vector<std::shared_ptr<option_impl> > &_options);
-
- void handle_service_availability(service_t _service, instance_t _instance,
- major_version_t _major,
- minor_version_t _minor, ttl_t _ttl,
- const boost::asio::ip::address &_address,
- uint16_t _port, bool _reliable);
- void handle_eventgroup_subscription(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl,
- const boost::asio::ip::address &_reliable_address,
- uint16_t _reliable_port, uint16_t _unreliable_port);
- void handle_eventgroup_subscription_ack(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl,
- const boost::asio::ip::address &_address, uint16_t _port);
-
- private:
- boost::asio::io_service &io_;
- service_discovery_host *host_;
-
- boost::asio::ip::address unicast_;
- uint16_t port_;
- bool reliable_;
-
- std::shared_ptr<serializer> serializer_;
- std::shared_ptr<deserializer> deserializer_;
-
- std::shared_ptr<service_discovery_fsm> default_;
- std::map<std::string, std::shared_ptr<service_discovery_fsm> > additional_;
-
- requests_t requested_;
- std::map<service_t,
- std::map<instance_t,
- std::map<eventgroup_t, std::shared_ptr<subscription> > > > subscribed_;
-
- std::mutex serialize_mutex_;
-
- // Sessions
- std::map<boost::asio::ip::address, session_t> sessions_;
+class service_discovery_impl: public service_discovery,
+ public std::enable_shared_from_this<service_discovery_impl> {
+public:
+ service_discovery_impl(service_discovery_host *_host);
+ virtual ~service_discovery_impl();
+
+ std::shared_ptr<configuration> get_configuration() const;
+ boost::asio::io_service & get_io();
+
+ void init();
+ void start();
+ void stop();
+
+ void request_service(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl);
+ void release_service(service_t _service, instance_t _instance);
+
+ void subscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client);
+ void unsubscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup);
+
+ void send(const std::string &_name, bool _is_announcing);
+
+ void on_message(const byte_t *_data, length_t _length);
+
+ void on_offer_change(const std::string &_name);
+
+private:
+ session_t get_session(const boost::asio::ip::address &_address);
+ void increment_session(const boost::asio::ip::address &_address);
+
+ void insert_option(std::shared_ptr<message_impl> &_message,
+ std::shared_ptr<entry_impl> _entry,
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _is_reliable);
+ void insert_find_entries(std::shared_ptr<message_impl> &_message,
+ requests_t &_requests);
+ void insert_offer_entries(std::shared_ptr<message_impl> &_message,
+ services_t &_services);
+ void insert_subscription(std::shared_ptr<message_impl> &_message,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<subscription> &_subscription);
+ void insert_subscription_ack(std::shared_ptr<message_impl> &_message,
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<eventgroupinfo> &_info);
+
+ void process_serviceentry(std::shared_ptr<serviceentry_impl> &_entry,
+ const std::vector<std::shared_ptr<option_impl> > &_options);
+ void process_eventgroupentry(std::shared_ptr<eventgroupentry_impl> &_entry,
+ const std::vector<std::shared_ptr<option_impl> > &_options);
+
+ void handle_service_availability(service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl,
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable);
+ void handle_eventgroup_subscription(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl,
+ const boost::asio::ip::address &_reliable_address,
+ uint16_t _reliable_port, uint16_t _unreliable_port);
+ void handle_eventgroup_subscription_ack(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl,
+ const boost::asio::ip::address &_address, uint16_t _port);
+
+private:
+ boost::asio::io_service &io_;
+ service_discovery_host *host_;
+
+ boost::asio::ip::address unicast_;
+ uint16_t port_;
+ bool reliable_;
+
+ std::shared_ptr<serializer> serializer_;
+ std::shared_ptr<deserializer> deserializer_;
+
+ std::shared_ptr<service_discovery_fsm> default_;
+ std::map<std::string, std::shared_ptr<service_discovery_fsm> > additional_;
+
+ requests_t requested_;
+ std::mutex requested_mutex_;
+ std::map<service_t,
+ std::map<instance_t,
+ std::map<eventgroup_t, std::map<client_t, std::shared_ptr<subscription> > > > > subscribed_;
+
+ std::mutex serialize_mutex_;
+
+ // Sessions
+ std::map<boost::asio::ip::address, session_t> sessions_;
+
+ // Runtime
+ std::weak_ptr<runtime> runtime_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/serviceentry_impl.hpp b/implementation/service_discovery/include/serviceentry_impl.hpp
index 3065418..f83e62a 100644
--- a/implementation/service_discovery/include/serviceentry_impl.hpp
+++ b/implementation/service_discovery/include/serviceentry_impl.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,17 +13,17 @@ namespace sd {
class serviceentry_impl: public entry_impl {
public:
- serviceentry_impl();
- virtual ~serviceentry_impl();
+ serviceentry_impl();
+ virtual ~serviceentry_impl();
- minor_version_t get_minor_version() const;
- void set_minor_version(minor_version_t _version);
+ minor_version_t get_minor_version() const;
+ void set_minor_version(minor_version_t _version);
- bool serialize(vsomeip::serializer *_to) const;
- bool deserialize(vsomeip::deserializer *_from);
+ bool serialize(vsomeip::serializer *_to) const;
+ bool deserialize(vsomeip::deserializer *_from);
private:
- minor_version_t minor_version_;
+ minor_version_t minor_version_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp
index 098bccf..c710b9d 100644
--- a/implementation/service_discovery/include/subscription.hpp
+++ b/implementation/service_discovery/include/subscription.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,28 +18,29 @@ namespace sd {
class subscription {
public:
- subscription(major_version_t _major, ttl_t _ttl,
- std::shared_ptr<endpoint> _reliable,
- std::shared_ptr<endpoint> _unreliable);
- ~subscription();
+ subscription(major_version_t _major, ttl_t _ttl,
+ std::shared_ptr<endpoint> _reliable,
+ std::shared_ptr<endpoint> _unreliable,
+ client_t _target);
+ ~subscription();
- major_version_t get_major() const;
- ttl_t get_ttl() const;
- void set_ttl(ttl_t _ttl);
- std::shared_ptr<endpoint> get_endpoint(bool _reliable) const;
- void set_endpoint(std::shared_ptr<endpoint> _endpoint, bool _reliable);
+ major_version_t get_major() const;
+ ttl_t get_ttl() const;
+ void set_ttl(ttl_t _ttl);
+ std::shared_ptr<endpoint> get_endpoint(bool _reliable) const;
+ void set_endpoint(std::shared_ptr<endpoint> _endpoint, bool _reliable);
- bool is_acknowleged() const;
- void set_acknowledged(bool _is_acknowledged);
+ bool is_acknowleged() const;
+ void set_acknowledged(bool _is_acknowledged);
private:
- major_version_t major_;
- ttl_t ttl_;
+ major_version_t major_;
+ ttl_t ttl_;
- std::shared_ptr<endpoint> reliable_;
- std::shared_ptr<endpoint> unreliable_;
+ std::shared_ptr<endpoint> reliable_;
+ std::shared_ptr<endpoint> unreliable_;
- bool is_acknowledged_;
+ bool is_acknowledged_;
};
} // namespace sd
diff --git a/implementation/service_discovery/src/configuration_option_impl.cpp b/implementation/service_discovery/src/configuration_option_impl.cpp
index f1b5284..e6092da 100755
--- a/implementation/service_discovery/src/configuration_option_impl.cpp
+++ b/implementation/service_discovery/src/configuration_option_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,107 +13,110 @@ namespace vsomeip {
namespace sd {
configuration_option_impl::configuration_option_impl() {
- length_ = 2; // always contains "Reserved" and the trailing '\0'
- type_ = option_type_e::CONFIGURATION;
+ length_ = 2; // always contains "Reserved" and the trailing '\0'
+ type_ = option_type_e::CONFIGURATION;
}
configuration_option_impl::~configuration_option_impl() {
}
bool configuration_option_impl::operator ==(const option_impl &_other) const {
- if (_other.get_type() != option_type_e::CONFIGURATION)
- return false;
+ if (_other.get_type() != option_type_e::CONFIGURATION)
+ return false;
- const configuration_option_impl& other
- = dynamic_cast< const configuration_option_impl & >(_other);
+ const configuration_option_impl& other =
+ dynamic_cast<const configuration_option_impl &>(_other);
- return (configuration_ == other.configuration_);
+ return (configuration_ == other.configuration_);
}
-void configuration_option_impl::add_item(const std::string &_key, const std::string &_value) {
- configuration_[_key] = _value;
- length_ += (_key.length() + _value.length() + 2); // +2 for the '=' and length
+void configuration_option_impl::add_item(const std::string &_key,
+ const std::string &_value) {
+ configuration_[_key] = _value;
+ length_ += (_key.length() + _value.length() + 2); // +2 for the '=' and length
}
void configuration_option_impl::remove_item(const std::string &_key) {
- auto it = configuration_.find(_key);
- if (it != configuration_.end()) {
- length_ -= (it->first.length() + it->second.length() + 2);
- configuration_.erase(it);
- }
+ auto it = configuration_.find(_key);
+ if (it != configuration_.end()) {
+ length_ -= (it->first.length() + it->second.length() + 2);
+ configuration_.erase(it);
+ }
}
std::vector<std::string> configuration_option_impl::get_keys() const {
- std::vector<std::string> l_keys;
- for (auto elem : configuration_)
- l_keys.push_back(elem.first);
- return l_keys;
+ std::vector < std::string > l_keys;
+ for (auto elem : configuration_)
+ l_keys.push_back(elem.first);
+ return l_keys;
}
std::vector<std::string> configuration_option_impl::get_values() const {
- std::vector<std::string> l_values;
- for (auto elem : configuration_)
- l_values.push_back(elem.second);
- return l_values;
+ std::vector < std::string > l_values;
+ for (auto elem : configuration_)
+ l_values.push_back(elem.second);
+ return l_values;
}
-std::string configuration_option_impl::get_value(const std::string &_key) const {
- std::string l_value("");
- auto l_elem = configuration_.find(_key);
- if (l_elem != configuration_.end())
- l_value = l_elem->second;
- return l_value;
+std::string configuration_option_impl::get_value(
+ const std::string &_key) const {
+ std::string l_value("");
+ auto l_elem = configuration_.find(_key);
+ if (l_elem != configuration_.end())
+ l_value = l_elem->second;
+ return l_value;
}
bool configuration_option_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful;
- std::string configuration_string;
-
- for (auto i = configuration_.begin(); i != configuration_.end(); ++i) {
- char l_length = 1 + i->first.length() + i->second.length();
- configuration_string.push_back(l_length);
- configuration_string.append(i->first);
- configuration_string.push_back('=');
- configuration_string.append(i->second);
- }
- configuration_string.push_back('\0');
-
- is_successful = option_impl::serialize(_to);
- if (is_successful) {
- is_successful = _to->serialize(
- reinterpret_cast<const uint8_t*>(configuration_string.c_str()),
- configuration_string.length());
- }
-
- return is_successful;
+ bool is_successful;
+ std::string configuration_string;
+
+ for (auto i = configuration_.begin(); i != configuration_.end(); ++i) {
+ char l_length = 1 + i->first.length() + i->second.length();
+ configuration_string.push_back(l_length);
+ configuration_string.append(i->first);
+ configuration_string.push_back('=');
+ configuration_string.append(i->second);
+ }
+ configuration_string.push_back('\0');
+
+ is_successful = option_impl::serialize(_to);
+ if (is_successful) {
+ is_successful = _to->serialize(
+ reinterpret_cast<const uint8_t*>(configuration_string.c_str()),
+ configuration_string.length());
+ }
+
+ return is_successful;
}
bool configuration_option_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = option_impl::deserialize(_from);
- uint8_t l_length = 0;
- std::string l_item(256, 0), l_key, l_value;
-
- do {
- is_successful = is_successful && _from->deserialize(l_length);
- if (l_length > 0) {
- is_successful = is_successful && _from->deserialize((uint8_t*)&l_item[0], l_length);
- if (is_successful) {
- size_t l_eqPos = l_item.find('=');
- l_key = l_item.substr(0, l_eqPos);
- l_value = l_item.substr(l_eqPos+1);
-
- if (configuration_.end() == configuration_.find(l_key)) {
- configuration_[l_key] = l_value;
- } else {
- // TODO: log reason for failing deserialization
- is_successful = false;
- }
- }
- }
-
- } while (is_successful && l_length > 0);
-
- return is_successful;
+ bool is_successful = option_impl::deserialize(_from);
+ uint8_t l_length = 0;
+ std::string l_item(256, 0), l_key, l_value;
+
+ do {
+ is_successful = is_successful && _from->deserialize(l_length);
+ if (l_length > 0) {
+ is_successful = is_successful
+ && _from->deserialize((uint8_t*) &l_item[0], l_length);
+ if (is_successful) {
+ size_t l_eqPos = l_item.find('=');
+ l_key = l_item.substr(0, l_eqPos);
+ l_value = l_item.substr(l_eqPos + 1);
+
+ if (configuration_.end() == configuration_.find(l_key)) {
+ configuration_[l_key] = l_value;
+ } else {
+ // TODO: log reason for failing deserialization
+ is_successful = false;
+ }
+ }
+ }
+
+ } while (is_successful && l_length > 0);
+
+ return is_successful;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/deserializer.cpp b/implementation/service_discovery/src/deserializer.cpp
index 4fcdaa5..cb86c52 100644
--- a/implementation/service_discovery/src/deserializer.cpp
+++ b/implementation/service_discovery/src/deserializer.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -11,30 +10,30 @@ namespace vsomeip {
namespace sd {
deserializer::deserializer()
- : vsomeip::deserializer() {
+ : vsomeip::deserializer() {
}
deserializer::deserializer(uint8_t *_data, std::size_t _length)
- : vsomeip::deserializer(_data, _length) {
+ : vsomeip::deserializer(_data, _length) {
}
deserializer::deserializer(const deserializer &_other)
- : vsomeip::deserializer(_other) {
+ : vsomeip::deserializer(_other) {
}
deserializer::~deserializer() {
}
message_impl * deserializer::deserialize_sd_message() {
- message_impl* deserialized_message = new message_impl;
- if (0 != deserialized_message) {
- if (false == deserialized_message->deserialize(this)) {
- delete deserialized_message;
- deserialized_message = 0;
- }
- }
-
- return deserialized_message;
+ message_impl* deserialized_message = new message_impl;
+ if (0 != deserialized_message) {
+ if (false == deserialized_message->deserialize(this)) {
+ delete deserialized_message;
+ deserialized_message = 0;
+ }
+ }
+
+ return deserialized_message;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/entry_impl.cpp b/implementation/service_discovery/src/entry_impl.cpp
index bf9d804..735f120 100755
--- a/implementation/service_discovery/src/entry_impl.cpp
+++ b/implementation/service_discovery/src/entry_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -16,159 +15,158 @@ namespace sd {
// TODO: throw exception if this constructor is used
entry_impl::entry_impl() {
- type_ = entry_type_e::UNKNOWN;
- major_version_ = 0;
- service_ = 0x0;
- instance_ = 0x0;
- ttl_ = 0x0;
+ type_ = entry_type_e::UNKNOWN;
+ major_version_ = 0;
+ service_ = 0x0;
+ instance_ = 0x0;
+ ttl_ = 0x0;
}
entry_impl::entry_impl(const entry_impl &_entry) {
- type_ = _entry.type_;
- major_version_ = _entry.major_version_;
- service_ = _entry.service_;
- instance_ = _entry.instance_;
- ttl_ = _entry.ttl_;
+ type_ = _entry.type_;
+ major_version_ = _entry.major_version_;
+ service_ = _entry.service_;
+ instance_ = _entry.instance_;
+ ttl_ = _entry.ttl_;
}
entry_impl::~entry_impl() {
}
entry_type_e entry_impl::get_type() const {
- return type_;
+ return type_;
}
void entry_impl::set_type(entry_type_e _type) {
- type_ = _type;
+ type_ = _type;
}
service_t entry_impl::get_service() const {
- return service_;
+ return service_;
}
void entry_impl::set_service(service_t _service) {
- service_ = _service;
+ service_ = _service;
}
instance_t entry_impl::get_instance() const {
- return instance_;
+ return instance_;
}
void entry_impl::set_instance(instance_t _instance) {
- instance_ = _instance;
+ instance_ = _instance;
}
major_version_t entry_impl::get_major_version() const {
- return major_version_;
+ return major_version_;
}
void entry_impl::set_major_version(major_version_t _major_version) {
- major_version_ = _major_version;
+ major_version_ = _major_version;
}
ttl_t entry_impl::get_ttl() const {
- return ttl_;
+ return ttl_;
}
void entry_impl::set_ttl(ttl_t _ttl) {
- ttl_ = _ttl;
+ ttl_ = _ttl;
}
-const std::vector< uint8_t > & entry_impl::get_options(uint8_t _run) const {
- static std::vector< uint8_t > invalid_options;
- if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN)
- return options_[_run-1];
+const std::vector<uint8_t> & entry_impl::get_options(uint8_t _run) const {
+ static std::vector<uint8_t> invalid_options;
+ if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN)
+ return options_[_run - 1];
- return invalid_options;
+ return invalid_options;
}
-void entry_impl::assign_option(const std::shared_ptr< option_impl > &_option, uint8_t _run) {
- if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN) {
- _run--; // Index = Run-1
+void entry_impl::assign_option(const std::shared_ptr<option_impl> &_option,
+ uint8_t _run) {
+ if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN) {
+ _run--; // Index = Run-1
- uint8_t option_index = get_owning_message()->get_option_index(_option);
- if (0x10 > option_index) { // as we have only a nibble for the option counter
- options_[_run].push_back(option_index);
- std::sort(options_[_run].begin(), options_[_run].end());
- } else {
- // TODO: decide what to do if option does not belong to the message.
- }
- } else {
- // TODO: decide what to do if an illegal index for the option run is provided
- }
+ uint8_t option_index = get_owning_message()->get_option_index(_option);
+ if (0x10 > option_index) { // as we have only a nibble for the option counter
+ options_[_run].push_back(option_index);
+ std::sort(options_[_run].begin(), options_[_run].end());
+ } else {
+ // TODO: decide what to do if option does not belong to the message.
+ }
+ } else {
+ // TODO: decide what to do if an illegal index for the option run is provided
+ }
}
bool entry_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = (0 != _to && _to->serialize(static_cast< uint8_t >(type_)));
+ bool is_successful = (0 != _to
+ && _to->serialize(static_cast<uint8_t>(type_)));
- uint8_t index_first_option_run = 0;
- if (options_[0].size() > 0)
- index_first_option_run = options_[0][0];
- is_successful = is_successful
- && _to->serialize(index_first_option_run);
+ uint8_t index_first_option_run = 0;
+ if (options_[0].size() > 0)
+ index_first_option_run = options_[0][0];
+ is_successful = is_successful && _to->serialize(index_first_option_run);
- uint8_t index_second_option_run = 0;
- if (options_[1].size() > 0)
- index_second_option_run = options_[1][0];
- is_successful = is_successful
- && _to->serialize(index_second_option_run);
+ uint8_t index_second_option_run = 0;
+ if (options_[1].size() > 0)
+ index_second_option_run = options_[1][0];
+ is_successful = is_successful && _to->serialize(index_second_option_run);
- uint8_t number_of_options = ((((uint8_t)options_[0].size()) << 4)
- | (((uint8_t)options_[1].size()) & 0x0F));
- is_successful = is_successful
- && _to->serialize(number_of_options);
+ uint8_t number_of_options = ((((uint8_t) options_[0].size()) << 4)
+ | (((uint8_t) options_[1].size()) & 0x0F));
+ is_successful = is_successful && _to->serialize(number_of_options);
- is_successful = is_successful
- && _to->serialize(static_cast< uint16_t >(service_));
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint16_t>(service_));
- is_successful = is_successful
- && _to->serialize(static_cast< uint16_t >(instance_));
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint16_t>(instance_));
- return is_successful;
+ return is_successful;
}
bool entry_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = (0 != _from);
+ bool is_successful = (0 != _from);
- uint8_t its_type;
- is_successful = is_successful && _from->deserialize(its_type);
- type_ = static_cast< entry_type_e >(its_type);
+ uint8_t its_type;
+ is_successful = is_successful && _from->deserialize(its_type);
+ type_ = static_cast<entry_type_e>(its_type);
- uint8_t its_index1;
- is_successful = is_successful && _from->deserialize(its_index1);
+ uint8_t its_index1;
+ is_successful = is_successful && _from->deserialize(its_index1);
- uint8_t its_index2;
- is_successful = is_successful && _from->deserialize(its_index2);
+ uint8_t its_index2;
+ is_successful = is_successful && _from->deserialize(its_index2);
- uint8_t its_numbers;
- is_successful = is_successful && _from->deserialize(its_numbers);
+ uint8_t its_numbers;
+ is_successful = is_successful && _from->deserialize(its_numbers);
- uint8_t its_numbers1 = (its_numbers >> 4);
- uint8_t its_numbers2 = (its_numbers & 0xF);
+ uint8_t its_numbers1 = (its_numbers >> 4);
+ uint8_t its_numbers2 = (its_numbers & 0xF);
- for (uint8_t i = its_index1; i < its_index1 + its_numbers1; ++i)
- options_[0].push_back(i);
+ for (uint8_t i = its_index1; i < its_index1 + its_numbers1; ++i)
+ options_[0].push_back(i);
- for (uint8_t i = its_index2; i < its_index2 + its_numbers2; ++i)
- options_[1].push_back(i);
+ for (uint8_t i = its_index2; i < its_index2 + its_numbers2; ++i)
+ options_[1].push_back(i);
- uint16_t its_id;
- is_successful = is_successful && _from->deserialize(its_id);
- service_ = static_cast< service_t >(its_id);
+ uint16_t its_id;
+ is_successful = is_successful && _from->deserialize(its_id);
+ service_ = static_cast<service_t>(its_id);
- is_successful = is_successful && _from->deserialize(its_id);
- instance_ = static_cast< instance_t >(its_id);
+ is_successful = is_successful && _from->deserialize(its_id);
+ instance_ = static_cast<instance_t>(its_id);
- return is_successful;
+ return is_successful;
}
bool entry_impl::is_service_entry() const {
- return (type_ <= entry_type_e::REQUEST_SERVICE);
+ return (type_ <= entry_type_e::REQUEST_SERVICE);
}
bool entry_impl::is_eventgroup_entry() const {
- return (type_ >= entry_type_e::FIND_EVENT_GROUP
- && type_ <= entry_type_e::SUBSCRIBE_EVENTGROUP_ACK);
+ return (type_ >= entry_type_e::FIND_EVENT_GROUP
+ && type_ <= entry_type_e::SUBSCRIBE_EVENTGROUP_ACK);
}
} // namespace sd
diff --git a/implementation/service_discovery/src/eventgroupentry_impl.cpp b/implementation/service_discovery/src/eventgroupentry_impl.cpp
index 7f2481a..ba303d9 100755
--- a/implementation/service_discovery/src/eventgroupentry_impl.cpp
+++ b/implementation/service_discovery/src/eventgroupentry_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,62 +12,59 @@ namespace vsomeip {
namespace sd {
eventgroupentry_impl::eventgroupentry_impl() {
- eventgroup_ = 0xFFFF;
+ eventgroup_ = 0xFFFF;
}
eventgroupentry_impl::eventgroupentry_impl(const eventgroupentry_impl &_entry)
- : entry_impl(_entry) {
-
- eventgroup_ = _entry.eventgroup_;
+ : entry_impl(_entry) {
+ eventgroup_ = _entry.eventgroup_;
}
eventgroupentry_impl::~eventgroupentry_impl() {
}
eventgroup_t eventgroupentry_impl::get_eventgroup() const {
- return eventgroup_;
+ return eventgroup_;
}
void eventgroupentry_impl::set_eventgroup(eventgroup_t _eventgroup) {
- eventgroup_ = _eventgroup;
+ eventgroup_ = _eventgroup;
}
bool eventgroupentry_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = entry_impl::serialize(_to);
+ bool is_successful = entry_impl::serialize(_to);
- is_successful = is_successful
- && _to->serialize(protocol::reserved_byte);
+ is_successful = is_successful && _to->serialize(protocol::reserved_byte);
- is_successful = is_successful
- && _to->serialize(static_cast< uint32_t >(ttl_), true);
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint32_t>(ttl_), true);
- is_successful = is_successful
- && _to->serialize(protocol::reserved_word);
+ is_successful = is_successful && _to->serialize(protocol::reserved_word);
- is_successful = is_successful
- && _to->serialize(static_cast< uint16_t >(eventgroup_));
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint16_t>(eventgroup_));
- return is_successful;
+ return is_successful;
}
bool eventgroupentry_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = entry_impl::deserialize(_from);
+ bool is_successful = entry_impl::deserialize(_from);
- uint8_t its_reserved0;
- is_successful = is_successful && _from->deserialize(its_reserved0);
+ uint8_t its_reserved0;
+ is_successful = is_successful && _from->deserialize(its_reserved0);
- uint32_t its_ttl;
- is_successful = is_successful && _from->deserialize(its_ttl, true);
- ttl_ = static_cast< ttl_t >(its_ttl);
+ uint32_t its_ttl;
+ is_successful = is_successful && _from->deserialize(its_ttl, true);
+ ttl_ = static_cast<ttl_t>(its_ttl);
- uint16_t its_reserved1;
- is_successful = is_successful && _from->deserialize(its_reserved1);
+ uint16_t its_reserved1;
+ is_successful = is_successful && _from->deserialize(its_reserved1);
- uint16_t its_eventgroup = 0;
- is_successful = is_successful && _from->deserialize(its_eventgroup);
- eventgroup_ = static_cast< eventgroup_t >(its_eventgroup);
+ uint16_t its_eventgroup = 0;
+ is_successful = is_successful && _from->deserialize(its_eventgroup);
+ eventgroup_ = static_cast<eventgroup_t>(its_eventgroup);
- return is_successful;
+ return is_successful;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/fsm_base.cpp b/implementation/service_discovery/src/fsm_base.cpp
index 1feba93..07a0def 100644
--- a/implementation/service_discovery/src/fsm_base.cpp
+++ b/implementation/service_discovery/src/fsm_base.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,31 +8,27 @@
namespace vsomeip {
namespace sd {
-fsm_base::fsm_base(boost::asio::io_service &_io) : timer_(_io) {
+fsm_base::fsm_base(boost::asio::io_service &_io)
+ : timer_(_io) {
}
fsm_base::~fsm_base() {
}
void fsm_base::start_timer(uint32_t _milliseconds) {
- timer_.expires_from_now(std::chrono::milliseconds(_milliseconds));
- timer_.async_wait(
- std::bind(
- &fsm_base::timer_expired,
- shared_from_this(),
- std::placeholders::_1
- )
- );
+ timer_.expires_from_now(std::chrono::milliseconds(_milliseconds));
+ timer_.async_wait(
+ std::bind(&fsm_base::timer_expired, shared_from_this(),
+ std::placeholders::_1));
}
void fsm_base::stop_timer() {
- timer_.cancel();
+ timer_.cancel();
}
uint32_t fsm_base::expired_from_now() {
- return std::chrono::duration_cast<
- std::chrono::milliseconds>(
- timer_.expires_from_now()).count();
+ return (uint32_t) std::chrono::duration_cast < std::chrono::milliseconds
+ > (timer_.expires_from_now()).count();
}
} // namespace sd
diff --git a/implementation/service_discovery/src/ipv4_option_impl.cpp b/implementation/service_discovery/src/ipv4_option_impl.cpp
index ad7449e..6416cf0 100644
--- a/implementation/service_discovery/src/ipv4_option_impl.cpp
+++ b/implementation/service_discovery/src/ipv4_option_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,68 +14,71 @@ namespace vsomeip {
namespace sd {
ipv4_option_impl::ipv4_option_impl(bool _is_multicast) {
- length_ = (1 + 4 + 1 + 1 + 2);
- type_ = (_is_multicast ? option_type_e::IP4_MULTICAST : option_type_e::IP4_ENDPOINT);
- is_udp_ = _is_multicast;
+ length_ = (1 + 4 + 1 + 1 + 2);
+ type_ = (
+ _is_multicast ?
+ option_type_e::IP4_MULTICAST : option_type_e::IP4_ENDPOINT);
+ is_udp_ = _is_multicast;
}
ipv4_option_impl::~ipv4_option_impl() {
}
bool ipv4_option_impl::operator ==(const option_impl &_other) const {
- if (type_ != _other.get_type())
- return false;
+ if (type_ != _other.get_type())
+ return false;
- const ipv4_option_impl & other = dynamic_cast< const ipv4_option_impl & >(_other);
- return true;
+ const ipv4_option_impl & other =
+ dynamic_cast<const ipv4_option_impl &>(_other);
+ return true;
}
const ipv4_address_t & ipv4_option_impl::get_address() const {
- return address_;
+ return address_;
}
void ipv4_option_impl::set_address(const ipv4_address_t &_address) {
- address_ = _address;
+ address_ = _address;
}
unsigned short ipv4_option_impl::get_port() const {
- return port_;
+ return port_;
}
void ipv4_option_impl::set_port(unsigned short _port) {
- port_ = _port;
+ port_ = _port;
}
bool ipv4_option_impl::is_udp() const {
- return is_udp_;
+ return is_udp_;
}
void ipv4_option_impl::set_udp(bool _is_udp) {
- is_udp_ = _is_udp;
+ is_udp_ = _is_udp;
}
bool ipv4_option_impl::is_multicast() const {
- return (type_ == option_type_e::IP4_MULTICAST);
+ return (type_ == option_type_e::IP4_MULTICAST);
}
bool ipv4_option_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = option_impl::serialize(_to);
- _to->serialize(&address_[0], address_.size());
- _to->serialize(protocol::reserved_byte);
- _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
- _to->serialize(port_);
- return is_successful;
+ bool is_successful = option_impl::serialize(_to);
+ _to->serialize(&address_[0], address_.size());
+ _to->serialize(protocol::reserved_byte);
+ _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
+ _to->serialize(port_);
+ return is_successful;
}
bool ipv4_option_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = option_impl::deserialize(_from);
- uint8_t its_reserved;
- _from->deserialize(address_.data(), 4);
- _from->deserialize(its_reserved);
- _from->deserialize(its_reserved);
- is_udp_ = (protocol::udp == its_reserved);
- _from->deserialize(port_);
- return is_successful;
+ bool is_successful = option_impl::deserialize(_from);
+ uint8_t its_reserved;
+ _from->deserialize(address_.data(), 4);
+ _from->deserialize(its_reserved);
+ _from->deserialize(its_reserved);
+ is_udp_ = (protocol::udp == its_reserved);
+ _from->deserialize(port_);
+ return is_successful;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/ipv6_option_impl.cpp b/implementation/service_discovery/src/ipv6_option_impl.cpp
index 1017f40..556045c 100755
--- a/implementation/service_discovery/src/ipv6_option_impl.cpp
+++ b/implementation/service_discovery/src/ipv6_option_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,70 +14,70 @@ namespace vsomeip {
namespace sd {
ipv6_option_impl::ipv6_option_impl(bool _is_multicast) {
- length_ = (1 + 16 + 1 + 1 + 2);
- type_ = (_is_multicast ? option_type_e::IP6_MULTICAST : option_type_e::IP6_ENDPOINT) ;
- is_udp_ = _is_multicast;
+ length_ = (1 + 16 + 1 + 1 + 2);
+ type_ = (
+ _is_multicast ?
+ option_type_e::IP6_MULTICAST : option_type_e::IP6_ENDPOINT);
+ is_udp_ = _is_multicast;
}
ipv6_option_impl::~ipv6_option_impl() {
}
bool ipv6_option_impl::operator ==(const option_impl &_other) const {
- if (_other.get_type() != option_type_e::IP6_ENDPOINT)
- return false;
+ if (_other.get_type() != option_type_e::IP6_ENDPOINT)
+ return false;
- const ipv6_option_impl& other
- = dynamic_cast< const ipv6_option_impl & >(_other);
+ const ipv6_option_impl& other =
+ dynamic_cast<const ipv6_option_impl &>(_other);
- return true; // TODO:
+ return true; // TODO:
}
const ipv6_address_t & ipv6_option_impl::get_address() const {
- return address_;
+ return address_;
}
void ipv6_option_impl::set_address(const ipv6_address_t &_address) {
- address_ = _address;
+ address_ = _address;
}
unsigned short ipv6_option_impl::get_port() const {
- return port_;
+ return port_;
}
void ipv6_option_impl::set_port(unsigned short _port) {
- port_ = _port;
+ port_ = _port;
}
bool ipv6_option_impl::is_udp() const {
- return is_udp_;
+ return is_udp_;
}
void ipv6_option_impl::set_udp(bool _is_udp) {
- is_udp_ = _is_udp;
+ is_udp_ = _is_udp;
}
bool ipv6_option_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = option_impl::serialize(_to);
- _to->serialize(&address_[0], address_.size());
- _to->serialize(protocol::reserved_byte);
- _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
- _to->serialize(port_);
- return is_successful;
+ bool is_successful = option_impl::serialize(_to);
+ _to->serialize(&address_[0], address_.size());
+ _to->serialize(protocol::reserved_byte);
+ _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
+ _to->serialize(port_);
+ return is_successful;
}
bool ipv6_option_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = option_impl::deserialize(_from);
- uint8_t its_reserved;
- _from->deserialize(address_.data(), 16);
- _from->deserialize(its_reserved);
- _from->deserialize(its_reserved);
- is_udp_ = (protocol::udp == its_reserved);
- _from->deserialize(port_);
- return is_successful;
+ bool is_successful = option_impl::deserialize(_from);
+ uint8_t its_reserved;
+ _from->deserialize(address_.data(), 16);
+ _from->deserialize(its_reserved);
+ _from->deserialize(its_reserved);
+ is_udp_ = (protocol::udp == its_reserved);
+ _from->deserialize(port_);
+ return is_successful;
}
} // namespace sd
} // namespace vsomeip
-
-
diff --git a/implementation/service_discovery/src/load_balancing_option_impl.cpp b/implementation/service_discovery/src/load_balancing_option_impl.cpp
index feea545..47a5b70 100755
--- a/implementation/service_discovery/src/load_balancing_option_impl.cpp
+++ b/implementation/service_discovery/src/load_balancing_option_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,61 +11,62 @@ namespace vsomeip {
namespace sd {
load_balancing_option_impl::load_balancing_option_impl() {
- length_ = 1 + 2 + 2;
- type_ = option_type_e::LOAD_BALANCING;
- priority_ = 0;
- weight_ = 0;
+ length_ = 1 + 2 + 2;
+ type_ = option_type_e::LOAD_BALANCING;
+ priority_ = 0;
+ weight_ = 0;
}
load_balancing_option_impl::~load_balancing_option_impl() {
}
bool load_balancing_option_impl::operator ==(const option_impl &_other) const {
- if (_other.get_type() != option_type_e::LOAD_BALANCING)
- return false;
+ if (_other.get_type() != option_type_e::LOAD_BALANCING)
+ return false;
- const load_balancing_option_impl& other
- = dynamic_cast< const load_balancing_option_impl & >(_other);
+ const load_balancing_option_impl& other =
+ dynamic_cast<const load_balancing_option_impl &>(_other);
- return (priority_ == other.priority_
- && weight_ == other.weight_);
+ return (priority_ == other.priority_ && weight_ == other.weight_);
}
priority_t load_balancing_option_impl::get_priority() const {
- return priority_;
+ return priority_;
}
void load_balancing_option_impl::set_priority(priority_t _priority) {
- priority_ = _priority;
+ priority_ = _priority;
}
weight_t load_balancing_option_impl::get_weight() const {
- return weight_;
+ return weight_;
}
void load_balancing_option_impl::set_weight(weight_t _weight) {
- weight_ = _weight;
+ weight_ = _weight;
}
bool load_balancing_option_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = option_impl::serialize(_to);
- is_successful = is_successful && _to->serialize(static_cast< uint16_t >(priority_));
- is_successful = is_successful && _to->serialize(static_cast< uint16_t >(weight_));
- return is_successful;
+ bool is_successful = option_impl::serialize(_to);
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint16_t>(priority_));
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint16_t>(weight_));
+ return is_successful;
}
bool load_balancing_option_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = option_impl::deserialize(_from);
+ bool is_successful = option_impl::deserialize(_from);
- uint16_t tmp_priority = 0;
- is_successful = is_successful && _from->deserialize(tmp_priority);
- priority_ = static_cast< priority_t >(tmp_priority);
+ uint16_t tmp_priority = 0;
+ is_successful = is_successful && _from->deserialize(tmp_priority);
+ priority_ = static_cast<priority_t>(tmp_priority);
- uint16_t tmp_weight = 0;
- is_successful = is_successful && _from->deserialize(tmp_weight);
- weight_ = static_cast< weight_t >(tmp_weight);
+ uint16_t tmp_weight = 0;
+ is_successful = is_successful && _from->deserialize(tmp_weight);
+ weight_ = static_cast<weight_t>(tmp_weight);
- return is_successful;
+ return is_successful;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/message_element_impl.cpp b/implementation/service_discovery/src/message_element_impl.cpp
index bb7a319..6577115 100755
--- a/implementation/service_discovery/src/message_element_impl.cpp
+++ b/implementation/service_discovery/src/message_element_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -10,15 +9,15 @@ namespace vsomeip {
namespace sd {
message_element_impl::message_element_impl() {
- owner_ = 0;
+ owner_ = 0;
}
message_impl * message_element_impl::get_owning_message() const {
- return owner_;
+ return owner_;
}
void message_element_impl::set_owning_message(message_impl *_owner) {
- owner_ = _owner;
+ owner_ = _owner;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/message_impl.cpp b/implementation/service_discovery/src/message_impl.cpp
index 31da16b..6736b50 100755
--- a/implementation/service_discovery/src/message_impl.cpp
+++ b/implementation/service_discovery/src/message_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -28,301 +27,314 @@ namespace vsomeip {
namespace sd {
message_impl::message_impl() {
- header_.service_ = 0xFFFF;
- header_.method_ = 0x8100;
- header_.protocol_version_ = 0x01;
- flags_ = 0x00;
+ header_.service_ = 0xFFFF;
+ header_.method_ = 0x8100;
+ header_.protocol_version_ = 0x01;
+ flags_ = 0x00;
}
message_impl::~message_impl() {
}
length_t message_impl::get_length() const {
- length_t current_length = VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_SD_DATA_SIZE;
- current_length += (entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
- for (size_t i = 0; i < options_.size(); ++i) {
- current_length += (options_[i]->get_length() + VSOMEIP_SOMEIP_SD_OPTION_HEADER_SIZE);
- }
- return current_length;
+ length_t current_length = VSOMEIP_SOMEIP_HEADER_SIZE
+ + VSOMEIP_SOMEIP_SD_DATA_SIZE;
+ current_length += (entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
+ for (size_t i = 0; i < options_.size(); ++i) {
+ current_length += (options_[i]->get_length()
+ + VSOMEIP_SOMEIP_SD_OPTION_HEADER_SIZE);
+ }
+ return current_length;
}
#define VSOMEIP_REBOOT_FLAG 0x80
bool message_impl::get_reboot_flag() const {
- return ((flags_ & VSOMEIP_REBOOT_FLAG) != 0);
+ return ((flags_ & VSOMEIP_REBOOT_FLAG) != 0);
}
void message_impl::set_reboot_flag(bool _is_set) {
- if (_is_set)
- flags_ |= VSOMEIP_REBOOT_FLAG;
- else
- flags_ &= ~VSOMEIP_REBOOT_FLAG;
+ if (_is_set)
+ flags_ |= VSOMEIP_REBOOT_FLAG;
+ else
+ flags_ &= ~VSOMEIP_REBOOT_FLAG;
}
#define VSOMEIP_UNICAST_FLAG 0x40
bool message_impl::get_unicast_flag() const {
- return ((flags_ & VSOMEIP_UNICAST_FLAG) != 0);
+ return ((flags_ & VSOMEIP_UNICAST_FLAG) != 0);
}
void message_impl::set_unicast_flag(bool _is_set) {
- if (_is_set)
- flags_ |= VSOMEIP_UNICAST_FLAG;
- else
- flags_ &= ~VSOMEIP_UNICAST_FLAG;
+ if (_is_set)
+ flags_ |= VSOMEIP_UNICAST_FLAG;
+ else
+ flags_ &= ~VSOMEIP_UNICAST_FLAG;
}
void message_impl::set_length(length_t _length) {
}
-std::shared_ptr< eventgroupentry_impl > message_impl::create_eventgroup_entry() {
- std::shared_ptr< eventgroupentry_impl > its_entry(std::make_shared< eventgroupentry_impl>());
- //TODO: throw OutOfMemoryException if allocation fails
- its_entry->set_owning_message(this);
- entries_.push_back(its_entry);
- return its_entry;
+std::shared_ptr<eventgroupentry_impl> message_impl::create_eventgroup_entry() {
+ std::shared_ptr < eventgroupentry_impl
+ > its_entry(std::make_shared<eventgroupentry_impl>());
+ //TODO: throw OutOfMemoryException if allocation fails
+ its_entry->set_owning_message(this);
+ entries_.push_back(its_entry);
+ return its_entry;
}
-std::shared_ptr< serviceentry_impl > message_impl::create_service_entry() {
- std::shared_ptr< serviceentry_impl > its_entry(std::make_shared< serviceentry_impl >());
- //TODO: throw OutOfMemoryException if allocation fails
- its_entry->set_owning_message(this);
- entries_.push_back(its_entry);
- return its_entry;
+std::shared_ptr<serviceentry_impl> message_impl::create_service_entry() {
+ std::shared_ptr < serviceentry_impl
+ > its_entry(std::make_shared<serviceentry_impl>());
+ //TODO: throw OutOfMemoryException if allocation fails
+ its_entry->set_owning_message(this);
+ entries_.push_back(its_entry);
+ return its_entry;
}
-std::shared_ptr< configuration_option_impl > message_impl::create_configuration_option() {
- std::shared_ptr< configuration_option_impl > its_option(std::make_shared< configuration_option_impl >());
- //TODO: throw OutOfMemoryException if allocation fails
- its_option->set_owning_message(this);
- options_.push_back(its_option);
- return its_option;
+std::shared_ptr<configuration_option_impl> message_impl::create_configuration_option() {
+ std::shared_ptr < configuration_option_impl
+ > its_option(std::make_shared<configuration_option_impl>());
+ //TODO: throw OutOfMemoryException if allocation fails
+ its_option->set_owning_message(this);
+ options_.push_back(its_option);
+ return its_option;
}
-std::shared_ptr< ipv4_option_impl > message_impl::create_ipv4_option(bool _is_multicast) {
- std::shared_ptr< ipv4_option_impl > its_option(std::make_shared< ipv4_option_impl >(_is_multicast));
- //TODO: throw OutOfMemoryException if allocation fails
- its_option->set_owning_message(this);
- options_.push_back(its_option);
- return its_option;
+std::shared_ptr<ipv4_option_impl> message_impl::create_ipv4_option(
+ bool _is_multicast) {
+ std::shared_ptr < ipv4_option_impl
+ > its_option(std::make_shared < ipv4_option_impl > (_is_multicast));
+ //TODO: throw OutOfMemoryException if allocation fails
+ its_option->set_owning_message(this);
+ options_.push_back(its_option);
+ return its_option;
}
-std::shared_ptr< ipv6_option_impl > message_impl::create_ipv6_option(bool _is_multicast) {
- std::shared_ptr< ipv6_option_impl > its_option(std::make_shared< ipv6_option_impl >(_is_multicast));
- //TODO: throw OutOfMemoryException if allocation fails
- its_option->set_owning_message(this);
- options_.push_back(its_option);
- return its_option;
+std::shared_ptr<ipv6_option_impl> message_impl::create_ipv6_option(
+ bool _is_multicast) {
+ std::shared_ptr < ipv6_option_impl
+ > its_option(std::make_shared < ipv6_option_impl > (_is_multicast));
+ //TODO: throw OutOfMemoryException if allocation fails
+ its_option->set_owning_message(this);
+ options_.push_back(its_option);
+ return its_option;
}
-std::shared_ptr< load_balancing_option_impl > message_impl::create_load_balancing_option() {
- std::shared_ptr< load_balancing_option_impl > its_option(std::make_shared< load_balancing_option_impl >());
- //TODO: throw OutOfMemoryException if allocation fails
- its_option->set_owning_message(this);
- options_.push_back(its_option);
- return its_option;
+std::shared_ptr<load_balancing_option_impl> message_impl::create_load_balancing_option() {
+ std::shared_ptr < load_balancing_option_impl
+ > its_option(std::make_shared<load_balancing_option_impl>());
+ //TODO: throw OutOfMemoryException if allocation fails
+ its_option->set_owning_message(this);
+ options_.push_back(its_option);
+ return its_option;
}
-std::shared_ptr< protection_option_impl > message_impl::create_protection_option() {
- std::shared_ptr< protection_option_impl > its_option(std::make_shared< protection_option_impl >());
- //TODO: throw OutOfMemoryException if allocation fails
- its_option->set_owning_message(this);
- options_.push_back(its_option);
- return its_option;
+std::shared_ptr<protection_option_impl> message_impl::create_protection_option() {
+ std::shared_ptr < protection_option_impl
+ > its_option(std::make_shared<protection_option_impl>());
+ //TODO: throw OutOfMemoryException if allocation fails
+ its_option->set_owning_message(this);
+ options_.push_back(its_option);
+ return its_option;
}
-const std::vector< std::shared_ptr< entry_impl > > & message_impl::get_entries() const {
- return entries_;
+const std::vector<std::shared_ptr<entry_impl> > & message_impl::get_entries() const {
+ return entries_;
}
-const std::vector< std::shared_ptr< option_impl > > & message_impl::get_options() const {
- return options_;
+const std::vector<std::shared_ptr<option_impl> > & message_impl::get_options() const {
+ return options_;
}
// TODO: throw exception to signal "OptionNotFound"
-int16_t message_impl::get_option_index(const std::shared_ptr< option_impl > &_option) const {
- int16_t i = 0;
+int16_t message_impl::get_option_index(
+ const std::shared_ptr<option_impl> &_option) const {
+ int16_t i = 0;
- while (i < options_.size()) {
- if (options_[i] == _option)
- return i;
- i++;
- }
+ while (i < options_.size()) {
+ if (options_[i] == _option)
+ return i;
+ i++;
+ }
- return -1;
+ return -1;
}
-std::shared_ptr< payload > message_impl::get_payload() const {
- return std::make_shared< payload_impl >();
+std::shared_ptr<payload> message_impl::get_payload() const {
+ return std::make_shared<payload_impl>();
}
-void message_impl::set_payload(std::shared_ptr< payload > _payload) {
+void message_impl::set_payload(std::shared_ptr<payload> _payload) {
}
bool message_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = header_.serialize(_to);
+ bool is_successful = header_.serialize(_to);
- is_successful = is_successful && _to->serialize(flags_);
- is_successful = is_successful
- && _to->serialize(protocol::reserved_long, true);
+ is_successful = is_successful && _to->serialize(flags_);
+ is_successful = is_successful
+ && _to->serialize(protocol::reserved_long, true);
- uint32_t entries_length = (entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
- is_successful = is_successful && _to->serialize(entries_length);
+ uint32_t entries_length = (entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
+ is_successful = is_successful && _to->serialize(entries_length);
- for (auto it = entries_.begin(); it != entries_.end(); ++it)
- is_successful = is_successful && (*it)->serialize(_to);
+ for (auto it = entries_.begin(); it != entries_.end(); ++it)
+ is_successful = is_successful && (*it)->serialize(_to);
- uint32_t options_length = 0;
- for (auto its_option : options_)
- options_length += its_option->get_length() + VSOMEIP_SOMEIP_SD_OPTION_HEADER_SIZE;
- is_successful = is_successful && _to->serialize(options_length);
+ uint32_t options_length = 0;
+ for (auto its_option : options_)
+ options_length += its_option->get_length()
+ + VSOMEIP_SOMEIP_SD_OPTION_HEADER_SIZE;
+ is_successful = is_successful && _to->serialize(options_length);
- for (auto its_option : options_)
- is_successful = is_successful && its_option->serialize(_to);
+ for (auto its_option : options_)
+ is_successful = is_successful && its_option->serialize(_to);
- return is_successful;
+ return is_successful;
}
bool message_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful;
-
- // header
- is_successful = header_.deserialize(_from);
-
- // flags
- is_successful = is_successful && _from->deserialize(flags_);
-
- // reserved
- uint32_t reserved;
- is_successful = is_successful && _from->deserialize(reserved, true);
-
- // entries
- uint32_t entries_length = 0;
- is_successful = is_successful && _from->deserialize(entries_length);
-
- // backup the current remaining length
- uint32_t save_remaining = _from->get_remaining();
-
- // set remaining bytes to length of entries array
- _from->set_remaining(entries_length);
-
- // deserialize the entries
- while (is_successful && _from->get_remaining()) {
- std::shared_ptr< entry_impl > its_entry(deserialize_entry(_from));
- if (its_entry) {
- entries_.push_back(its_entry);
- } else {
- is_successful = false;
- }
- }
-
- // set length to remaining bytes after entries array
- _from->set_remaining(save_remaining - entries_length);
-
- // deserialize the options
- uint32_t options_length = 0;
- is_successful = is_successful && _from->deserialize(options_length);
-
- while (is_successful && _from->get_remaining()) {
- std::shared_ptr< option_impl > its_option(deserialize_option(_from));
- if (its_option) {
- options_.push_back(its_option);
- } else {
- is_successful = false;
- }
- }
-
- return is_successful;
+ bool is_successful;
+
+ // header
+ is_successful = header_.deserialize(_from);
+
+ // flags
+ is_successful = is_successful && _from->deserialize(flags_);
+
+ // reserved
+ uint32_t reserved;
+ is_successful = is_successful && _from->deserialize(reserved, true);
+
+ // entries
+ uint32_t entries_length = 0;
+ is_successful = is_successful && _from->deserialize(entries_length);
+
+ // backup the current remaining length
+ uint32_t save_remaining = _from->get_remaining();
+
+ // set remaining bytes to length of entries array
+ _from->set_remaining(entries_length);
+
+ // deserialize the entries
+ while (is_successful && _from->get_remaining()) {
+ std::shared_ptr < entry_impl > its_entry(deserialize_entry(_from));
+ if (its_entry) {
+ entries_.push_back(its_entry);
+ } else {
+ is_successful = false;
+ }
+ }
+
+ // set length to remaining bytes after entries array
+ _from->set_remaining(save_remaining - entries_length);
+
+ // deserialize the options
+ uint32_t options_length = 0;
+ is_successful = is_successful && _from->deserialize(options_length);
+
+ while (is_successful && _from->get_remaining()) {
+ std::shared_ptr < option_impl > its_option(deserialize_option(_from));
+ if (its_option) {
+ options_.push_back(its_option);
+ } else {
+ is_successful = false;
+ }
+ }
+
+ return is_successful;
}
entry_impl * message_impl::deserialize_entry(vsomeip::deserializer *_from) {
- entry_impl *deserialized_entry = 0;
- uint8_t tmp_entry_type;
-
- if (_from->look_ahead(0, tmp_entry_type)) {
- entry_type_e deserialized_entry_type =
- static_cast< entry_type_e >(tmp_entry_type);
-
- switch (deserialized_entry_type) {
- case entry_type_e::FIND_SERVICE:
- case entry_type_e::OFFER_SERVICE:
- //case entry_type_e::STOP_OFFER_SERVICE:
- case entry_type_e::REQUEST_SERVICE:
- deserialized_entry = new serviceentry_impl;
- break;
-
- case entry_type_e::FIND_EVENT_GROUP:
- case entry_type_e::PUBLISH_EVENTGROUP:
- //case entry_type_e::STOP_PUBLISH_EVENTGROUP:
- case entry_type_e::SUBSCRIBE_EVENTGROUP:
- //case entry_type_e::STOP_SUBSCRIBE_EVENTGROUP:
- case entry_type_e::SUBSCRIBE_EVENTGROUP_ACK:
- //case entry_type_e::STOP_SUBSCRIBE_EVENTGROUP_ACK:
- deserialized_entry = new eventgroupentry_impl;
- break;
-
- default:
- break;
- };
-
- // deserialize object
- if (0 != deserialized_entry) {
- if (!deserialized_entry->deserialize(_from)) {
- delete deserialized_entry;
- deserialized_entry = 0;
- };
- }
- }
-
- return deserialized_entry;
+ entry_impl *deserialized_entry = 0;
+ uint8_t tmp_entry_type;
+
+ if (_from->look_ahead(0, tmp_entry_type)) {
+ entry_type_e deserialized_entry_type =
+ static_cast<entry_type_e>(tmp_entry_type);
+
+ switch (deserialized_entry_type) {
+ case entry_type_e::FIND_SERVICE:
+ case entry_type_e::OFFER_SERVICE:
+ //case entry_type_e::STOP_OFFER_SERVICE:
+ case entry_type_e::REQUEST_SERVICE:
+ deserialized_entry = new serviceentry_impl;
+ break;
+
+ case entry_type_e::FIND_EVENT_GROUP:
+ case entry_type_e::PUBLISH_EVENTGROUP:
+ //case entry_type_e::STOP_PUBLISH_EVENTGROUP:
+ case entry_type_e::SUBSCRIBE_EVENTGROUP:
+ //case entry_type_e::STOP_SUBSCRIBE_EVENTGROUP:
+ case entry_type_e::SUBSCRIBE_EVENTGROUP_ACK:
+ //case entry_type_e::STOP_SUBSCRIBE_EVENTGROUP_ACK:
+ deserialized_entry = new eventgroupentry_impl;
+ break;
+
+ default:
+ break;
+ };
+
+ // deserialize object
+ if (0 != deserialized_entry) {
+ if (!deserialized_entry->deserialize(_from)) {
+ delete deserialized_entry;
+ deserialized_entry = 0;
+ };
+ }
+ }
+
+ return deserialized_entry;
}
option_impl * message_impl::deserialize_option(vsomeip::deserializer *_from) {
- option_impl *deserialized_option = 0;
- uint8_t tmp_option_type;
-
- if (_from->look_ahead(2, tmp_option_type)) {
-
- option_type_e deserialized_option_type =
- static_cast< option_type_e >(tmp_option_type);
-
- switch (deserialized_option_type) {
-
- case option_type_e::CONFIGURATION:
- deserialized_option = new configuration_option_impl;
- break;
- case option_type_e::LOAD_BALANCING:
- deserialized_option = new load_balancing_option_impl;
- break;
- case option_type_e::PROTECTION:
- deserialized_option = new protection_option_impl;
- break;
- case option_type_e::IP4_ENDPOINT:
- deserialized_option = new ipv4_option_impl(false);
- break;
- case option_type_e::IP4_MULTICAST:
- deserialized_option = new ipv4_option_impl(true);
- break;
- case option_type_e::IP6_ENDPOINT:
- deserialized_option = new ipv6_option_impl(false);
- break;
- case option_type_e::IP6_MULTICAST:
- deserialized_option = new ipv6_option_impl(true);
- break;
-
- default:
- break;
- };
-
- // deserialize object
- if (0 != deserialized_option
- && !deserialized_option->deserialize(_from)) {
- delete deserialized_option;
- deserialized_option = 0;
- };
- }
-
- return deserialized_option;
+ option_impl *deserialized_option = 0;
+ uint8_t tmp_option_type;
+
+ if (_from->look_ahead(2, tmp_option_type)) {
+
+ option_type_e deserialized_option_type =
+ static_cast<option_type_e>(tmp_option_type);
+
+ switch (deserialized_option_type) {
+
+ case option_type_e::CONFIGURATION:
+ deserialized_option = new configuration_option_impl;
+ break;
+ case option_type_e::LOAD_BALANCING:
+ deserialized_option = new load_balancing_option_impl;
+ break;
+ case option_type_e::PROTECTION:
+ deserialized_option = new protection_option_impl;
+ break;
+ case option_type_e::IP4_ENDPOINT:
+ deserialized_option = new ipv4_option_impl(false);
+ break;
+ case option_type_e::IP4_MULTICAST:
+ deserialized_option = new ipv4_option_impl(true);
+ break;
+ case option_type_e::IP6_ENDPOINT:
+ deserialized_option = new ipv6_option_impl(false);
+ break;
+ case option_type_e::IP6_MULTICAST:
+ deserialized_option = new ipv6_option_impl(true);
+ break;
+
+ default:
+ break;
+ };
+
+ // deserialize object
+ if (0 != deserialized_option
+ && !deserialized_option->deserialize(_from)) {
+ delete deserialized_option;
+ deserialized_option = 0;
+ };
+ }
+
+ return deserialized_option;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/option_impl.cpp b/implementation/service_discovery/src/option_impl.cpp
index 92c3132..a9ac4a9 100755
--- a/implementation/service_discovery/src/option_impl.cpp
+++ b/implementation/service_discovery/src/option_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -13,44 +12,41 @@ namespace vsomeip {
namespace sd {
option_impl::option_impl() {
- length_ = 0;
- type_ = option_type_e::UNKNOWN;
+ length_ = 0;
+ type_ = option_type_e::UNKNOWN;
}
option_impl::~option_impl() {
}
bool option_impl::operator ==(const option_impl &_other) const {
- return false;
+ return false;
}
uint16_t option_impl::get_length() const {
- return length_;
+ return length_;
}
option_type_e option_impl::get_type() const {
- return type_;
+ return type_;
}
bool option_impl::serialize(vsomeip::serializer *_to) const {
- return (0 != _to
- && _to->serialize(length_)
- && _to->serialize(static_cast<uint8_t>(type_))
- && _to->serialize(protocol::reserved_byte));
+ return (0 != _to && _to->serialize(length_)
+ && _to->serialize(static_cast<uint8_t>(type_))
+ && _to->serialize(protocol::reserved_byte));
}
bool option_impl::deserialize(vsomeip::deserializer *_from) {
- uint8_t its_type, reserved;
- bool l_result = (0 != _from
- && _from->deserialize(length_)
- && _from->deserialize(its_type)
- && _from->deserialize(reserved));
+ uint8_t its_type, reserved;
+ bool l_result = (0 != _from && _from->deserialize(length_)
+ && _from->deserialize(its_type) && _from->deserialize(reserved));
- if (l_result) {
- type_ = static_cast< option_type_e >(its_type);
- }
+ if (l_result) {
+ type_ = static_cast<option_type_e>(its_type);
+ }
- return l_result;
+ return l_result;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/protection_option_impl.cpp b/implementation/service_discovery/src/protection_option_impl.cpp
index 15593a5..7197565 100755
--- a/implementation/service_discovery/src/protection_option_impl.cpp
+++ b/implementation/service_discovery/src/protection_option_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,60 +11,62 @@ namespace vsomeip {
namespace sd {
protection_option_impl::protection_option_impl() {
- length_ = 1 + 4 + 4;
- type_ = option_type_e::PROTECTION;
- counter_ = 0;
- crc_ = 0;
+ length_ = 1 + 4 + 4;
+ type_ = option_type_e::PROTECTION;
+ counter_ = 0;
+ crc_ = 0;
}
protection_option_impl::~protection_option_impl() {
}
bool protection_option_impl::operator ==(const option_impl &_other) const {
- if (_other.get_type() != option_type_e::PROTECTION)
- return false;
+ if (_other.get_type() != option_type_e::PROTECTION)
+ return false;
- const protection_option_impl& other
- = dynamic_cast< const protection_option_impl & >(_other);
+ const protection_option_impl& other =
+ dynamic_cast<const protection_option_impl &>(_other);
- return (counter_ == other.counter_ && crc_ == other.crc_);
+ return (counter_ == other.counter_ && crc_ == other.crc_);
}
alive_counter_t protection_option_impl::get_alive_counter() const {
- return counter_;
+ return counter_;
}
void protection_option_impl::set_alive_counter(alive_counter_t _counter) {
- counter_ = _counter;
+ counter_ = _counter;
}
crc_t protection_option_impl::get_crc() const {
- return crc_;
+ return crc_;
}
void protection_option_impl::set_crc(crc_t _crc) {
- crc_ = _crc;
+ crc_ = _crc;
}
bool protection_option_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = option_impl::serialize(_to);
- is_successful = is_successful && _to->serialize(static_cast< uint32_t >(counter_));
- is_successful = is_successful && _to->serialize(static_cast< uint32_t >(crc_));
- return is_successful;
+ bool is_successful = option_impl::serialize(_to);
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint32_t>(counter_));
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint32_t>(crc_));
+ return is_successful;
}
bool protection_option_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = option_impl::deserialize(_from);
+ bool is_successful = option_impl::deserialize(_from);
- uint32_t its_alive_counter = 0;
- is_successful = is_successful && _from->deserialize(its_alive_counter);
- counter_ = static_cast< alive_counter_t >(its_alive_counter);
+ uint32_t its_alive_counter = 0;
+ is_successful = is_successful && _from->deserialize(its_alive_counter);
+ counter_ = static_cast<alive_counter_t>(its_alive_counter);
- uint32_t its_crc = 0;
- is_successful = is_successful && _from->deserialize(its_crc);
- crc_ = static_cast< crc_t >(its_crc);
+ uint32_t its_crc = 0;
+ is_successful = is_successful && _from->deserialize(its_crc);
+ crc_ = static_cast<crc_t>(its_crc);
- return is_successful;
+ return is_successful;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/request.cpp b/implementation/service_discovery/src/request.cpp
index 2637a3f..8673822 100644
--- a/implementation/service_discovery/src/request.cpp
+++ b/implementation/service_discovery/src/request.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -10,34 +9,32 @@ namespace vsomeip {
namespace sd {
request::request(major_version_t _major, minor_version_t _minor, ttl_t _ttl)
- : major_(_major),
- minor_(_minor),
- ttl_(_ttl) {
+ : major_(_major), minor_(_minor), ttl_(_ttl) {
}
major_version_t request::get_major() const {
- return major_;
+ return major_;
}
void request::set_major(major_version_t _major) {
- major_ = _major;
+ major_ = _major;
}
minor_version_t request::get_minor() const {
- return minor_;
+ return minor_;
}
void request::set_minor(minor_version_t _minor) {
- minor_ = _minor;
+ minor_ = _minor;
}
ttl_t request::get_ttl() const {
- return ttl_;
+ return ttl_;
}
void request::set_ttl(ttl_t _ttl) {
- ttl_ = _ttl;
+ ttl_ = _ttl;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/runtime.cpp b/implementation/service_discovery/src/runtime.cpp
index d642cf1..f7d1a4f 100644
--- a/implementation/service_discovery/src/runtime.cpp
+++ b/implementation/service_discovery/src/runtime.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,22 +6,40 @@
#include "../include/runtime_impl.hpp"
#include "../../configuration/include/internal.hpp"
-vsomeip::sd::runtime * VSOMEIP_SD_RUNTIME_SYMBOL;
-
-static void init_vsomeip_sd() __attribute__((constructor));
-static void init_vsomeip_sd() {
- VSOMEIP_SD_RUNTIME_SYMBOL = vsomeip::sd::runtime::get();
+#ifdef WIN32
+extern "C"
+{
+ __declspec(dllexport) std::shared_ptr<vsomeip::sd::runtime> VSOMEIP_SD_RUNTIME_SYMBOL;
+}
+#else
+std::shared_ptr<vsomeip::sd::runtime> VSOMEIP_SD_RUNTIME_SYMBOL;
+#endif
+
+#ifdef WIN32
+#define CCALL __cdecl
+#pragma section(".CRT$XCU",read)
+#define INITIALIZER(f) \
+ static void __cdecl f(void); \
+ __declspec(allocate(".CRT$XCU")) void(__cdecl*f##_)(void) = f; \
+ static void __cdecl f(void)
+#else
+#define CCALL
+#define INITIALIZER(f) \
+ static void f(void) __attribute__((constructor)); \
+ static void f(void)
+#endif
+
+INITIALIZER(init_vsomeip_sd) {
+ VSOMEIP_SD_RUNTIME_SYMBOL = vsomeip::sd::runtime::get();
}
namespace vsomeip {
namespace sd {
-runtime * runtime::get() {
- return runtime_impl::get();
+std::shared_ptr<runtime> runtime::get() {
+ return runtime_impl::get();
}
} // namespace sd
} // namespace vsomeip
-
-
diff --git a/implementation/service_discovery/src/runtime_impl.cpp b/implementation/service_discovery/src/runtime_impl.cpp
index 6a88d42..f626cb3 100644
--- a/implementation/service_discovery/src/runtime_impl.cpp
+++ b/implementation/service_discovery/src/runtime_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -16,30 +15,33 @@
namespace vsomeip {
namespace sd {
-runtime * runtime_impl::get() {
- static runtime_impl the_runtime;
- return &the_runtime;
+std::shared_ptr<runtime> runtime_impl::get() {
+ static std::shared_ptr<runtime> the_runtime =
+ std::make_shared<runtime_impl>();
+ return the_runtime;
}
runtime_impl::~runtime_impl() {
}
-std::shared_ptr< service_discovery > runtime_impl::create_service_discovery(service_discovery_host *_host) const {
- return std::make_shared< service_discovery_impl >(_host);
+std::shared_ptr<service_discovery> runtime_impl::create_service_discovery(
+ service_discovery_host *_host) const {
+ return std::make_shared < service_discovery_impl > (_host);
}
-std::shared_ptr< message_impl > runtime_impl::create_message() const {
- std::shared_ptr< message_impl > its_message = std::make_shared< message_impl >();
- its_message->set_service(VSOMEIP_SD_SERVICE);
- its_message->set_instance(VSOMEIP_SD_INSTANCE);
- its_message->set_method(VSOMEIP_SD_METHOD);
- its_message->set_client(VSOMEIP_SD_CLIENT);
- // session must be set dynamically
- its_message->set_protocol_version(protocol_version);
- its_message->set_interface_version(interface_version);
- its_message->set_message_type(message_type);
- its_message->set_return_code(return_code);
- return its_message;
+std::shared_ptr<message_impl> runtime_impl::create_message() const {
+ std::shared_ptr < message_impl > its_message =
+ std::make_shared<message_impl>();
+ its_message->set_service(VSOMEIP_SD_SERVICE);
+ its_message->set_instance(VSOMEIP_SD_INSTANCE);
+ its_message->set_method(VSOMEIP_SD_METHOD);
+ its_message->set_client(VSOMEIP_SD_CLIENT);
+ // session must be set dynamically
+ its_message->set_protocol_version(protocol_version);
+ its_message->set_interface_version(interface_version);
+ its_message->set_message_type(message_type);
+ its_message->set_return_code(return_code);
+ return its_message;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/service_discovery_fsm.cpp b/implementation/service_discovery/src/service_discovery_fsm.cpp
index c6c3147..8b2cb17 100644
--- a/implementation/service_discovery/src/service_discovery_fsm.cpp
+++ b/implementation/service_discovery/src/service_discovery_fsm.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -10,6 +9,7 @@
#include <vsomeip/configuration.hpp>
#include <vsomeip/logger.hpp>
+#include "../include/defines.hpp"
#include "../include/service_discovery.hpp"
#include "../include/service_discovery_fsm.hpp"
@@ -21,118 +21,149 @@ namespace sd {
///////////////////////////////////////////////////////////////////////////////
namespace _sd {
-fsm::fsm(service_discovery_fsm *_fsm):
- fsm_(_fsm),
- fsm_base(_fsm->get_io()),
- is_up_(true) {
+fsm::fsm(boost::asio::io_service &_io)
+ : fsm_base(_io), is_up_(true) {
}
fsm::~fsm() {
}
+void fsm::set_fsm(std::shared_ptr<service_discovery_fsm> _fsm) {
+ fsm_ = _fsm;
+}
+
void fsm::timer_expired(const boost::system::error_code &_error) {
- if (!_error) {
- process_event(ev_timeout());
- }
+ if (!_error) {
+ std::shared_ptr<service_discovery_fsm> its_fsm = fsm_.lock();
+ if (its_fsm)
+ its_fsm->process(ev_timeout());
+ }
}
///////////////////////////////////////////////////////////////////////////////
// State "Inactive"
///////////////////////////////////////////////////////////////////////////////
-inactive::inactive(my_context context): sc::state< inactive, fsm >(context) {
- VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::inactive";
- outermost_context().run_ = 0;
+inactive::inactive(my_context context)
+ : sc::state<inactive, fsm>(context) {
+ std::shared_ptr < service_discovery_fsm > fsm =
+ outermost_context().fsm_.lock();
+ if (fsm) {
+ VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::inactive";
+ outermost_context().run_ = 0;
+ }
}
sc::result inactive::react(const ev_none &_event) {
- if (outermost_context().is_up_) {
- return transit< active >();
- }
+ if (outermost_context().is_up_) {
+ return transit<active>();
+ }
- return discard_event();
+ return discard_event();
}
sc::result inactive::react(const ev_status_change &_event) {
- outermost_context().is_up_ = _event.is_up_;
- if (outermost_context().is_up_) {
- return transit< active >();
- }
+ outermost_context().is_up_ = _event.is_up_;
+ if (outermost_context().is_up_) {
+ return transit<active>();
+ }
- return discard_event();
+ return discard_event();
}
///////////////////////////////////////////////////////////////////////////////
// State "Active"
///////////////////////////////////////////////////////////////////////////////
-active::active(my_context _context): sc::state< active, fsm, initial >(_context) {
- VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::active";
+active::active(my_context _context)
+ : sc::state<active, fsm, initial>(_context) {
+ std::shared_ptr < service_discovery_fsm > fsm =
+ outermost_context().fsm_.lock();
+ if (fsm) {
+ VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active";
+ }
}
active::~active() {
}
sc::result active::react(const ev_status_change &_event) {
- outermost_context().stop_timer();
- outermost_context().is_up_ = _event.is_up_;
- if (!outermost_context().is_up_)
- return transit< inactive >();
+ outermost_context().stop_timer();
+ outermost_context().is_up_ = _event.is_up_;
+ if (!outermost_context().is_up_)
+ return transit<inactive>();
- return discard_event();
+ return discard_event();
}
///////////////////////////////////////////////////////////////////////////////
// State "Active.Initial"
///////////////////////////////////////////////////////////////////////////////
-initial::initial(my_context _context): sc::state< initial, active >(_context) {
- VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::active.initial";
- outermost_context().start_timer(outermost_context().initial_delay_);
+initial::initial(my_context _context)
+ : sc::state<initial, active>(_context) {
+ std::shared_ptr < service_discovery_fsm > fsm =
+ outermost_context().fsm_.lock();
+ if (fsm) {
+ VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active.initial";
+ outermost_context().start_timer(outermost_context().initial_delay_);
+ }
}
sc::result initial::react(const ev_timeout &_event) {
- return transit< repeat >();
+ return transit<repeat>();
}
///////////////////////////////////////////////////////////////////////////////
// State "Active.Repeat"
///////////////////////////////////////////////////////////////////////////////
-repeat::repeat(my_context _context): sc::state< repeat, active >(_context) {
- VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::active.repeat";
- uint32_t its_timeout = (outermost_context().repetition_base_delay_ << outermost_context().run_);
- outermost_context().run_ ++;
- outermost_context().fsm_->send(false);
- outermost_context().start_timer(its_timeout);
+repeat::repeat(my_context _context)
+ : sc::state<repeat, active>(_context) {
+ std::shared_ptr < service_discovery_fsm > fsm =
+ outermost_context().fsm_.lock();
+ if (fsm) {
+ VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active.repeat";
+ uint32_t its_timeout = (outermost_context().repetition_base_delay_
+ << outermost_context().run_);
+ outermost_context().run_++;
+ fsm->send(false);
+ outermost_context().start_timer(its_timeout);
+ }
}
sc::result repeat::react(const ev_timeout &_event) {
- if (outermost_context().run_ < outermost_context().repetition_max_)
- return transit< repeat >();
+ if (outermost_context().run_ < outermost_context().repetition_max_)
+ return transit<repeat>();
- return transit< announce >();
+ return transit<announce>();
}
sc::result repeat::react(const ev_find_service &_event) {
- return discard_event();
+ return discard_event();
}
///////////////////////////////////////////////////////////////////////////////
// State "Active.Announce"
///////////////////////////////////////////////////////////////////////////////
-announce::announce(my_context _context): sc::state< announce, active >(_context) {
- VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::active.announce";
- outermost_context().start_timer(outermost_context().cyclic_offer_delay_);
- outermost_context().fsm_->send(true);
+announce::announce(my_context _context)
+ : sc::state<announce, active>(_context) {
+ std::shared_ptr < service_discovery_fsm > fsm =
+ outermost_context().fsm_.lock();
+ if (fsm) {
+ VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active.announce";
+ outermost_context().start_timer(
+ outermost_context().cyclic_offer_delay_);
+ fsm->send(true);
+ }
}
sc::result announce::react(const ev_timeout &_event) {
- return transit< announce >();
+ return transit<announce>();
}
sc::result announce::react(const ev_find_service &_event) {
- return discard_event();
+ return discard_event();
}
sc::result announce::react(const ev_offer_change &_event) {
- return transit< announce >();
+ return transit<announce>();
}
} // namespace _sd
@@ -140,58 +171,79 @@ sc::result announce::react(const ev_offer_change &_event) {
///////////////////////////////////////////////////////////////////////////////
// Interface
///////////////////////////////////////////////////////////////////////////////
-service_discovery_fsm::service_discovery_fsm(
- const std::string &_name, service_discovery *_discovery)
- : name_(_name), discovery_(_discovery), fsm_(std::make_shared< _sd::fsm >(this)) {
-
- std::shared_ptr< configuration > its_configuration
- = discovery_->get_configuration();
-
- int32_t its_min_initial_delay = its_configuration->get_min_initial_delay(name_);
- int32_t its_max_initial_delay = its_configuration->get_max_initial_delay(name_);
-
- VSOMEIP_TRACE << "Inital delay ["
- << its_min_initial_delay << ", " << its_max_initial_delay << "]";
-
- boost::random::mt19937 its_generator;
- boost::random::uniform_int_distribution<> its_distribution(
- its_min_initial_delay,
- its_max_initial_delay
- );
- fsm_->initial_delay_ = its_distribution(its_generator);
-
- fsm_->repetition_base_delay_
- = its_configuration->get_repetition_base_delay(name_);
- fsm_->repetition_max_
- = its_configuration->get_repetition_max(name_);
-
- fsm_->cyclic_offer_delay_
- = its_configuration->get_cyclic_offer_delay(name_);
-
- VSOMEIP_INFO << "SD configuration ["
- << fsm_->initial_delay_ << ":"
- << fsm_->repetition_base_delay_ << ":"
- << (int)fsm_->repetition_max_ << ":"
- << fsm_->cyclic_offer_delay_ << "]";
+service_discovery_fsm::service_discovery_fsm(const std::string &_name,
+ std::shared_ptr<service_discovery> _discovery)
+ : name_(_name), discovery_(_discovery), fsm_(
+ std::make_shared < _sd::fsm > (_discovery->get_io())) {
+
+ std::shared_ptr < service_discovery > discovery = discovery_.lock();
+ if (discovery) {
+ std::shared_ptr < configuration > its_configuration =
+ discovery->get_configuration();
+
+ int32_t its_min_initial_delay =
+ its_configuration->get_min_initial_delay(name_);
+ if (its_min_initial_delay < 0)
+ its_min_initial_delay = VSOMEIP_SD_DEFAULT_MIN_INITIAL_DELAY;
+
+ int32_t its_max_initial_delay =
+ its_configuration->get_max_initial_delay(name_);
+ if (its_max_initial_delay <= 0)
+ its_max_initial_delay = VSOMEIP_SD_DEFAULT_MAX_INITIAL_DELAY;
+
+ if (its_min_initial_delay > its_max_initial_delay) {
+ int32_t tmp_initial_delay = its_min_initial_delay;
+ its_min_initial_delay = its_max_initial_delay;
+ its_max_initial_delay = its_min_initial_delay;
+ }
+
+ VSOMEIP_TRACE << "Inital delay [" << its_min_initial_delay << ", "
+ << its_max_initial_delay << "]";
+
+ boost::random::mt19937 its_generator;
+ boost::random::uniform_int_distribution<> its_distribution(
+ its_min_initial_delay, its_max_initial_delay);
+ fsm_->initial_delay_ = its_distribution(its_generator);
+
+ fsm_->repetition_base_delay_ =
+ its_configuration->get_repetition_base_delay(name_);
+ if (fsm_->repetition_base_delay_ <= 0)
+ fsm_->repetition_base_delay_
+ = VSOMEIP_SD_DEFAULT_REPETITION_BASE_DELAY;
+ fsm_->repetition_max_ = its_configuration->get_repetition_max(name_);
+ if (fsm_->repetition_max_ <= 0)
+ fsm_->repetition_max_ = VSOMEIP_SD_DEFAULT_REPETITION_MAX;
+
+ fsm_->cyclic_offer_delay_ =
+ its_configuration->get_cyclic_offer_delay(name_);
+ if (fsm_->cyclic_offer_delay_ <= 0)
+ fsm_->cyclic_offer_delay_ = VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY;
+
+ VSOMEIP_INFO << "SD configuration [" << fsm_->initial_delay_ << ":"
+ << fsm_->repetition_base_delay_ << ":"
+ << (int) fsm_->repetition_max_ << ":"
+ << fsm_->cyclic_offer_delay_ << "]";
+ } else {
+ VSOMEIP_ERROR << "SD initialization failed";
+ }
}
const std::string & service_discovery_fsm::get_name() const {
- return name_;
-}
-
-boost::asio::io_service & service_discovery_fsm::get_io() {
- return discovery_->get_io();
+ return name_;
}
void service_discovery_fsm::start() {
- fsm_->initiate();
+ fsm_->set_fsm(shared_from_this());
+ fsm_->initiate();
}
void service_discovery_fsm::stop() {
}
void service_discovery_fsm::send(bool _is_announcing) {
- discovery_->send(name_, _is_announcing);
+ std::shared_ptr < service_discovery > discovery = discovery_.lock();
+ if (discovery)
+ discovery->send(name_, _is_announcing);
}
} // namespace sd
diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp
index 1efbdf1..42d93b6 100644
--- a/implementation/service_discovery/src/service_discovery_impl.cpp
+++ b/implementation/service_discovery/src/service_discovery_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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,698 +34,788 @@
namespace vsomeip {
namespace sd {
-service_discovery_impl::service_discovery_impl(service_discovery_host *_host) :
- host_(_host), io_(_host->get_io()), default_(
- std::make_shared<service_discovery_fsm>("default", this)), serializer_(
- std::make_shared<serializer>()), deserializer_(
- std::make_shared<deserializer>()) {
+service_discovery_impl::service_discovery_impl(service_discovery_host *_host)
+ : host_(_host), io_(_host->get_io()), serializer_(
+ std::make_shared<serializer>()), deserializer_(
+ std::make_shared<deserializer>()) {
}
service_discovery_impl::~service_discovery_impl() {
}
std::shared_ptr<configuration> service_discovery_impl::get_configuration() const {
- return host_->get_configuration();
+ return host_->get_configuration();
}
boost::asio::io_service & service_discovery_impl::get_io() {
- return io_;
+ return io_;
}
void service_discovery_impl::init() {
- std::shared_ptr<configuration> its_configuration =
- host_->get_configuration();
- if (its_configuration) {
- unicast_ = its_configuration->get_unicast();
-
- std::set<std::string> its_servicegroups =
- its_configuration->get_servicegroups();
- for (auto its_group : its_servicegroups) {
- if (its_group != "default"
- && its_configuration->is_local_servicegroup(its_group)) {
- additional_[its_group] =
- std::make_shared<service_discovery_fsm>(its_group,
- this);
- }
- }
-
- port_ = its_configuration->get_service_discovery_port();
- reliable_ = (its_configuration->get_service_discovery_protocol()
- == "tcp");
-
- serializer_->create_data(reliable_ ?
- VSOMEIP_MAX_TCP_MESSAGE_SIZE :
- VSOMEIP_MAX_UDP_MESSAGE_SIZE);
-
- host_->create_service_discovery_endpoint(
- its_configuration->get_service_discovery_multicast(), port_,
- reliable_);
-
- } else {
- VSOMEIP_ERROR<< "SD: no configuration found!";
- }
+ runtime_ = runtime::get();
+ default_ = std::make_shared < service_discovery_fsm
+ > ("default", shared_from_this());
+
+ std::shared_ptr < configuration > its_configuration =
+ host_->get_configuration();
+ if (its_configuration) {
+ unicast_ = its_configuration->get_unicast();
+
+ std::set < std::string > its_servicegroups =
+ its_configuration->get_servicegroups();
+ for (auto its_group : its_servicegroups) {
+ if (its_group != "default"
+ && its_configuration->is_local_servicegroup(its_group)) {
+ additional_[its_group] = std::make_shared
+ < service_discovery_fsm
+ > (its_group, shared_from_this());
+ }
+ }
+
+ port_ = its_configuration->get_service_discovery_port();
+ reliable_ = (its_configuration->get_service_discovery_protocol()
+ == "tcp");
+
+ serializer_->create_data(
+ reliable_ ?
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE :
+ VSOMEIP_MAX_UDP_MESSAGE_SIZE);
+
+ host_->create_service_discovery_endpoint(
+ its_configuration->get_service_discovery_multicast(), port_,
+ reliable_);
+
+ } else {
+ VSOMEIP_ERROR << "SD: no configuration found!";
+ }
}
void service_discovery_impl::start() {
- default_->start();
- for (auto &its_group : additional_) {
- its_group.second->start();
- }
-
- default_->process(ev_none());
- for (auto &its_group : additional_) {
- its_group.second->process(ev_none());
- }
+ default_->start();
+ for (auto &its_group : additional_) {
+ its_group.second->start();
+ }
+
+ default_->process(ev_none());
+ for (auto &its_group : additional_) {
+ its_group.second->process(ev_none());
+ }
}
void service_discovery_impl::stop() {
}
void service_discovery_impl::request_service(service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl) {
- auto find_service = requested_.find(_service);
- if (find_service != requested_.end()) {
- auto find_instance = find_service->second.find(_instance);
- if (find_instance != find_service->second.end()) {
- // TODO: check version and report errors
- } else {
- find_service->second[_instance] = std::make_shared<request>(_major,
- _minor, _ttl);
- }
- } else {
- requested_[_service][_instance] = std::make_shared<request>(_major,
- _minor, _ttl);
- }
+ instance_t _instance, major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl) {
+ std::lock_guard<std::mutex> its_lock(requested_mutex_);
+ auto find_service = requested_.find(_service);
+ if (find_service != requested_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end()) {
+ // TODO: check version and report errors
+ } else {
+ find_service->second[_instance] = std::make_shared < request
+ > (_major, _minor, _ttl);
+ }
+ } else {
+ requested_[_service][_instance] = std::make_shared < request
+ > (_major, _minor, _ttl);
+ }
}
void service_discovery_impl::release_service(service_t _service,
- instance_t _instance) {
- auto find_service = requested_.find(_service);
- if (find_service != requested_.end()) {
- find_service->second.erase(_instance);
- }
+ instance_t _instance) {
+ auto find_service = requested_.find(_service);
+ if (find_service != requested_.end()) {
+ find_service->second.erase(_instance);
+ }
}
void service_discovery_impl::subscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl) {
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_eventgroup = found_instance->second.find(_eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- if (found_eventgroup->second->get_major() == _major) {
- found_eventgroup->second->set_ttl(_ttl);
- } else {
- VSOMEIP_ERROR<< "Subscriptions to different versions of the same "
- "service instance are not supported!";
- }
- return;
- }
- }
- }
-
- std::shared_ptr<endpoint> its_reliable = host_->find_remote_client(_service,
- _instance, true);
- std::shared_ptr<endpoint> its_unreliable = host_->find_remote_client(
- _service, _instance, false);
- std::shared_ptr<subscription> its_subscription = std::make_shared<
- subscription>(_major, _ttl, its_reliable, its_unreliable);
- subscribed_[_service][_instance][_eventgroup] = its_subscription;
+ eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client) {
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ auto found_client = found_eventgroup->second.find(_client);
+ if (found_client != found_eventgroup->second.end()) {
+ if (found_client->second->get_major() == _major) {
+ found_client->second->set_ttl(_ttl);
+ } else {
+ VSOMEIP_ERROR
+ << "Subscriptions to different versions of the same "
+ "service instance are not supported!";
+ }
+ return;
+ }
+ }
+ }
+ }
+
+ std::shared_ptr < endpoint > its_reliable = host_->find_or_create_remote_client(
+ _service, _instance, true, _client);
+ std::shared_ptr < endpoint > its_unreliable = host_->find_or_create_remote_client(
+ _service, _instance, false, _client);
+ std::shared_ptr < subscription > its_subscription = std::make_shared
+ < subscription > (_major, _ttl, its_reliable, its_unreliable, _client);
+ subscribed_[_service][_instance][_eventgroup][_client] = its_subscription;
+
+ if (!its_subscription->is_acknowleged()) {
+ bool has_address(false);
+ boost::asio::ip::address its_address;
+
+ std::shared_ptr<endpoint> its_endpoint
+ = host_->find_or_create_remote_client(_service, _instance, false, _client);
+
+ if (its_endpoint) {
+ has_address = its_endpoint->get_remote_address(its_address);
+ its_subscription->set_endpoint(its_endpoint, false);
+ }
+
+ its_endpoint = host_->find_or_create_remote_client(_service, _instance, true, _client);
+ if (its_endpoint) {
+ has_address = has_address || its_endpoint->get_remote_address(its_address);
+ its_subscription->set_endpoint(its_endpoint, true);
+ }
+
+ if (has_address) {
+ std::shared_ptr < runtime > its_runtime = runtime_.lock();
+ if (!its_runtime)
+ return;
+
+ std::shared_ptr < message_impl > its_message
+ = its_runtime->create_message();
+
+ // TODO: consume major & ttl
+ insert_subscription(its_message, _service, _instance, _eventgroup,
+ its_subscription);
+ its_message->set_session(get_session(its_address));
+
+ serializer_->serialize(its_message.get());
+
+ if (host_->send_to(
+ std::make_shared<endpoint_definition>(
+ its_address, port_, reliable_),
+ serializer_->get_data(),
+ serializer_->get_size())) {
+ increment_session(its_address);
+ }
+ serializer_->reset();
+ }
+ }
}
void service_discovery_impl::unsubscribe(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) {
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_eventgroup = found_instance->second.find(_eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- found_eventgroup->second->set_ttl(0); // is read once and removed afterwards!
- }
- }
- }
+ instance_t _instance, eventgroup_t _eventgroup) {
+ // TODO: add client_id!!!
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ for (auto its_client : found_eventgroup->second) {
+ its_client.second->set_ttl(0); // is read once and removed afterwards!
+ }
+ }
+ }
+ }
}
session_t service_discovery_impl::get_session(
- const boost::asio::ip::address &_address) {
- session_t its_session;
- auto found_session = sessions_.find(_address);
- if (found_session == sessions_.end()) {
- its_session = sessions_[_address] = 1;
- } else {
- its_session = found_session->second;
- }
- return its_session;
+ const boost::asio::ip::address &_address) {
+ session_t its_session;
+ auto found_session = sessions_.find(_address);
+ if (found_session == sessions_.end()) {
+ its_session = sessions_[_address] = 1;
+ } else {
+ its_session = found_session->second;
+ }
+ return its_session;
}
void service_discovery_impl::increment_session(
- const boost::asio::ip::address &_address) {
- auto found_session = sessions_.find(_address);
- if (found_session != sessions_.end()) {
- found_session->second++;
- if (0 == found_session->second) {
- found_session->second++;
- // TODO: what about the reboot flag?
- }
- }
+ const boost::asio::ip::address &_address) {
+ auto found_session = sessions_.find(_address);
+ if (found_session != sessions_.end()) {
+ found_session->second++;
+ if (0 == found_session->second) {
+ found_session->second++;
+ // TODO: what about the reboot flag?
+ }
+ }
}
void service_discovery_impl::insert_option(
- std::shared_ptr<message_impl> &_message,
- std::shared_ptr<entry_impl> _entry,
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _is_reliable) {
- if (unicast_ == _address) {
- if (unicast_.is_v4()) {
- ipv4_address_t its_address = unicast_.to_v4().to_bytes();
- std::shared_ptr<ipv4_option_impl> its_option =
- _message->create_ipv4_option(false);
- if (its_option) {
- its_option->set_address(its_address);
- its_option->set_port(_port);
- its_option->set_udp(!_is_reliable);
- _entry->assign_option(its_option, 1);
- }
- } else {
- ipv6_address_t its_address = unicast_.to_v6().to_bytes();
- std::shared_ptr<ipv6_option_impl> its_option =
- _message->create_ipv6_option(false);
- if (its_option) {
- its_option->set_address(its_address);
- its_option->set_port(_port);
- its_option->set_udp(!_is_reliable);
- _entry->assign_option(its_option, 1);
- }
- }
- } else {
- if (_address.is_v4()) {
- ipv4_address_t its_address = _address.to_v4().to_bytes();
- std::shared_ptr<ipv4_option_impl> its_option =
- _message->create_ipv4_option(true);
- if (its_option) {
- its_option->set_address(its_address);
- its_option->set_port(_port);
- _entry->assign_option(its_option, 1);
- }
- } else {
- ipv6_address_t its_address = _address.to_v6().to_bytes();
- std::shared_ptr<ipv6_option_impl> its_option =
- _message->create_ipv6_option(true);
- if (its_option) {
- its_option->set_address(its_address);
- its_option->set_port(_port);
- _entry->assign_option(its_option, 1);
- }
- }
- }
+ std::shared_ptr<message_impl> &_message,
+ std::shared_ptr<entry_impl> _entry,
+ const boost::asio::ip::address &_address, uint16_t _port,
+ bool _is_reliable) {
+ if (unicast_ == _address) {
+ if (unicast_.is_v4()) {
+ ipv4_address_t its_address = unicast_.to_v4().to_bytes();
+ std::shared_ptr < ipv4_option_impl > its_option =
+ _message->create_ipv4_option(false);
+ if (its_option) {
+ its_option->set_address(its_address);
+ its_option->set_port(_port);
+ its_option->set_udp(!_is_reliable);
+ _entry->assign_option(its_option, 1);
+ }
+ } else {
+ ipv6_address_t its_address = unicast_.to_v6().to_bytes();
+ std::shared_ptr < ipv6_option_impl > its_option =
+ _message->create_ipv6_option(false);
+ if (its_option) {
+ its_option->set_address(its_address);
+ its_option->set_port(_port);
+ its_option->set_udp(!_is_reliable);
+ _entry->assign_option(its_option, 1);
+ }
+ }
+ } else {
+ if (_address.is_v4()) {
+ ipv4_address_t its_address = _address.to_v4().to_bytes();
+ std::shared_ptr < ipv4_option_impl > its_option =
+ _message->create_ipv4_option(true);
+ if (its_option) {
+ its_option->set_address(its_address);
+ its_option->set_port(_port);
+ _entry->assign_option(its_option, 1);
+ }
+ } else {
+ ipv6_address_t its_address = _address.to_v6().to_bytes();
+ std::shared_ptr < ipv6_option_impl > its_option =
+ _message->create_ipv6_option(true);
+ if (its_option) {
+ its_option->set_address(its_address);
+ its_option->set_port(_port);
+ _entry->assign_option(its_option, 1);
+ }
+ }
+ }
}
void service_discovery_impl::insert_find_entries(
- std::shared_ptr<message_impl> &_message, requests_t &_requests) {
- for (auto its_service : _requests) {
- for (auto its_instance : its_service.second) {
- auto its_request = its_instance.second;
- std::shared_ptr<serviceentry_impl> its_entry =
- _message->create_service_entry();
- if (its_entry) {
- its_entry->set_type(entry_type_e::FIND_SERVICE);
- its_entry->set_service(its_service.first);
- its_entry->set_instance(its_instance.first);
- its_entry->set_major_version(its_request->get_major());
- its_entry->set_minor_version(its_request->get_minor());
- its_entry->set_ttl(its_request->get_ttl());
- } else {
- VSOMEIP_ERROR<< "Failed to create service entry!";
- }
- }
- }
+ std::shared_ptr<message_impl> &_message, requests_t &_requests) {
+ std::lock_guard<std::mutex> its_lock(requested_mutex_);
+ for (auto its_service : _requests) {
+ for (auto its_instance : its_service.second) {
+ auto its_request = its_instance.second;
+ std::shared_ptr < serviceentry_impl > its_entry =
+ _message->create_service_entry();
+ if (its_entry) {
+ its_entry->set_type(entry_type_e::FIND_SERVICE);
+ its_entry->set_service(its_service.first);
+ its_entry->set_instance(its_instance.first);
+ its_entry->set_major_version(its_request->get_major());
+ its_entry->set_minor_version(its_request->get_minor());
+ its_entry->set_ttl(its_request->get_ttl());
+ } else {
+ VSOMEIP_ERROR << "Failed to create service entry!";
+ }
+ }
+ }
}
void service_discovery_impl::insert_offer_entries(
- std::shared_ptr<message_impl> &_message, services_t &_services) {
- for (auto its_service : _services) {
- for (auto its_instance : its_service.second) {
- auto its_info = its_instance.second;
- std::shared_ptr<serviceentry_impl> its_entry =
- _message->create_service_entry();
- if (its_entry) {
- its_entry->set_type(entry_type_e::OFFER_SERVICE);
- its_entry->set_service(its_service.first);
- its_entry->set_instance(its_instance.first);
- its_entry->set_major_version(its_info->get_major());
- its_entry->set_minor_version(its_info->get_minor());
- its_entry->set_ttl(its_info->get_ttl());
-
- std::shared_ptr<endpoint> its_endpoint = its_info->get_endpoint(
- true);
- if (its_endpoint) {
- insert_option(_message, its_entry, unicast_,
- its_endpoint->get_port(), true);
- if (0 == its_info->get_ttl()) {
- host_->del_routing_info(its_service.first,
- its_instance.first,
- true);
- }
- }
-
- its_endpoint = its_info->get_endpoint(false);
- if (its_endpoint) {
- insert_option(_message, its_entry, unicast_,
- its_endpoint->get_port(), false);
- if (0 == its_info->get_ttl()) {
- host_->del_routing_info(its_service.first,
- its_instance.first,
- false);
- }
- }
- } else {
- VSOMEIP_ERROR<< "Failed to create service entry.";
- }
- }
- }
+ std::shared_ptr<message_impl> &_message, services_t &_services) {
+ for (auto its_service : _services) {
+ for (auto its_instance : its_service.second) {
+ auto its_info = its_instance.second;
+ std::shared_ptr < serviceentry_impl > its_entry =
+ _message->create_service_entry();
+ if (its_entry) {
+ its_entry->set_type(entry_type_e::OFFER_SERVICE);
+ its_entry->set_service(its_service.first);
+ its_entry->set_instance(its_instance.first);
+ its_entry->set_major_version(its_info->get_major());
+ its_entry->set_minor_version(its_info->get_minor());
+ its_entry->set_ttl(its_info->get_ttl());
+
+ std::shared_ptr < endpoint > its_endpoint =
+ its_info->get_endpoint(true);
+ if (its_endpoint) {
+ insert_option(_message, its_entry, unicast_,
+ its_endpoint->get_local_port(), true);
+ if (0 == its_info->get_ttl()) {
+ host_->del_routing_info(its_service.first,
+ its_instance.first, true);
+ }
+ }
+
+ its_endpoint = its_info->get_endpoint(false);
+ if (its_endpoint) {
+ insert_option(_message, its_entry, unicast_,
+ its_endpoint->get_local_port(), false);
+ if (0 == its_info->get_ttl()) {
+ host_->del_routing_info(its_service.first,
+ its_instance.first, false);
+ }
+ }
+ } else {
+ VSOMEIP_ERROR << "Failed to create service entry.";
+ }
+ }
+ }
}
void service_discovery_impl::insert_subscription(
- std::shared_ptr<message_impl> &_message, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<subscription> &_subscription) {
- std::shared_ptr<eventgroupentry_impl> its_entry =
- _message->create_eventgroup_entry();
- its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP);
- its_entry->set_service(_service);
- its_entry->set_instance(_instance);
- its_entry->set_eventgroup(_eventgroup);
- its_entry->set_major_version(_subscription->get_major());
- its_entry->set_ttl(_subscription->get_ttl());
- std::shared_ptr<endpoint> its_endpoint = _subscription->get_endpoint(true);
- if (its_endpoint) {
- insert_option(_message, its_entry, unicast_, its_endpoint->get_port(),
- true);
- }
- its_endpoint = _subscription->get_endpoint(false);
- if (its_endpoint) {
- insert_option(_message, its_entry, unicast_, its_endpoint->get_port(),
- false);
- }
+ std::shared_ptr<message_impl> &_message, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<subscription> &_subscription) {
+ std::shared_ptr < eventgroupentry_impl > its_entry =
+ _message->create_eventgroup_entry();
+ its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP);
+ its_entry->set_service(_service);
+ its_entry->set_instance(_instance);
+ its_entry->set_eventgroup(_eventgroup);
+ its_entry->set_major_version(_subscription->get_major());
+ its_entry->set_ttl(_subscription->get_ttl());
+ std::shared_ptr < endpoint > its_endpoint = _subscription->get_endpoint(
+ true);
+ if (its_endpoint) {
+ insert_option(_message, its_entry, unicast_, its_endpoint->get_local_port(),
+ true);
+ }
+ its_endpoint = _subscription->get_endpoint(false);
+ if (its_endpoint) {
+ insert_option(_message, its_entry, unicast_, its_endpoint->get_local_port(),
+ false);
+ }
}
void service_discovery_impl::insert_subscription_ack(
- std::shared_ptr<message_impl> &_message, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<eventgroupinfo> &_info) {
- std::shared_ptr<eventgroupentry_impl> its_entry =
- _message->create_eventgroup_entry();
- its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP_ACK);
- its_entry->set_service(_service);
- its_entry->set_instance(_instance);
- its_entry->set_eventgroup(_eventgroup);
- its_entry->set_major_version(_info->get_major());
- its_entry->set_ttl(_info->get_ttl());
-
- boost::asio::ip::address its_address;
- uint16_t its_port;
- if (_info->get_multicast(its_address, its_port)) {
- insert_option(_message, its_entry, its_address, its_port, false);
- }
+ std::shared_ptr<message_impl> &_message, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<eventgroupinfo> &_info) {
+ std::shared_ptr < eventgroupentry_impl > its_entry =
+ _message->create_eventgroup_entry();
+ its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP_ACK);
+ its_entry->set_service(_service);
+ its_entry->set_instance(_instance);
+ its_entry->set_eventgroup(_eventgroup);
+ its_entry->set_major_version(_info->get_major());
+ its_entry->set_ttl(_info->get_ttl());
+
+ boost::asio::ip::address its_address;
+ uint16_t its_port;
+ if (_info->get_multicast(its_address, its_port)) {
+ insert_option(_message, its_entry, its_address, its_port, false);
+ }
}
void service_discovery_impl::send(const std::string &_name,
-bool _is_announcing) {
- std::shared_ptr<message_impl> its_message =
- runtime::get()->create_message();
-
- // TODO: optimize building of SD message (common options, utilize the two runs)
-
- // If we are the default group and not in main phase, include "FindOffer"-entries
- if (_name == "default" && !_is_announcing) {
- insert_find_entries(its_message, requested_);
- }
-
- // Always include the "OfferService"-entries for the service group
- services_t its_offers = host_->get_offered_services(_name);
- insert_offer_entries(its_message, its_offers);
-
- // Serialize and send
- if (its_message->get_entries().size() > 0) {
- its_message->set_session(get_session(unicast_));
- if (host_->send(VSOMEIP_SD_CLIENT, its_message, true, false)) {
- increment_session(unicast_);
- }
- }
+ bool _is_announcing) {
+
+ std::shared_ptr < runtime > its_runtime = runtime_.lock();
+ if (!its_runtime)
+ return;
+
+ std::shared_ptr < message_impl > its_message =
+ its_runtime->create_message();
+
+ // TODO: optimize building of SD message (common options, utilize the two runs)
+
+ // If we are the default group and not in main phase, include "FindOffer"-entries
+ if (_name == "default" && !_is_announcing) {
+ insert_find_entries(its_message, requested_);
+ }
+
+ // Always include the "OfferService"-entries for the service group
+ services_t its_offers = host_->get_offered_services(_name);
+ insert_offer_entries(its_message, its_offers);
+
+ // Serialize and send
+ if (its_message->get_entries().size() > 0) {
+ its_message->set_session(get_session(unicast_));
+ if (host_->send(VSOMEIP_SD_CLIENT, its_message, true)) {
+ increment_session (unicast_);
+ }
+ }
}
// Interface endpoint_host
void service_discovery_impl::on_message(const byte_t *_data, length_t _length) {
#if 0
- std::stringstream msg;
- msg << "sdi::on_message: ";
- for (length_t i = 0; i < _length; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "sdi::on_message: ";
+ for (length_t i = 0; i < _length; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- deserializer_->set_data(_data, _length);
- std::shared_ptr<message_impl> its_message(
- deserializer_->deserialize_sd_message());
- if (its_message) {
- std::vector<std::shared_ptr<option_impl> > its_options =
- its_message->get_options();
- for (auto its_entry : its_message->get_entries()) {
- if (its_entry->is_service_entry()) {
- std::shared_ptr<serviceentry_impl> its_service_entry =
- std::dynamic_pointer_cast<serviceentry_impl>(its_entry);
- process_serviceentry(its_service_entry, its_options);
- } else {
- std::shared_ptr<eventgroupentry_impl> its_eventgroup_entry =
- std::dynamic_pointer_cast<eventgroupentry_impl>(
- its_entry);
- process_eventgroupentry(its_eventgroup_entry, its_options);
- }
- }
- }
+ deserializer_->set_data(_data, _length);
+ std::shared_ptr < message_impl
+ > its_message(deserializer_->deserialize_sd_message());
+ if (its_message) {
+ std::vector < std::shared_ptr<option_impl> > its_options =
+ its_message->get_options();
+ for (auto its_entry : its_message->get_entries()) {
+ if (its_entry->is_service_entry()) {
+ std::shared_ptr < serviceentry_impl > its_service_entry =
+ std::dynamic_pointer_cast < serviceentry_impl
+ > (its_entry);
+ process_serviceentry(its_service_entry, its_options);
+ } else {
+ std::shared_ptr < eventgroupentry_impl > its_eventgroup_entry =
+ std::dynamic_pointer_cast < eventgroupentry_impl
+ > (its_entry);
+ process_eventgroupentry(its_eventgroup_entry, its_options);
+ }
+ }
+ }
}
void service_discovery_impl::on_offer_change(const std::string &_name) {
- if (_name == "default") {
- default_->process(ev_offer_change());
- } else {
- auto found_group = additional_.find(_name);
- if (found_group != additional_.end()) {
- found_group->second->process(ev_offer_change());
- }
- }
+ if (_name == "default") {
+ default_->process(ev_offer_change());
+ } else {
+ auto found_group = additional_.find(_name);
+ if (found_group != additional_.end()) {
+ found_group->second->process(ev_offer_change());
+ }
+ }
}
// Entry processing
void service_discovery_impl::process_serviceentry(
- std::shared_ptr<serviceentry_impl> &_entry,
- const std::vector<std::shared_ptr<option_impl> > &_options) {
- service_t its_service = _entry->get_service();
- instance_t its_instance = _entry->get_instance();
- major_version_t its_major = _entry->get_major_version();
- minor_version_t its_minor = _entry->get_minor_version();
- ttl_t its_ttl = _entry->get_ttl();
-
- for (auto i : { 1, 2 }) {
- for (auto its_index : _entry->get_options(i)) {
- std::vector<byte_t> its_option_address;
- uint16_t its_option_port = VSOMEIP_INVALID_PORT;
- std::shared_ptr<option_impl> its_option = _options[its_index];
- switch (its_option->get_type()) {
- case option_type_e::IP4_ENDPOINT: {
- std::shared_ptr<ipv4_option_impl> its_ipv4_option =
- std::dynamic_pointer_cast<ipv4_option_impl>(its_option);
-
- boost::asio::ip::address_v4 its_ipv4_address(
- its_ipv4_option->get_address());
- boost::asio::ip::address its_address(its_ipv4_address);
- its_option_port = its_ipv4_option->get_port();
-
- handle_service_availability(its_service, its_instance,
- its_major, its_minor, its_ttl, its_address,
- its_option_port, !its_ipv4_option->is_udp());
- break;
- }
- case option_type_e::IP6_ENDPOINT: {
- std::shared_ptr<ipv6_option_impl> its_ipv6_option =
- std::dynamic_pointer_cast<ipv6_option_impl>(its_option);
-
- boost::asio::ip::address_v6 its_ipv6_address(
- its_ipv6_option->get_address());
- boost::asio::ip::address its_address(its_ipv6_address);
- its_option_port = its_ipv6_option->get_port();
-
- handle_service_availability(its_service, its_instance,
- its_major, its_minor, its_ttl, its_address,
- its_option_port, !its_ipv6_option->is_udp());
- break;
- }
- case option_type_e::IP4_MULTICAST:
- case option_type_e::IP6_MULTICAST:
- VSOMEIP_ERROR<< "Invalid service option (Multicast)";
- break;
- default:
- VSOMEIP_WARNING << "Unsupported service option";
- break;
- }
- }
- }
+ std::shared_ptr<serviceentry_impl> &_entry,
+ const std::vector<std::shared_ptr<option_impl> > &_options) {
+ service_t its_service = _entry->get_service();
+ instance_t its_instance = _entry->get_instance();
+ major_version_t its_major = _entry->get_major_version();
+ minor_version_t its_minor = _entry->get_minor_version();
+ ttl_t its_ttl = _entry->get_ttl();
+
+ for (auto i : { 1, 2 }) {
+ for (auto its_index : _entry->get_options(i)) {
+ std::vector < byte_t > its_option_address;
+ uint16_t its_option_port = VSOMEIP_INVALID_PORT;
+ std::shared_ptr < option_impl > its_option = _options[its_index];
+ switch (its_option->get_type()) {
+ case option_type_e::IP4_ENDPOINT: {
+ std::shared_ptr < ipv4_option_impl > its_ipv4_option =
+ std::dynamic_pointer_cast < ipv4_option_impl
+ > (its_option);
+
+ boost::asio::ip::address_v4 its_ipv4_address(
+ its_ipv4_option->get_address());
+ boost::asio::ip::address its_address(its_ipv4_address);
+ its_option_port = its_ipv4_option->get_port();
+
+ handle_service_availability(its_service, its_instance,
+ its_major, its_minor, its_ttl, its_address,
+ its_option_port, !its_ipv4_option->is_udp());
+ break;
+ }
+ case option_type_e::IP6_ENDPOINT: {
+ std::shared_ptr < ipv6_option_impl > its_ipv6_option =
+ std::dynamic_pointer_cast < ipv6_option_impl
+ > (its_option);
+
+ boost::asio::ip::address_v6 its_ipv6_address(
+ its_ipv6_option->get_address());
+ boost::asio::ip::address its_address(its_ipv6_address);
+ its_option_port = its_ipv6_option->get_port();
+
+ handle_service_availability(its_service, its_instance,
+ its_major, its_minor, its_ttl, its_address,
+ its_option_port, !its_ipv6_option->is_udp());
+ break;
+ }
+ case option_type_e::IP4_MULTICAST:
+ case option_type_e::IP6_MULTICAST:
+ VSOMEIP_ERROR << "Invalid service option (Multicast)";
+ break;
+ default:
+ VSOMEIP_WARNING << "Unsupported service option";
+ break;
+ }
+ }
+ }
}
void service_discovery_impl::process_eventgroupentry(
- std::shared_ptr<eventgroupentry_impl> &_entry,
- const std::vector<std::shared_ptr<option_impl> > &_options) {
- service_t its_service = _entry->get_service();
- instance_t its_instance = _entry->get_instance();
- eventgroup_t its_eventgroup = _entry->get_eventgroup();
- entry_type_e its_type = _entry->get_type();
- major_version_t its_major = _entry->get_major_version();
- ttl_t its_ttl = _entry->get_ttl();
-
- boost::asio::ip::address its_reliable_address;
- uint16_t its_reliable_port = VSOMEIP_INVALID_PORT;
- boost::asio::ip::address its_unreliable_address;
- uint16_t its_unreliable_port = VSOMEIP_INVALID_PORT;
-
- for (auto i : { 1, 2 }) {
- for (auto its_index : _entry->get_options(i)) {
- std::vector<byte_t> its_option_address;
- std::shared_ptr<option_impl> its_option = _options[its_index];
- switch (its_option->get_type()) {
- case option_type_e::IP4_ENDPOINT: {
- if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) {
- std::shared_ptr<ipv4_option_impl> its_ipv4_option =
- std::dynamic_pointer_cast<ipv4_option_impl>(
- its_option);
-
- boost::asio::ip::address_v4 its_ipv4_address(
- its_ipv4_option->get_address());
-
- // TODO: add error handling (port already set) here
- if (its_ipv4_option->is_udp()) {
- its_unreliable_address = its_ipv4_address;
- its_unreliable_port = its_ipv4_option->get_port();
- } else {
- its_reliable_address = its_ipv4_address;
- its_reliable_port = its_ipv4_option->get_port();
- }
- } else {
- VSOMEIP_ERROR<< "Invalid eventgroup option (IPv4 Endpoint)";
- }
- break;
- }
- case option_type_e::IP6_ENDPOINT: {
- if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) {
- std::shared_ptr<ipv6_option_impl> its_ipv6_option =
- std::dynamic_pointer_cast < ipv6_option_impl > (its_option);
-
- boost::asio::ip::address_v6 its_ipv6_address(
- its_ipv6_option->get_address());
-
- // TODO: add error handling (port already set) here
- if (its_ipv6_option->is_udp()) {
- its_unreliable_address = its_ipv6_address;
- its_unreliable_port = its_ipv6_option->get_port();
- } else {
- its_unreliable_address = its_ipv6_address;
- its_reliable_port = its_ipv6_option->get_port();
- }
- } else {
- VSOMEIP_ERROR << "Invalid eventgroup option (IPv6 Endpoint)";
- }
- break;
- }
- case option_type_e::IP4_MULTICAST:
- if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == _entry->get_type()) {
- std::shared_ptr<ipv4_option_impl> its_ipv4_option =
- std::dynamic_pointer_cast < ipv4_option_impl > (its_option);
-
- boost::asio::ip::address_v4 its_ipv4_address(
- its_ipv4_option->get_address());
-
- its_unreliable_address = its_ipv4_address;
- its_unreliable_port = its_ipv4_option->get_port();
- } else {
- VSOMEIP_ERROR << "Invalid eventgroup option (IPv4 Multicast)";
- }
- break;
- case option_type_e::IP6_MULTICAST:
- if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == _entry->get_type()) {
- std::shared_ptr<ipv6_option_impl> its_ipv6_option =
- std::dynamic_pointer_cast < ipv6_option_impl > (its_option);
-
- boost::asio::ip::address_v6 its_ipv6_address(
- its_ipv6_option->get_address());
-
- its_unreliable_address = its_ipv6_address;
- its_unreliable_port = its_ipv6_option->get_port();
- } else {
- VSOMEIP_ERROR << "Invalid eventgroup option (IPv6 Multicast)";
- }
- break;
- default:
- VSOMEIP_WARNING << "Unsupported eventgroup option";
- break;
- }
- }
-}
-
- if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) {
- handle_eventgroup_subscription(its_service, its_instance,
- its_eventgroup, its_major, its_ttl,
- (its_reliable_port != VSOMEIP_INVALID_PORT ?
- its_reliable_address : its_unreliable_address),
- its_reliable_port, its_unreliable_port);
- } else {
- handle_eventgroup_subscription_ack(its_service, its_instance,
- its_eventgroup, its_major, its_ttl, its_unreliable_address,
- its_unreliable_port);
- }
+ std::shared_ptr<eventgroupentry_impl> &_entry,
+ const std::vector<std::shared_ptr<option_impl> > &_options) {
+ service_t its_service = _entry->get_service();
+ instance_t its_instance = _entry->get_instance();
+ eventgroup_t its_eventgroup = _entry->get_eventgroup();
+ entry_type_e its_type = _entry->get_type();
+ major_version_t its_major = _entry->get_major_version();
+ ttl_t its_ttl = _entry->get_ttl();
+
+ boost::asio::ip::address its_reliable_address;
+ uint16_t its_reliable_port = VSOMEIP_INVALID_PORT;
+ boost::asio::ip::address its_unreliable_address;
+ uint16_t its_unreliable_port = VSOMEIP_INVALID_PORT;
+
+ for (auto i : { 1, 2 }) {
+ for (auto its_index : _entry->get_options(i)) {
+ std::vector < byte_t > its_option_address;
+ std::shared_ptr < option_impl > its_option = _options[its_index];
+ switch (its_option->get_type()) {
+ case option_type_e::IP4_ENDPOINT: {
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) {
+ std::shared_ptr < ipv4_option_impl > its_ipv4_option =
+ std::dynamic_pointer_cast < ipv4_option_impl
+ > (its_option);
+
+ boost::asio::ip::address_v4 its_ipv4_address(
+ its_ipv4_option->get_address());
+
+ // TODO: add error handling (port already set) here
+ if (its_ipv4_option->is_udp()) {
+ its_unreliable_address = its_ipv4_address;
+ its_unreliable_port = its_ipv4_option->get_port();
+ } else {
+ its_reliable_address = its_ipv4_address;
+ its_reliable_port = its_ipv4_option->get_port();
+ }
+ } else {
+ VSOMEIP_ERROR
+ << "Invalid eventgroup option (IPv4 Endpoint)";
+ }
+ break;
+ }
+ case option_type_e::IP6_ENDPOINT: {
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) {
+ std::shared_ptr < ipv6_option_impl > its_ipv6_option =
+ std::dynamic_pointer_cast < ipv6_option_impl
+ > (its_option);
+
+ boost::asio::ip::address_v6 its_ipv6_address(
+ its_ipv6_option->get_address());
+
+ // TODO: add error handling (port already set) here
+ if (its_ipv6_option->is_udp()) {
+ its_unreliable_address = its_ipv6_address;
+ its_unreliable_port = its_ipv6_option->get_port();
+ } else {
+ its_unreliable_address = its_ipv6_address;
+ its_reliable_port = its_ipv6_option->get_port();
+ }
+ } else {
+ VSOMEIP_ERROR
+ << "Invalid eventgroup option (IPv6 Endpoint)";
+ }
+ break;
+ }
+ case option_type_e::IP4_MULTICAST:
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK
+ == _entry->get_type()) {
+ std::shared_ptr < ipv4_option_impl > its_ipv4_option =
+ std::dynamic_pointer_cast < ipv4_option_impl
+ > (its_option);
+
+ boost::asio::ip::address_v4 its_ipv4_address(
+ its_ipv4_option->get_address());
+
+ its_unreliable_address = its_ipv4_address;
+ its_unreliable_port = its_ipv4_option->get_port();
+ } else {
+ VSOMEIP_ERROR
+ << "Invalid eventgroup option (IPv4 Multicast)";
+ }
+ break;
+ case option_type_e::IP6_MULTICAST:
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK
+ == _entry->get_type()) {
+ std::shared_ptr < ipv6_option_impl > its_ipv6_option =
+ std::dynamic_pointer_cast < ipv6_option_impl
+ > (its_option);
+
+ boost::asio::ip::address_v6 its_ipv6_address(
+ its_ipv6_option->get_address());
+
+ its_unreliable_address = its_ipv6_address;
+ its_unreliable_port = its_ipv6_option->get_port();
+ } else {
+ VSOMEIP_ERROR
+ << "Invalid eventgroup option (IPv6 Multicast)";
+ }
+ break;
+ default:
+ VSOMEIP_WARNING << "Unsupported eventgroup option";
+ break;
+ }
+ }
+ }
+
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) {
+ handle_eventgroup_subscription(its_service, its_instance,
+ its_eventgroup, its_major, its_ttl,
+ (its_reliable_port != VSOMEIP_INVALID_PORT ?
+ its_reliable_address : its_unreliable_address),
+ its_reliable_port, its_unreliable_port);
+ } else {
+ handle_eventgroup_subscription_ack(its_service, its_instance,
+ its_eventgroup, its_major, its_ttl, its_unreliable_address,
+ its_unreliable_port);
+ }
}
void service_discovery_impl::handle_service_availability(service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl, const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) {
-
- if (0 < _ttl) {
- host_->add_routing_info(_service, _instance, _major, _minor, _ttl,
- _address, _port, _reliable);
-
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- if (0 < found_instance->second.size()) {
- std::shared_ptr<message_impl> its_message =
- runtime::get()->create_message();
- for (auto its_eventgroup : found_instance->second) {
- std::shared_ptr<subscription> its_subscription(
- its_eventgroup.second);
- if (!its_subscription->is_acknowleged()) {
- its_subscription->set_endpoint(
- host_->find_remote_client(_service,
- _instance, true), true);
- its_subscription->set_endpoint(
- host_->find_remote_client(_service,
- _instance, false), false);
-
- // TODO: consume major & ttl
- insert_subscription(its_message, _service,
- _instance, its_eventgroup.first,
- its_subscription);
- }
- }
-
- if (0 < its_message->get_entries().size()) {
- its_message->set_session(get_session(_address));
- serializer_->serialize(its_message.get());
- if (host_->send_to(
- std::make_shared<endpoint_definition>(_address,
- port_, reliable_),
- serializer_->get_data(),
- serializer_->get_size())) {
- increment_session(_address);
- }
- serializer_->reset();
- }
- }
- }
- }
- } else {
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- for (auto &its_eventgroup : found_instance->second) {
- its_eventgroup.second->set_acknowledged(false);
- }
- }
- }
- host_->del_routing_info(_service, _instance, _reliable);
- }
+ instance_t _instance, major_version_t _major, minor_version_t _minor,
+ ttl_t _ttl, const boost::asio::ip::address &_address, uint16_t _port,
+ bool _reliable) {
+
+ std::shared_ptr < runtime > its_runtime = runtime_.lock();
+ if (!its_runtime)
+ return;
+
+ if (0 < _ttl) {
+ host_->add_routing_info(_service, _instance, _major, _minor, _ttl,
+ _address, _port, _reliable);
+
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ if (0 < found_instance->second.size()) {
+ std::shared_ptr < message_impl > its_message =
+ its_runtime->create_message();
+ for (auto its_eventgroup : found_instance->second) {
+ for (auto its_client : its_eventgroup.second) {
+ std::shared_ptr < subscription
+ > its_subscription(its_client.second);
+ if (!its_subscription->is_acknowleged()) {
+ its_subscription->set_endpoint(
+ host_->find_or_create_remote_client(_service,
+ _instance, true, its_client.first), true);
+ its_subscription->set_endpoint(
+ host_->find_or_create_remote_client(_service,
+ _instance, false, its_client.first), false);
+
+ // TODO: consume major & ttl
+ insert_subscription(its_message, _service,
+ _instance, its_eventgroup.first,
+ its_subscription);
+ }
+ }
+
+ }
+
+ if (0 < its_message->get_entries().size()) {
+ its_message->set_session(get_session(_address));
+ serializer_->serialize(its_message.get());
+ if (host_->send_to(
+ std::make_shared < endpoint_definition
+ > (_address, port_, reliable_),
+ serializer_->get_data(),
+ serializer_->get_size())) {
+ increment_session(_address);
+ }
+ serializer_->reset();
+ }
+ }
+ }
+ }
+ } else {
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ for (auto &its_eventgroup : found_instance->second) {
+ for (auto its_client : its_eventgroup.second) {
+ its_client.second->set_acknowledged(false);
+ }
+ }
+ }
+ }
+ host_->del_routing_info(_service, _instance, _reliable);
+ }
}
void service_discovery_impl::handle_eventgroup_subscription(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- ttl_t _ttl, const boost::asio::ip::address &_address,
- uint16_t _reliable_port, uint16_t _unreliable_port) {
- std::shared_ptr<message_impl> its_message =
- runtime::get()->create_message();
- if (its_message) {
- std::shared_ptr<eventgroupinfo> its_info = host_->find_eventgroup(
- _service, _instance, _eventgroup);
-
- bool is_nack(false);
- std::shared_ptr<endpoint_definition> its_subscriber;
- std::shared_ptr<endpoint_definition> its_target;
-
- // Could not find eventgroup --> send Nack
- if (!its_info || _major > its_info->get_major()
- || _ttl > its_info->get_ttl()) {
- its_info = std::make_shared<eventgroupinfo>(_major, 0);
- is_nack = true;
- } else {
- boost::asio::ip::address its_target_address;
- uint16_t its_target_port;
- if (VSOMEIP_INVALID_PORT != _unreliable_port) {
- its_subscriber = std::make_shared<endpoint_definition>(
- _address, _unreliable_port, false);
- if (!its_info->get_multicast(its_target_address,
- its_target_port)) {
- its_target = std::make_shared<endpoint_definition>(
- its_target_address, its_target_port, false);
- } else {
- its_target = its_subscriber;
- }
- } else {
- its_subscriber = std::make_shared<endpoint_definition>(
- _address, _reliable_port, true);
- its_target = its_subscriber;
- }
- }
-
- insert_subscription_ack(its_message,
- _service, _instance, _eventgroup, its_info);
-
- its_message->set_session(get_session(_address));
- serializer_->serialize(its_message.get());
- if (host_->send_to(
- std::make_shared<endpoint_definition>(_address, port_,
- reliable_), serializer_->get_data(),
- serializer_->get_size())) {
- increment_session(_address);
- }
- serializer_->reset();
-
- // Finally register the new subscriber and send him all the fields(!)
- if (!is_nack) {
- host_->on_subscribe(_service, _instance, _eventgroup,
- its_subscriber, its_target);
- }
- }
+ instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
+ ttl_t _ttl, const boost::asio::ip::address &_address,
+ uint16_t _reliable_port, uint16_t _unreliable_port) {
+
+ std::shared_ptr < runtime > its_runtime = runtime_.lock();
+ if (!its_runtime)
+ return;
+
+ std::shared_ptr < message_impl > its_message =
+ its_runtime->create_message();
+ if (its_message) {
+ std::shared_ptr < eventgroupinfo > its_info = host_->find_eventgroup(
+ _service, _instance, _eventgroup);
+
+ bool is_nack(false);
+ std::shared_ptr < endpoint_definition > its_subscriber;
+ std::shared_ptr < endpoint_definition > its_target;
+
+ // Could not find eventgroup --> send Nack
+ if (!its_info || _major > its_info->get_major()
+ || _ttl > its_info->get_ttl()) {
+ its_info = std::make_shared < eventgroupinfo > (_major, 0);
+ is_nack = true;
+ } else {
+ boost::asio::ip::address its_target_address;
+ uint16_t its_target_port;
+ if (VSOMEIP_INVALID_PORT != _unreliable_port) {
+ its_subscriber = std::make_shared < endpoint_definition
+ > (_address, _unreliable_port, false);
+ if (its_info->get_multicast(its_target_address,
+ its_target_port)) {
+ its_target = std::make_shared < endpoint_definition
+ > (its_target_address, its_target_port, false);
+ } else {
+ its_target = its_subscriber;
+ }
+ } else {
+ its_subscriber = std::make_shared < endpoint_definition
+ > (_address, _reliable_port, true);
+ its_target = its_subscriber;
+ }
+ }
+
+ insert_subscription_ack(its_message, _service, _instance, _eventgroup,
+ its_info);
+
+ its_message->set_session(get_session(_address));
+ serializer_->serialize(its_message.get());
+ if (host_->send_to(
+ std::make_shared < endpoint_definition
+ > (_address, port_, reliable_), serializer_->get_data(),
+ serializer_->get_size())) {
+ increment_session(_address);
+ }
+ serializer_->reset();
+
+ // Finally register the new subscriber and send him all the fields(!)
+ if (!is_nack) {
+ host_->on_subscribe(_service, _instance, _eventgroup,
+ its_subscriber, its_target);
+ }
+ }
}
void service_discovery_impl::handle_eventgroup_subscription_ack(
- service_t _service, instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl,
- const boost::asio::ip::address &_address, uint16_t _port) {
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- auto found_eventgroup = found_instance->second.find(_eventgroup);
- if (found_eventgroup != found_instance->second.end()) {
- found_eventgroup->second->set_acknowledged(true);
- if (_address.is_multicast()) {
- host_->on_subscribe_ack(_service, _instance, _address,
- _port);
- }
- }
- }
- }
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ major_version_t _major, ttl_t _ttl,
+ const boost::asio::ip::address &_address, uint16_t _port) {
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ for (auto its_client : found_eventgroup->second) {
+ its_client.second->set_acknowledged(true);
+ if (_address.is_multicast()) {
+ host_->on_subscribe_ack(_service, _instance, _address,
+ _port);
+ }
+ }
+
+ }
+ }
+ }
}
} // namespace sd
diff --git a/implementation/service_discovery/src/serviceentry_impl.cpp b/implementation/service_discovery/src/serviceentry_impl.cpp
index e7e8c1f..fe31703 100755
--- a/implementation/service_discovery/src/serviceentry_impl.cpp
+++ b/implementation/service_discovery/src/serviceentry_impl.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,46 +11,49 @@ namespace vsomeip {
namespace sd {
serviceentry_impl::serviceentry_impl() {
- minor_version_ = 0;
+ minor_version_ = 0;
}
serviceentry_impl::~serviceentry_impl() {
}
minor_version_t serviceentry_impl::get_minor_version() const {
- return minor_version_;
+ return minor_version_;
}
void serviceentry_impl::set_minor_version(minor_version_t _version) {
- minor_version_ = _version;
+ minor_version_ = _version;
}
bool serviceentry_impl::serialize(vsomeip::serializer *_to) const {
- bool is_successful = entry_impl::serialize(_to);
+ bool is_successful = entry_impl::serialize(_to);
- is_successful = is_successful && _to->serialize(static_cast<uint8_t>(major_version_));
- is_successful = is_successful && _to->serialize(static_cast<uint32_t>(ttl_), true);
- is_successful = is_successful && _to->serialize(static_cast<uint32_t>(minor_version_));
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint8_t>(major_version_));
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint32_t>(ttl_), true);
+ is_successful = is_successful
+ && _to->serialize(static_cast<uint32_t>(minor_version_));
- return is_successful;
+ return is_successful;
}
bool serviceentry_impl::deserialize(vsomeip::deserializer *_from) {
- bool is_successful = entry_impl::deserialize(_from);
+ bool is_successful = entry_impl::deserialize(_from);
- uint8_t tmp_major_version;
- is_successful = is_successful && _from->deserialize(tmp_major_version);
- major_version_ = static_cast< major_version_t >(tmp_major_version);
+ uint8_t tmp_major_version;
+ is_successful = is_successful && _from->deserialize(tmp_major_version);
+ major_version_ = static_cast<major_version_t>(tmp_major_version);
- uint32_t tmp_ttl;
- is_successful = is_successful && _from->deserialize(tmp_ttl, true);
- ttl_ = static_cast< ttl_t >(tmp_ttl);
+ uint32_t tmp_ttl;
+ is_successful = is_successful && _from->deserialize(tmp_ttl, true);
+ ttl_ = static_cast<ttl_t>(tmp_ttl);
- uint32_t tmp_minor_version;
- is_successful = is_successful && _from->deserialize(tmp_minor_version);
- minor_version_ = static_cast< minor_version_t >(tmp_minor_version);
+ uint32_t tmp_minor_version;
+ is_successful = is_successful && _from->deserialize(tmp_minor_version);
+ minor_version_ = static_cast<minor_version_t>(tmp_minor_version);
- return is_successful;
+ return is_successful;
}
} // namespace sd
diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp
index 19d115c..4b823be 100644
--- a/implementation/service_discovery/src/subscription.cpp
+++ b/implementation/service_discovery/src/subscription.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -10,48 +9,46 @@ namespace vsomeip {
namespace sd {
subscription::subscription(major_version_t _major, ttl_t _ttl,
- std::shared_ptr<endpoint> _reliable,
- std::shared_ptr<endpoint> _unreliable)
- : major_(_major),
- ttl_(_ttl),
- reliable_(_reliable),
- unreliable_(_unreliable),
- is_acknowledged_(false) {
+ std::shared_ptr<endpoint> _reliable,
+ std::shared_ptr<endpoint> _unreliable,
+ client_t _target)
+ : major_(_major), ttl_(_ttl), reliable_(_reliable), unreliable_(
+ _unreliable), is_acknowledged_(false) {
}
subscription::~subscription() {
}
major_version_t subscription::get_major() const {
- return major_;
+ return major_;
}
ttl_t subscription::get_ttl() const {
- return ttl_;
+ return ttl_;
}
void subscription::set_ttl(ttl_t _ttl) {
- ttl_ = _ttl;
+ ttl_ = _ttl;
}
std::shared_ptr<endpoint> subscription::get_endpoint(bool _reliable) const {
- return (_reliable ? reliable_ : unreliable_);
+ return (_reliable ? reliable_ : unreliable_);
}
void subscription::set_endpoint(std::shared_ptr<endpoint> _endpoint,
- bool _reliable) {
- if (_reliable)
- reliable_ = _endpoint;
- else
- unreliable_ = _endpoint;
+ bool _reliable) {
+ if (_reliable)
+ reliable_ = _endpoint;
+ else
+ unreliable_ = _endpoint;
}
bool subscription::is_acknowleged() const {
- return is_acknowledged_;
+ return is_acknowledged_;
}
void subscription::set_acknowledged(bool _is_acknowledged) {
- is_acknowledged_ = _is_acknowledged;
+ is_acknowledged_ = _is_acknowledged;
}
} // namespace sd
diff --git a/implementation/utility/include/byteorder.hpp b/implementation/utility/include/byteorder.hpp
index ba04b61..55088f1 100644
--- a/implementation/utility/include/byteorder.hpp
+++ b/implementation/utility/include/byteorder.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,7 +11,8 @@
#elif defined(FREEBSD)
#include <sys/endian.h>
#else
-#error "Undefined OS (only Linux/FreeBSD are currently supported)"
+// TEST IF THERE COULD BE AN ERROR!
+//#error "Undefined OS (only Linux/FreeBSD are currently supported)"
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -55,5 +55,4 @@
#endif
-
#endif // VSOMEIP_BYTEORDER_HPP
diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp
index 186c1ad..000ca9b 100644
--- a/implementation/utility/include/utility.hpp
+++ b/implementation/utility/include/utility.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -16,51 +15,60 @@
namespace vsomeip {
class utility {
- public:
- static void * load_library(const std::string &_path,
- const std::string &_symbol);
-
- static inline bool is_request(std::shared_ptr<message> _message) {
- return (_message ? is_request(_message->get_message_type()) : false);
- }
-
- static inline bool is_request(byte_t _type) {
- return (is_request(static_cast<message_type_e>(_type)));
- }
-
- static inline bool is_request(message_type_e _type) {
- return ((_type < message_type_e::NOTIFICATION)
- || (_type >= message_type_e::REQUEST_ACK
- && _type <= message_type_e::REQUEST_NO_RETURN_ACK));
- }
-
- static inline bool is_request_no_return(std::shared_ptr<message> _message) {
- return (_message && is_request_no_return(_message->get_message_type()));
- }
-
- static inline bool is_request_no_return(byte_t _type) {
- return (is_request_no_return(static_cast<message_type_e>(_type)));
- }
-
- static inline bool is_request_no_return(message_type_e _type) {
- return (_type == message_type_e::REQUEST_NO_RETURN
- || _type == message_type_e::REQUEST_NO_RETURN_ACK);
- }
-
- static inline bool is_event(byte_t _data) {
- return (0 == (0x80 & _data));
- }
-
- static bool is_notification(const byte_t *_data);
-
- static uint32_t get_message_size(const byte_t *_data, uint32_t _size);
- static inline uint32_t get_message_size(std::vector<byte_t> &_data) {
- return (get_message_size(&_data[0], _data.size()));
- }
-
- static uint32_t get_payload_size(const byte_t *_data, uint32_t _size);
-
- static bool exists(const std::string &_path);
+public:
+ static void * load_library(const std::string &_path,
+ const std::string &_symbol);
+
+ static inline bool is_request(std::shared_ptr<message> _message) {
+ return (_message ? is_request(_message->get_message_type()) : false);
+ }
+
+ static inline bool is_request(byte_t _type) {
+ return (is_request(static_cast<message_type_e>(_type)));
+ }
+
+ static inline bool is_request(message_type_e _type) {
+ return ((_type < message_type_e::MT_NOTIFICATION)
+ || (_type >= message_type_e::MT_REQUEST_ACK
+ && _type <= message_type_e::MT_REQUEST_NO_RETURN_ACK));
+ }
+
+ static inline bool is_request_no_return(std::shared_ptr<message> _message) {
+ return (_message && is_request_no_return(_message->get_message_type()));
+ }
+
+ static inline bool is_request_no_return(byte_t _type) {
+ return (is_request_no_return(static_cast<message_type_e>(_type)));
+ }
+
+ static inline bool is_request_no_return(message_type_e _type) {
+ return (_type == message_type_e::MT_REQUEST_NO_RETURN
+ || _type == message_type_e::MT_REQUEST_NO_RETURN_ACK);
+ }
+
+ static inline bool is_event(byte_t _data) {
+ return (0x80 & _data);
+ }
+
+ static inline bool is_notification(byte_t _type) {
+ return (is_notification(static_cast<message_type_e>(_type)));
+ }
+
+ static inline bool is_notification(message_type_e _type) {
+ return (_type == message_type_e::MT_NOTIFICATION);
+ }
+
+ static uint32_t get_message_size(const byte_t *_data, uint32_t _size);
+ static inline uint32_t get_message_size(std::vector<byte_t> &_data) {
+ if (_data.size() > 0) {
+ return (get_message_size(&_data[0], _data.size()));
+ }
+ return 0;
+ }
+
+ static uint32_t get_payload_size(const byte_t *_data, uint32_t _size);
+
+ static bool exists(const std::string &_path);
};
} // namespace vsomeip
diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp
index fd3c864..28eef27 100644
--- a/implementation/utility/src/utility.cpp
+++ b/implementation/utility/src/utility.cpp
@@ -1,10 +1,15 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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 <Windows.h>
+#include <iostream>
+#else
#include <dlfcn.h>
+#endif
+
#include <sys/stat.h>
#include <vsomeip/defines.hpp>
@@ -15,48 +20,67 @@
namespace vsomeip {
-bool utility::is_notification(const byte_t *_data) {
- return (0 == _data[VSOMEIP_CLIENT_POS_MIN]
- && 0 == _data[VSOMEIP_CLIENT_POS_MAX]
- && 0 == _data[VSOMEIP_SESSION_POS_MIN]
- && 0 == _data[VSOMEIP_SESSION_POS_MAX]);
-}
-
uint32_t utility::get_message_size(const byte_t *_data, uint32_t _size) {
- uint32_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]);
- }
- return (its_size);
+ uint32_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]);
+ }
+ 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);
+ 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);
}
void * utility::load_library(const std::string &_path,
- const std::string &_symbol) {
- void * its_symbol = 0;
+ const std::string &_symbol) {
+ void * its_symbol = 0;
+
+#ifdef WIN32
+ std::string path = _path.substr(0, _path.length() - 5).substr(3) + ".dll";
+
+ HINSTANCE hDLL = LoadLibrary(path.c_str());
+ if (hDLL != NULL) {
+ //loadedLibraries_.insert(itsLibrary);
+ std::cout << "Loading interface library \"" << path << "\" succeeded." << std::endl;
+
+ typedef UINT(CALLBACK* LPFNDLLFUNC1)(DWORD, UINT);
- void *handle = dlopen(_path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
- if (0 != handle) {
- its_symbol = dlsym(handle, _symbol.c_str());
- } else {
- VSOMEIP_ERROR<< "Loading failed: (" << dlerror() << ")";
- }
+ LPFNDLLFUNC1 lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, _symbol.c_str());
+ if (!lpfnDllFunc1)
+ {
+ FreeLibrary(hDLL);
+ std::cerr << "Loading symbol \"" << _symbol << "\" failed (" << GetLastError() << ")" << std::endl;
+ }
+ else
+ {
+ its_symbol = lpfnDllFunc1;
+ }
- return (its_symbol);
+ }
+ else {
+ std::cerr << "Loading interface library \"" << path << "\" failed (" << GetLastError() << ")" << std::endl;
+ }
+#else
+ void *handle = dlopen(_path.c_str(), RTLD_LAZY | RTLD_GLOBAL);
+ if (0 != handle) {
+ its_symbol = dlsym(handle, _symbol.c_str());
+ } else {
+ VSOMEIP_ERROR << "Loading failed: (" << dlerror() << ")";
+ }
+#endif
+ return (its_symbol);
}
bool utility::exists(const std::string &_path) {
- struct stat its_stat;
- return (stat(_path.c_str(), &its_stat) == 0);
+ struct stat its_stat;
+ return (stat(_path.c_str(), &its_stat) == 0);
}
-} // namespace vsomeip
+} // namespace vsomeip
diff --git a/interface/vsomeip/application.hpp b/interface/vsomeip/application.hpp
index 529b1c2..98ee93d 100644
--- a/interface/vsomeip/application.hpp
+++ b/interface/vsomeip/application.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -21,65 +20,73 @@ class payload;
class application {
public:
- virtual ~application() {};
+ virtual ~application() {
+ }
- // get name
- virtual const std::string & get_name() const = 0;
- virtual client_t get_client() const = 0;
+ // get name
+ virtual const std::string & get_name() const = 0;
+ virtual client_t get_client() const = 0;
- // Lifecycle
- virtual bool init() = 0;
- virtual void start() = 0;
- virtual void stop() = 0;
+ // Lifecycle
+ virtual bool init() = 0;
+ virtual void start() = 0;
+ virtual void stop() = 0;
- // Provide services
- virtual void offer_service(service_t _service, instance_t _instance,
- major_version_t _major = DEFAULT_MAJOR, minor_version_t _minor =
- DEFAULT_MINOR, ttl_t _ttl = DEFAULT_TTL) = 0;
+ // Provide services
+ virtual void offer_service(service_t _service, instance_t _instance,
+ major_version_t _major = DEFAULT_MAJOR, minor_version_t _minor =
+ DEFAULT_MINOR, ttl_t _ttl = DEFAULT_TTL) = 0;
- virtual void stop_offer_service(service_t _service,
- instance_t _instance) = 0;
+ virtual void stop_offer_service(service_t _service,
+ instance_t _instance) = 0;
- // Consume services
- virtual void request_service(service_t _service, instance_t _instance,
- major_version_t _major = ANY_MAJOR, minor_version_t _minor =
- ANY_MINOR, ttl_t _ttl = ANY_TTL) = 0;
+ // Consume services
+ virtual void request_service(service_t _service, instance_t _instance,
+ bool _has_selective = false, major_version_t _major = ANY_MAJOR,
+ minor_version_t _minor = ANY_MINOR, ttl_t _ttl = ANY_TTL) = 0;
- virtual void release_service(service_t _service, instance_t _instance) = 0;
+ virtual void release_service(service_t _service, instance_t _instance) = 0;
- virtual void subscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major = ANY_MAJOR,
- ttl_t _ttl = ANY_TTL) = 0;
+ virtual void subscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, major_version_t _major = ANY_MAJOR,
+ ttl_t _ttl = ANY_TTL) = 0;
- virtual void unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup) = 0;
+ virtual void unsubscribe(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup) = 0;
- virtual bool is_available(service_t _service, instance_t _instance) = 0;
+ virtual bool is_available(service_t _service, instance_t _instance) = 0;
- // Send a message
- virtual void send(std::shared_ptr<message> _message, bool _flush = true,
- bool _reliable = false) = 0;
+ // Send a message
+ virtual void send(std::shared_ptr<message> _message, bool _flush = true) = 0;
- // Notify subscribers in case an event payload changes
- virtual void notify(service_t _service, instance_t _instance, event_t _event,
- std::shared_ptr<payload> _payload) const = 0;
+ // Notify subscribers in case an event payload changes
+ virtual void notify(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload) const = 0;
- // Receive events (Non-SOME/IP)
- virtual void register_event_handler(event_handler_t _handler) = 0;
- virtual void unregister_event_handler() = 0;
+ virtual void notify_one(service_t _service, instance_t _instance,
+ event_t _event, std::shared_ptr<payload> _payload, client_t _client) const = 0;
- // Receive messages
- virtual void register_message_handler(service_t _service,
- instance_t _instance, method_t _method,
- message_handler_t _handler) = 0;
- virtual void unregister_message_handler(service_t _service,
- instance_t _instance, method_t _method) = 0;
+ // Receive events (Non-SOME/IP)
+ virtual void register_event_handler(event_handler_t _handler) = 0;
+ virtual void unregister_event_handler() = 0;
- // Receive availability
- virtual void register_availability_handler(service_t _service,
- instance_t _instance, availability_handler_t _handler) = 0;
- virtual void unregister_availability_handler(service_t _service,
- instance_t _instance) = 0;
+ // Receive messages
+ virtual void register_message_handler(service_t _service,
+ instance_t _instance, method_t _method,
+ message_handler_t _handler) = 0;
+ virtual void unregister_message_handler(service_t _service,
+ instance_t _instance, method_t _method) = 0;
+
+ // Receive availability
+ virtual void register_availability_handler(service_t _service,
+ instance_t _instance, availability_handler_t _handler) = 0;
+ virtual void unregister_availability_handler(service_t _service,
+ instance_t _instance) = 0;
+
+ virtual void register_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup, subscription_handler_t _handler) = 0;
+ virtual void unregister_subscription_handler(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/configuration.hpp b/interface/vsomeip/configuration.hpp
index 16815ff..7eb81fc 100644
--- a/interface/vsomeip/configuration.hpp
+++ b/interface/vsomeip/configuration.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,6 +14,7 @@
#include <boost/asio/ip/address.hpp>
#include <boost/log/trivial.hpp>
+#include <vsomeip/export.hpp>
#include <vsomeip/defines.hpp>
#include <vsomeip/primitive_types.hpp>
@@ -22,56 +22,70 @@ namespace vsomeip {
class event;
-class configuration {
+class VSOMEIP_EXPORT configuration {
public:
- static configuration * get(const std::string &_path = VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH);
- virtual ~configuration() {};
-
- virtual bool load(const std::string &_path) = 0;
-
- virtual const boost::asio::ip::address & get_unicast() const = 0;
- virtual bool is_v4() const = 0;
- virtual bool is_v6() const = 0;
-
- virtual bool has_console_log() const = 0;
- virtual bool has_file_log() const = 0;
- virtual bool has_dlt_log() const = 0;
- virtual const std::string & get_logfile() const = 0;
- virtual boost::log::trivial::severity_level get_loglevel() const = 0;
-
- virtual const std::string & get_routing_host() const = 0;
-
- virtual bool is_service_discovery_enabled() const = 0;
- virtual const std::string & get_service_discovery_multicast() const = 0;
- virtual uint16_t get_service_discovery_port() const = 0;
- virtual const std::string & get_service_discovery_protocol() const = 0;
-
- virtual std::string get_group(service_t _service, instance_t _instance) const = 0;
- virtual std::set< std::string > get_servicegroups() const = 0;
-
- virtual bool is_local_servicegroup(const std::string &_name) const = 0;
- virtual int32_t get_min_initial_delay(const std::string &_name) const = 0;
- virtual int32_t get_max_initial_delay(const std::string &_name) const = 0;
- virtual int32_t get_repetition_base_delay(const std::string &_name) const = 0;
- virtual uint8_t get_repetition_max(const std::string &_name) const = 0;
- virtual int32_t get_cyclic_offer_delay(const std::string &_name) const = 0;
- virtual int32_t get_cyclic_request_delay(const std::string &_name) const = 0;
-
- virtual std::string get_unicast(service_t _service, instance_t _instance) const = 0;
- virtual std::string get_multicast_address(service_t _service, instance_t _instance) const = 0;
- virtual uint16_t get_multicast_port(service_t _service, instance_t _instance) const = 0;
- virtual uint16_t get_multicast_group(service_t _service, instance_t _instance) const = 0;
- virtual uint16_t get_reliable_port(service_t _service, instance_t _instance) const = 0;
- virtual bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const = 0;
- virtual uint16_t get_unreliable_port(service_t _service, instance_t _instance) const = 0;
-
- virtual std::set< std::pair< service_t, instance_t > > get_remote_services() const = 0;
-
- virtual std::map<service_t, std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > get_eventgroups() const = 0;
- virtual std::map<service_t, std::map<instance_t, std::set<event_t> > > get_events() const = 0;
- virtual void set_event(std::shared_ptr<event> &_event) const = 0;
-
- virtual client_t get_id(const std::string &_name) const = 0;
+ static configuration * get(const std::string &_path =
+ VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH);
+ virtual ~configuration() {
+ }
+
+ virtual bool load(const std::string &_path) = 0;
+
+ virtual const boost::asio::ip::address & get_unicast() const = 0;
+ virtual bool is_v4() const = 0;
+ virtual bool is_v6() const = 0;
+
+ virtual bool has_console_log() const = 0;
+ virtual bool has_file_log() const = 0;
+ virtual bool has_dlt_log() const = 0;
+ virtual const std::string & get_logfile() const = 0;
+ virtual boost::log::trivial::severity_level get_loglevel() const = 0;
+
+ virtual const std::string & get_routing_host() const = 0;
+
+ virtual bool is_service_discovery_enabled() const = 0;
+ virtual const std::string & get_service_discovery_multicast() const = 0;
+ virtual uint16_t get_service_discovery_port() const = 0;
+ virtual const std::string & get_service_discovery_protocol() const = 0;
+
+ virtual std::string get_group(service_t _service,
+ instance_t _instance) const = 0;
+ virtual std::set<std::string> get_servicegroups() const = 0;
+
+ virtual bool is_local_servicegroup(const std::string &_name) const = 0;
+ virtual int32_t get_min_initial_delay(const std::string &_name) const = 0;
+ virtual int32_t get_max_initial_delay(const std::string &_name) const = 0;
+ virtual int32_t get_repetition_base_delay(
+ const std::string &_name) const = 0;
+ virtual uint8_t get_repetition_max(const std::string &_name) const = 0;
+ virtual int32_t get_cyclic_offer_delay(const std::string &_name) const = 0;
+ virtual int32_t get_cyclic_request_delay(
+ const std::string &_name) const = 0;
+
+ virtual std::string get_unicast(service_t _service,
+ instance_t _instance) const = 0;
+ virtual std::string get_multicast_address(service_t _service,
+ instance_t _instance) const = 0;
+ virtual uint16_t get_multicast_port(service_t _service,
+ instance_t _instance) const = 0;
+ virtual uint16_t get_multicast_group(service_t _service,
+ instance_t _instance) const = 0;
+ virtual uint16_t get_reliable_port(service_t _service,
+ instance_t _instance) const = 0;
+ virtual bool has_enabled_magic_cookies(std::string _address,
+ uint16_t _port) const = 0;
+ virtual uint16_t get_unreliable_port(service_t _service,
+ instance_t _instance) const = 0;
+
+ virtual std::set<std::pair<service_t, instance_t> > get_remote_services() const = 0;
+
+ virtual std::map<service_t,
+ std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > get_eventgroups() const = 0;
+ virtual std::map<service_t, std::map<instance_t, std::set<event_t> > > get_events() const = 0;
+ virtual void set_event(std::shared_ptr<event> &_event) const = 0;
+
+ virtual client_t get_id(const std::string &_name) const = 0;
+ virtual std::size_t get_num_dispatchers(const std::string &_name) const = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/constants.hpp b/interface/vsomeip/constants.hpp
index cccd11c..fb947b8 100644
--- a/interface/vsomeip/constants.hpp
+++ b/interface/vsomeip/constants.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -14,8 +13,6 @@
namespace vsomeip {
-const std::string BASE_PATH = "/tmp/vsomeip-";
-
const major_version_t DEFAULT_MAJOR = 0x01;
const minor_version_t DEFAULT_MINOR = 0x000000;
const ttl_t DEFAULT_TTL = 0xFFFFFF; // basically means "forever"
@@ -37,23 +34,17 @@ const length_t MAGIC_COOKIE_SIZE = 0x00000008;
const request_t MAGIC_COOKIE_REQUEST = 0xDEADBEEF;
const protocol_version_t MAGIC_COOKIE_PROTOCOL_VERSION = 0x01;
const interface_version_t MAGIC_COOKIE_INTERFACE_VERSION = 0x01;
-const message_type_e MAGIC_COOKIE_CLIENT_MESSAGE_TYPE = message_type_e::REQUEST_NO_RETURN;
-const message_type_e MAGIC_COOKIE_SERVICE_MESSAGE_TYPE = message_type_e::NOTIFICATION;
+const message_type_e MAGIC_COOKIE_CLIENT_MESSAGE_TYPE =
+ message_type_e::MT_REQUEST_NO_RETURN;
+const message_type_e MAGIC_COOKIE_SERVICE_MESSAGE_TYPE =
+ message_type_e::MT_NOTIFICATION;
const return_code_e MAGIC_COOKIE_RETURN_CODE = return_code_e::E_OK;
-const byte_t CLIENT_COOKIE[] = {
- 0xFF, 0xFF, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08,
- 0xDE, 0xAD, 0xBE, 0xEF,
- 0x01, 0x01, 0x01, 0x00
-};
-
-const byte_t SERVICE_COOKIE[] = {
- 0xFF, 0xFF, 0x80, 0x00,
- 0x00, 0x00, 0x00, 0x08,
- 0xDE, 0xAD, 0xBE, 0xEF,
- 0x01, 0x01, 0x02, 0x00
-};
+const byte_t CLIENT_COOKIE[] = { 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x01, 0x01, 0x00 };
+
+const byte_t SERVICE_COOKIE[] = { 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x08, 0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x01, 0x02, 0x00 };
} // namespace vsomeip
diff --git a/interface/vsomeip/defines.hpp b/interface/vsomeip/defines.hpp
index 9f72807..598bb25 100644
--- a/interface/vsomeip/defines.hpp
+++ b/interface/vsomeip/defines.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,39 +6,41 @@
#ifndef VSOMEIP_DEFINES_HPP
#define VSOMEIP_DEFINES_HPP
-#define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME"
-#define VSOMEIP_ENV_CONFIGURATION_FILE_PATH "VSOMEIP_CONFIGURATION_FILE"
-
-#define VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH "/etc/vsomeip.json"
-#define VSOMEIP_LOCAL_CONFIGURATION_FILE_PATH "./vsomeip.json"
-
-#define VSOMEIP_PROTOCOL_VERSION 0x1
-
-#define VSOMEIP_MAX_LOCAL_MESSAGE_SIZE 32768
-#define VSOMEIP_MAX_TCP_MESSAGE_SIZE 4095
-#define VSOMEIP_MAX_UDP_MESSAGE_SIZE 1446
-
-#define VSOMEIP_PACKET_SIZE VSOMEIP_MAX_UDP_MESSAGE_SIZE
-
-#define VSOMEIP_SOMEIP_HEADER_SIZE 8
-#define VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE 8
-
-#define VSOMEIP_SERVICE_POS_MIN 0
-#define VSOMEIP_SERVICE_POS_MAX 1
-#define VSOMEIP_METHOD_POS_MIN 2
-#define VSOMEIP_METHOD_POS_MAX 3
-#define VSOMEIP_EVENT_POS_MIN 2
-#define VSOMEIP_EVENT_POS_MAX 3
-#define VSOMEIP_LENGTH_POS_MIN 4
-#define VSOMEIP_LENGTH_POS_MAX 7
-#define VSOMEIP_CLIENT_POS_MIN 8
-#define VSOMEIP_CLIENT_POS_MAX 9
-#define VSOMEIP_SESSION_POS_MIN 10
-#define VSOMEIP_SESSION_POS_MAX 11
-#define VSOMEIP_PROTOCOL_VERSION_POS 12
-#define VSOMEIP_INTERFACE_VERSION_POS 13
-#define VSOMEIP_MESSAGE_TYPE_POS 14
-#define VSOMEIP_RETURN_CODE_POS 15
-#define VSOMEIP_PAYLOAD_POS 16
+#define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME"
+#define VSOMEIP_ENV_CONFIGURATION_FILE_PATH "VSOMEIP_CONFIGURATION_FILE"
+
+#define VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH "/etc/vsomeip.json"
+#define VSOMEIP_LOCAL_CONFIGURATION_FILE_PATH "./vsomeip.json"
+
+#define VSOMEIP_BASE_PATH "/tmp/vsomeip-"
+
+#define VSOMEIP_PROTOCOL_VERSION 0x1
+
+#define VSOMEIP_MAX_LOCAL_MESSAGE_SIZE 32768
+#define VSOMEIP_MAX_TCP_MESSAGE_SIZE 4095
+#define VSOMEIP_MAX_UDP_MESSAGE_SIZE 1446
+
+#define VSOMEIP_PACKET_SIZE VSOMEIP_MAX_UDP_MESSAGE_SIZE
+
+#define VSOMEIP_SOMEIP_HEADER_SIZE 8
+#define VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE 8
+
+#define VSOMEIP_SERVICE_POS_MIN 0
+#define VSOMEIP_SERVICE_POS_MAX 1
+#define VSOMEIP_METHOD_POS_MIN 2
+#define VSOMEIP_METHOD_POS_MAX 3
+#define VSOMEIP_EVENT_POS_MIN 2
+#define VSOMEIP_EVENT_POS_MAX 3
+#define VSOMEIP_LENGTH_POS_MIN 4
+#define VSOMEIP_LENGTH_POS_MAX 7
+#define VSOMEIP_CLIENT_POS_MIN 8
+#define VSOMEIP_CLIENT_POS_MAX 9
+#define VSOMEIP_SESSION_POS_MIN 10
+#define VSOMEIP_SESSION_POS_MAX 11
+#define VSOMEIP_PROTOCOL_VERSION_POS 12
+#define VSOMEIP_INTERFACE_VERSION_POS 13
+#define VSOMEIP_MESSAGE_TYPE_POS 14
+#define VSOMEIP_RETURN_CODE_POS 15
+#define VSOMEIP_PAYLOAD_POS 16
#endif // VSOMEIP_DEFINES_HPP
diff --git a/interface/vsomeip/deserializable.hpp b/interface/vsomeip/deserializable.hpp
index 1743c5d..fb11dfd 100644
--- a/interface/vsomeip/deserializable.hpp
+++ b/interface/vsomeip/deserializable.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,14 +6,17 @@
#ifndef VSOMEIP_DESERIALIZABLE_HPP
#define VSOMEIP_DESERIALIZABLE_HPP
+#include <vsomeip/export.hpp>
+
namespace vsomeip {
class deserializer;
class deserializable {
public:
- virtual ~deserializable() {};
- virtual bool deserialize(deserializer *_from) = 0;
+ VSOMEIP_EXPORT virtual ~deserializable() {
+ }
+ VSOMEIP_EXPORT virtual bool deserialize(deserializer *_from) = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/enumeration_types.hpp b/interface/vsomeip/enumeration_types.hpp
index 787938a..51c3df1 100644
--- a/interface/vsomeip/enumeration_types.hpp
+++ b/interface/vsomeip/enumeration_types.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,40 +11,39 @@
namespace vsomeip {
enum class event_type_e : uint8_t {
- REGISTERED = 0x0,
- DEREGISTERED = 0x1
+ ET_REGISTERED = 0x0,
+ ET_DEREGISTERED = 0x1
};
-
// SIP_RPC_684
enum class message_type_e : uint8_t {
- REQUEST = 0x00,
- REQUEST_NO_RETURN = 0x01,
- NOTIFICATION = 0x02,
- REQUEST_ACK = 0x40,
- REQUEST_NO_RETURN_ACK = 0x41,
- NOTIFICATION_ACK = 0x42,
- RESPONSE = 0x80,
- ERROR = 0x81,
- RESPONSE_ACK = 0xC0,
- ERROR_ACK = 0xC1,
- UNKNOWN = 0xFF
+ MT_REQUEST = 0x00,
+ MT_REQUEST_NO_RETURN = 0x01,
+ MT_NOTIFICATION = 0x02,
+ MT_REQUEST_ACK = 0x40,
+ MT_REQUEST_NO_RETURN_ACK = 0x41,
+ MT_NOTIFICATION_ACK = 0x42,
+ MT_RESPONSE = 0x80,
+ MT_ERROR = 0x81,
+ MT_RESPONSE_ACK = 0xC0,
+ MT_ERROR_ACK = 0xC1,
+ MT_UNKNOWN = 0xFF
};
// SIP_RPC_371
enum class return_code_e : uint8_t {
- E_OK = 0x00,
- E_NOT_OK = 0x01,
- E_UNKNOWN_SERVICE = 0x02,
- E_UNKNOWN_METHOD = 0x03,
- E_NOT_READY = 0x04,
- E_NOT_REACHABLE = 0x05,
- E_TIMEOUT = 0x06,
- E_WRONG_PROTOCOL_VERSION = 0x07,
- E_WRONG_INTERFACE_VERSION = 0x08,
- E_MALFORMED_MESSAGE = 0x09,
- E_WRONG_MESSAGE_TYPE = 0xA,
- E_UNKNOWN = 0xFF
+ E_OK = 0x00,
+ E_NOT_OK = 0x01,
+ E_UNKNOWN_SERVICE = 0x02,
+ E_UNKNOWN_METHOD = 0x03,
+ E_NOT_READY = 0x04,
+ E_NOT_REACHABLE = 0x05,
+ E_TIMEOUT = 0x06,
+ E_WRONG_PROTOCOL_VERSION = 0x07,
+ E_WRONG_INTERFACE_VERSION = 0x08,
+ E_MALFORMED_MESSAGE = 0x09,
+ E_WRONG_MESSAGE_TYPE = 0xA,
+ E_UNKNOWN = 0xFF
};
} // namespace vsomeip
diff --git a/interface/vsomeip/error.hpp b/interface/vsomeip/error.hpp
index 305a776..b655174 100644
--- a/interface/vsomeip/error.hpp
+++ b/interface/vsomeip/error.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014-2015 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -12,11 +11,11 @@
namespace vsomeip {
enum class error_code_e : uint8_t {
- CONFIGURATION_MISSING,
- PORT_CONFIGURATION_MISSING,
- CLIENT_ENDPOINT_CREATION_FAILED,
- SERVER_ENDPOINT_CREATION_FAILED,
- SERVICE_PROPERTY_MISMATCH
+ CONFIGURATION_MISSING,
+ PORT_CONFIGURATION_MISSING,
+ CLIENT_ENDPOINT_CREATION_FAILED,
+ SERVER_ENDPOINT_CREATION_FAILED,
+ SERVICE_PROPERTY_MISMATCH
};
extern const char *ERROR_INFO[];
diff --git a/interface/vsomeip/export.hpp b/interface/vsomeip/export.hpp
new file mode 100644
index 0000000..7e8ddad
--- /dev/null
+++ b/interface/vsomeip/export.hpp
@@ -0,0 +1,15 @@
+// Copyright (C) 2014-2015 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 __EXPORT__HPP__
+#define __EXPORT__HPP__
+
+#if WIN32
+#define VSOMEIP_EXPORT __declspec(dllexport)
+#else
+#define VSOMEIP_EXPORT
+#endif
+
+#endif
diff --git a/interface/vsomeip/handler.hpp b/interface/vsomeip/handler.hpp
index f56365f..29df46a 100644
--- a/interface/vsomeip/handler.hpp
+++ b/interface/vsomeip/handler.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -17,8 +16,9 @@ namespace vsomeip {
class message;
typedef std::function< void (event_type_e) > event_handler_t;
-typedef std::function< void (std::shared_ptr< message > &) > message_handler_t;
+typedef std::function< void (const std::shared_ptr< message > &) > message_handler_t;
typedef std::function< void (service_t, instance_t, bool) > availability_handler_t;
+typedef std::function< bool (client_t, bool) > subscription_handler_t;
} // namespace vsomeip
diff --git a/interface/vsomeip/logger.hpp b/interface/vsomeip/logger.hpp
index 99b241c..555f15e 100644
--- a/interface/vsomeip/logger.hpp
+++ b/interface/vsomeip/logger.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,27 +8,40 @@
#include <string>
+#ifdef WIN32
+#include <iostream>
+#endif
+
+#include <vsomeip/export.hpp>
+
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
namespace vsomeip {
-class logger {
+class VSOMEIP_EXPORT logger {
public:
- static logger & get();
+ static std::shared_ptr<logger> get();
- virtual ~logger() {};
+ virtual ~logger() {
+ }
- virtual boost::log::sources::severity_logger<
- boost::log::trivial::severity_level > & get_internal() = 0;
+ virtual boost::log::sources::severity_logger<
+ boost::log::trivial::severity_level> & get_internal() = 0;
};
-#define VSOMEIP_FATAL BOOST_LOG_SEV(vsomeip::logger::get().get_internal(), boost::log::trivial::severity_level::fatal)
-#define VSOMEIP_ERROR BOOST_LOG_SEV(vsomeip::logger::get().get_internal(), boost::log::trivial::severity_level::error)
-#define VSOMEIP_WARNING BOOST_LOG_SEV(vsomeip::logger::get().get_internal(), boost::log::trivial::severity_level::warning)
-#define VSOMEIP_INFO BOOST_LOG_SEV(vsomeip::logger::get().get_internal(), boost::log::trivial::severity_level::info)
-#define VSOMEIP_DEBUG BOOST_LOG_SEV(vsomeip::logger::get().get_internal(), boost::log::trivial::severity_level::debug)
-#define VSOMEIP_TRACE BOOST_LOG_SEV(vsomeip::logger::get().get_internal(), boost::log::trivial::severity_level::trace)
+#define VSOMEIP_FATAL BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::fatal)
+#define VSOMEIP_ERROR BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::error)
+#define VSOMEIP_WARNING BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::warning)
+#define VSOMEIP_INFO BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::info)
+#define VSOMEIP_DEBUG BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::debug)
+#define VSOMEIP_TRACE BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::trace)
} // namespace vsomeip
diff --git a/interface/vsomeip/message.hpp b/interface/vsomeip/message.hpp
index 8944f0b..6b91712 100644
--- a/interface/vsomeip/message.hpp
+++ b/interface/vsomeip/message.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -15,13 +14,13 @@ namespace vsomeip {
class payload;
-class message
- : virtual public message_base {
+class message: virtual public message_base {
public:
- virtual ~message() {};
+ virtual ~message() {
+ }
- virtual std::shared_ptr< payload > get_payload() const = 0;
- virtual void set_payload(std::shared_ptr< payload > _payload) = 0;
+ virtual std::shared_ptr<payload> get_payload() const = 0;
+ virtual void set_payload(std::shared_ptr<payload> _payload) = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/message_base.hpp b/interface/vsomeip/message_base.hpp
index b80d0b6..9b464c7 100644
--- a/interface/vsomeip/message_base.hpp
+++ b/interface/vsomeip/message_base.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,6 +6,7 @@
#ifndef VSOMEIP_MESSAGE_BASE_HPP
#define VSOMEIP_MESSAGE_BASE_HPP
+#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/enumeration_types.hpp>
#include <vsomeip/deserializable.hpp>
@@ -15,43 +15,47 @@
namespace vsomeip {
class message_base
- : public serializable,
- public deserializable {
+ : public serializable,
+ public deserializable {
public:
- virtual ~message_base() {};
+ VSOMEIP_EXPORT virtual ~message_base() {};
- virtual message_t get_message() const = 0;
- virtual void set_message(message_t _message) = 0;
+ VSOMEIP_EXPORT virtual message_t get_message() const = 0;
+ VSOMEIP_EXPORT virtual void set_message(message_t _message) = 0;
- virtual service_t get_service() const = 0;
- virtual void set_service(service_t _service) = 0;
+ VSOMEIP_EXPORT virtual service_t get_service() const = 0;
+ VSOMEIP_EXPORT virtual void set_service(service_t _service) = 0;
- virtual instance_t get_instance() const = 0;
- virtual void set_instance(instance_t _instance) = 0;
+ VSOMEIP_EXPORT virtual instance_t get_instance() const = 0;
+ VSOMEIP_EXPORT virtual void set_instance(instance_t _instance) = 0;
- virtual method_t get_method() const = 0;
- virtual void set_method(method_t _method) = 0;
+ VSOMEIP_EXPORT virtual method_t get_method() const = 0;
+ VSOMEIP_EXPORT virtual void set_method(method_t _method) = 0;
- virtual length_t get_length() const = 0;
-
- virtual request_t get_request() const = 0;
+ VSOMEIP_EXPORT virtual length_t get_length() const = 0;
- virtual client_t get_client() const = 0;
- virtual void set_client(client_t _client) = 0;
+ VSOMEIP_EXPORT virtual request_t get_request() const = 0;
- virtual session_t get_session() const = 0;
- virtual void set_session(session_t _session) = 0;
-
- virtual protocol_version_t get_protocol_version() const = 0;
+ VSOMEIP_EXPORT virtual client_t get_client() const = 0;
+ VSOMEIP_EXPORT virtual void set_client(client_t _client) = 0;
- virtual interface_version_t get_interface_version() const = 0;
- virtual void set_interface_version(interface_version_t _version) = 0;
+ VSOMEIP_EXPORT virtual session_t get_session() const = 0;
+ VSOMEIP_EXPORT virtual void set_session(session_t _session) = 0;
- virtual message_type_e get_message_type() const = 0;
- virtual void set_message_type(message_type_e _type) = 0;
+ VSOMEIP_EXPORT virtual protocol_version_t get_protocol_version() const = 0;
- virtual return_code_e get_return_code() const = 0;
- virtual void set_return_code(return_code_e _code) = 0;
+ VSOMEIP_EXPORT virtual interface_version_t get_interface_version() const = 0;
+ VSOMEIP_EXPORT virtual void set_interface_version(interface_version_t _version) = 0;
+
+ VSOMEIP_EXPORT virtual message_type_e get_message_type() const = 0;
+ VSOMEIP_EXPORT virtual void set_message_type(message_type_e _type) = 0;
+
+ VSOMEIP_EXPORT virtual return_code_e get_return_code() const = 0;
+ VSOMEIP_EXPORT virtual void set_return_code(return_code_e _code) = 0;
+
+ // No part of the SOME/IP protocol header
+ VSOMEIP_EXPORT virtual bool is_reliable() const = 0;
+ VSOMEIP_EXPORT virtual void set_reliable(bool _is_reliable) = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/payload.hpp b/interface/vsomeip/payload.hpp
index 409866b..9c85906 100644
--- a/interface/vsomeip/payload.hpp
+++ b/interface/vsomeip/payload.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -9,28 +8,30 @@
#include <vector>
+#include <vsomeip/export.hpp>
#include <vsomeip/deserializable.hpp>
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/serializable.hpp>
namespace vsomeip {
-class payload :
- public serializable,
- public deserializable {
+class payload: public serializable, public deserializable {
public:
- virtual ~payload() {};
+ VSOMEIP_EXPORT virtual ~payload() {
+ }
- virtual bool operator == (const payload &_other) = 0;
+ VSOMEIP_EXPORT virtual bool operator ==(const payload &_other) = 0;
- virtual byte_t * get_data() = 0;
- virtual const byte_t * get_data() const = 0;
- virtual void set_data(const byte_t *_data, length_t _length) = 0;
- virtual void set_data(const std::vector< byte_t > &_data) = 0;
+ VSOMEIP_EXPORT virtual byte_t * get_data() = 0;
+ VSOMEIP_EXPORT virtual const byte_t * get_data() const = 0;
+ VSOMEIP_EXPORT virtual void set_data(const byte_t *_data,
+ length_t _length) = 0;
+ VSOMEIP_EXPORT virtual void set_data(
+ const std::vector<byte_t> &_data) = 0;
- virtual length_t get_length() const = 0;
-
- virtual void set_capacity(length_t _length) = 0;
+ VSOMEIP_EXPORT virtual length_t get_length() const = 0;
+
+ VSOMEIP_EXPORT virtual void set_capacity(length_t _length) = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/primitive_types.hpp b/interface/vsomeip/primitive_types.hpp
index 7a30033..3cc2b9a 100644
--- a/interface/vsomeip/primitive_types.hpp
+++ b/interface/vsomeip/primitive_types.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -37,8 +36,8 @@ typedef uint8_t interface_version_t;
typedef uint8_t byte_t;
// Addresses
-typedef std::array< byte_t, 4 > ipv4_address_t;
-typedef std::array< byte_t, 16 > ipv6_address_t;
+typedef std::array<byte_t, 4> ipv4_address_t;
+typedef std::array<byte_t, 16> ipv6_address_t;
} // namespace vsomeip
diff --git a/interface/vsomeip/runtime.hpp b/interface/vsomeip/runtime.hpp
index a3cf624..cb3f6f6 100644
--- a/interface/vsomeip/runtime.hpp
+++ b/interface/vsomeip/runtime.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -11,6 +10,8 @@
#include <string>
#include <vector>
+#include <vsomeip/export.hpp>
+
#include <vsomeip/primitive_types.hpp>
namespace vsomeip {
@@ -19,27 +20,30 @@ class application;
class message;
class payload;
-class runtime {
+class VSOMEIP_EXPORT runtime {
public:
- static runtime * get();
-
- virtual ~runtime() {};
-
- virtual std::shared_ptr<application> create_application(
- const std::string &_name = "") const = 0;
-
- virtual std::shared_ptr<message> create_message() const = 0;
- virtual std::shared_ptr<message> create_request() const = 0;
- virtual std::shared_ptr<message> create_response(
- const std::shared_ptr<message> &_request) const = 0;
- virtual std::shared_ptr<message> create_notification() const = 0;
-
- virtual std::shared_ptr<payload> create_payload() const = 0;
- virtual std::shared_ptr<payload> create_payload(
- const byte_t *_data, uint32_t _size) const = 0;
- virtual std::shared_ptr<payload> create_payload(
- const std::vector<byte_t> &_data) const = 0;
-
+ static std::shared_ptr<runtime> get();
+
+ virtual ~runtime() {
+ }
+
+ virtual std::shared_ptr<application> create_application(
+ const std::string &_name = "") const = 0;
+
+ virtual std::shared_ptr<message> create_message(
+ bool _reliable = false) const = 0;
+ virtual std::shared_ptr<message> create_request(
+ bool _reliable = false) const = 0;
+ virtual std::shared_ptr<message> create_response(
+ const std::shared_ptr<message> &_request) const = 0;
+ virtual std::shared_ptr<message> create_notification(
+ bool _reliable = false) const = 0;
+
+ virtual std::shared_ptr<payload> create_payload() const = 0;
+ virtual std::shared_ptr<payload> create_payload(
+ const byte_t *_data, uint32_t _size) const = 0;
+ virtual std::shared_ptr<payload> create_payload(
+ const std::vector<byte_t> &_data) const = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/serializable.hpp b/interface/vsomeip/serializable.hpp
index 86714ed..4cab10f 100644
--- a/interface/vsomeip/serializable.hpp
+++ b/interface/vsomeip/serializable.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/.
@@ -7,14 +6,18 @@
#ifndef VSOMEIP_SERIALIZABLE_HPP
#define VSOMEIP_SERIALIZABLE_HPP
+#include <vsomeip/export.hpp>
+
namespace vsomeip {
class serializer;
class serializable {
public:
- virtual ~serializable() {};
- virtual bool serialize(serializer *_to) const = 0;
+ VSOMEIP_EXPORT virtual ~serializable() {
+ }
+
+ VSOMEIP_EXPORT virtual bool serialize(serializer *_to) const = 0;
};
} // namespace vsomeip
diff --git a/interface/vsomeip/vsomeip.hpp b/interface/vsomeip/vsomeip.hpp
index cd1aa33..9d7cb56 100644
--- a/interface/vsomeip/vsomeip.hpp
+++ b/interface/vsomeip/vsomeip.hpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2014-2015 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/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..c944610
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,536 @@
+# Copyright (C) 2015 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 2.8.1)
+
+# Add the gtest header files to the include files
+include_directories(
+ .
+ ${gtest_SOURCE_DIR}/include
+)
+
+set(TEST_LINK_LIBRARIES gtest)
+
+# Function to copy files into the build directory (or anywhere else)
+# 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)
+ 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"
+ )
+ # 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)
+ ADD_CUSTOM_TARGET(copy_${FILENAME}_${RANDOMNUMBER}
+ DEPENDS "${DESTINATION_PATH}"
+ )
+ ADD_DEPENDENCIES(${TARGET_TO_DEPEND} copy_${FILENAME}_${RANDOMNUMBER})
+endfunction()
+
+##############################################################################
+# configuration-test
+##############################################################################
+
+set(TEST_CONFIGURATION configuration-test)
+
+add_executable(${TEST_CONFIGURATION} configuration-test.cpp)
+target_link_libraries(${TEST_CONFIGURATION}
+ vsomeip
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+)
+
+# 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 vsomeip-test.json)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/config/${TEST_CONFIGURATION_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${TEST_CONFIGURATION_CONFIG_FILE}
+ ${TEST_CONFIGURATION}
+)
+
+##############################################################################
+# magic-cookies-test-client
+##############################################################################
+set(TEST_MAGIC_COOKIES_NAME magic_cookies_test)
+
+set(TEST_MAGIC_COOKIES_CLIENT magic-cookies-test-client)
+add_executable(${TEST_MAGIC_COOKIES_CLIENT} magic-cookies-test-client.cpp)
+target_link_libraries(${TEST_MAGIC_COOKIES_CLIENT}
+ vsomeip
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT}
+)
+add_dependencies(${TEST_MAGIC_COOKIES_CLIENT} response-sample)
+
+# Copy config file for client into $BUILDDIR/test
+set(TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE vsomeip-magic-cookies-client.json)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/config/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE}
+ ${TEST_MAGIC_COOKIES_CLIENT}
+)
+
+# Copy bashscript to start client into $BUILDDIR/test
+set(TEST_MAGIC_COOKIES_CLIENT_UNDERSCORE magic_cookies_test_client)
+set(TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT ${TEST_MAGIC_COOKIES_CLIENT_UNDERSCORE}_start.sh)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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 vsomeip-magic-cookies-service.json)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/config/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE}
+ ${TEST_MAGIC_COOKIES_CLIENT}
+)
+
+# Copy bashscript to start service into $BUILDDIR/test
+set(TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT ${TEST_MAGIC_COOKIES_SERVICE}_start.sh)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/${TEST_MAGIC_COOKIES_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_STARTER}
+ ${TEST_MAGIC_COOKIES_CLIENT}
+)
+
+##############################################################################
+# 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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${TEST_LINK_LIBRARIES}
+)
+
+##############################################################################
+# Now comes the second part of the header factory test which consists of ouf
+# 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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${TEST_LINK_LIBRARIES}
+)
+
+# Copy config file for client into $BUILDDIR/test
+set(TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE ${TEST_HEADER_FACTORY_CLIENT}.json)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${TEST_LINK_LIBRARIES}
+)
+
+# Copy config file for service into $BUILDDIR/test
+set(TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE ${TEST_HEADER_FACTORY_SERVICE}.json)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_STARTER}
+ ${TEST_HEADER_FACTORY_CLIENT}
+)
+
+##############################################################################
+# routing-test
+##############################################################################
+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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${TEST_LINK_LIBRARIES}
+)
+
+# Copy config file for service into $BUILDDIR/test
+set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${TEST_LINK_LIBRARIES}
+)
+
+# Copy config file for client into $BUILDDIR/test
+set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${TEST_LINK_LIBRARIES}
+)
+
+# Copy config file for service into $BUILDDIR/test
+set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.json)
+copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER}
+ ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}
+)
+
+##############################################################################
+# 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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${TEST_LINK_LIBRARIES}
+)
+
+# Copy config file for service into $BUILDDIR/test
+set(TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE local_${TEST_PAYLOAD_SERVICE}.json)
+copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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
+ ${Boost_LIBRARIES}
+ ${DL_LIBRARY}
+ ${TEST_LINK_LIBRARIES}
+)
+
+# Copy config file for client into $BUILDDIR/test
+set(TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE local_${TEST_PAYLOAD_CLIENT}.json)
+copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${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)
+copy_to_builddir(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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(
+ ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${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(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER}
+ ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER}
+ ${TEST_PAYLOAD_CLIENT}
+)
+
+##############################################################################
+# Add for every test a dependency to gtest
+##############################################################################
+
+add_dependencies(${TEST_CONFIGURATION} gtest)
+add_dependencies(${TEST_MAGIC_COOKIES_CLIENT} 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 tests to the target build_tests
+##############################################################################
+
+add_dependencies(build_tests ${TEST_CONFIGURATION})
+add_dependencies(build_tests ${TEST_MAGIC_COOKIES_CLIENT})
+add_dependencies(build_tests ${TEST_HEADER_FACTORY})
+add_dependencies(build_tests ${TEST_HEADER_FACTORY_CLIENT})
+add_dependencies(build_tests ${TEST_HEADER_FACTORY_SERVICE})
+add_dependencies(build_tests ${TEST_LOCAL_ROUTING_SERVICE})
+add_dependencies(build_tests ${TEST_LOCAL_ROUTING_CLIENT})
+add_dependencies(build_tests ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE})
+add_dependencies(build_tests ${TEST_PAYLOAD_SERVICE})
+add_dependencies(build_tests ${TEST_PAYLOAD_CLIENT})
+
+##############################################################################
+# Add tests
+##############################################################################
+
+add_test(NAME ${TEST_CONFIGURATION}
+ COMMAND ${TEST_CONFIGURATION} --someip ${TEST_CONFIGURATION_CONFIG_FILE}
+)
+
+add_test(NAME ${TEST_MAGIC_COOKIES_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_STARTER}
+)
+set_tests_properties(${TEST_MAGIC_COOKIES_NAME} PROPERTIES TIMEOUT 60)
+
+# Header/Factory tets
+add_test(NAME ${TEST_HEADER_FACTORY_NAME} COMMAND ${TEST_HEADER_FACTORY})
+add_test(NAME ${TEST_HEADER_FACTORY_NAME}_send_receive
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_STARTER}
+)
+
+# Routing tests
+add_test(NAME ${TEST_LOCAL_ROUTING_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER}
+)
+add_test(NAME ${TEST_EXTERNAL_LOCAL_ROUTING_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER}
+)
+set_tests_properties(${TEST_EXTERNAL_LOCAL_ROUTING_NAME} PROPERTIES TIMEOUT 60)
+
+# Payload tests
+add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_STARTER}
+)
+add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER}
+)
+add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER}
+)
+set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 240)
+add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME}
+ COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER}
+)
+set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 240)
diff --git a/test/configuration-test.cpp b/test/configuration-test.cpp
index 03df48f..cc91ab0 100644
--- a/test/configuration-test.cpp
+++ b/test/configuration-test.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2015 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/test/header_factory_tests/header_factory_test.cpp b/test/header_factory_tests/header_factory_test.cpp
new file mode 100644
index 0000000..c3b8c32
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test.cpp
@@ -0,0 +1,120 @@
+// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include "../someip_test_globals.hpp"
+
+class someip_header_factory_test: public ::testing::Test
+{
+protected:
+ std::shared_ptr<vsomeip::message> request_;
+ std::shared_ptr<vsomeip::message> response_;
+ std::shared_ptr<vsomeip::message> notification_;
+ std::shared_ptr<vsomeip::application> app_;
+ std::shared_ptr<vsomeip::message> message_;
+
+ vsomeip::service_t service_id_ = vsomeip_test::TEST_SERVICE_SERVICE_ID;
+ vsomeip::method_t method_id_ = vsomeip_test::TEST_SERVICE_METHOD_ID;
+ vsomeip::instance_t instance_id_ = vsomeip_test::TEST_SERVICE_INSTANCE_ID;
+ vsomeip::interface_version_t interface_version_ = 0x01;
+ vsomeip::client_t client_id_ = vsomeip_test::TEST_CLIENT_CLIENT_ID;
+ vsomeip::session_t session_id_ = vsomeip_test::TEST_INITIAL_SESSION_ID;
+};
+
+TEST_F(someip_header_factory_test, create_request_test)
+{
+ ASSERT_TRUE(request_.get() == nullptr);
+ request_ = vsomeip::runtime::get()->create_request();
+
+ // check that returned shared_ptr is not null
+ ASSERT_TRUE(request_.get() != nullptr);
+
+ // Check the protocol version
+ // this shall be set to 0x01 according to the spec. TR_SOMEIP_00052
+ ASSERT_EQ(request_->get_protocol_version(), 0x01);
+ // Check the message type
+ // this shall be 0x00 (REQUEST) according to the spec. TR_SOMEIP_00055
+ ASSERT_EQ(request_->get_message_type(), vsomeip::message_type_e::MT_REQUEST);
+ // Check the return code
+ // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058
+ ASSERT_EQ(request_->get_return_code(), vsomeip::return_code_e::E_OK);
+
+}
+
+TEST_F(someip_header_factory_test, create_request_and_response_test)
+{
+ ASSERT_TRUE(request_.get() == nullptr);
+ request_ = vsomeip::runtime::get()->create_request();
+ // check that returned shared_ptr is not null
+ ASSERT_TRUE(request_.get() != nullptr);
+
+ request_->set_service(service_id_);
+ request_->set_method(method_id_);
+ request_->set_interface_version(interface_version_);
+ // set the request_id (client_id + session_id). This normally is set by the
+ // application_impl::send() if a request is send, we set it here to test the
+ // correct initialization of the response
+ request_->set_client(client_id_);
+ request_->set_session(session_id_);
+
+ ASSERT_TRUE(response_.get() == nullptr);
+ response_ = vsomeip::runtime::get()->create_response(request_);
+ // check that returned shared_ptr is not null
+ ASSERT_TRUE(response_.get() != nullptr);
+
+ ASSERT_EQ(response_->get_service(), request_->get_service());
+ ASSERT_EQ(response_->get_method(), request_->get_method());
+ ASSERT_EQ(response_->get_client(), request_->get_client());
+ ASSERT_EQ(response_->get_session(), request_->get_session());
+
+ // length? --> gets only set if a payload is added
+
+ ASSERT_EQ(response_->get_protocol_version(), request_->get_protocol_version());
+ ASSERT_EQ(response_->get_interface_version(), request_->get_interface_version());
+
+ // Check the message type
+ // this shall be 0x00 (REQUEST) according to the spec. TR_SOMEIP_00055
+ ASSERT_EQ(request_->get_message_type(), vsomeip::message_type_e::MT_REQUEST);
+
+ // Check the message type
+ // this shall be 0x80 (RESPONSE) according to the spec. TR_SOMEIP_00055
+ ASSERT_EQ(response_->get_message_type(), vsomeip::message_type_e::MT_RESPONSE);
+
+ // Check the return code
+ // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058
+ // and TR_SOMEIP_00191
+ ASSERT_EQ(response_->get_return_code(), vsomeip::return_code_e::E_OK);
+
+}
+
+TEST_F(someip_header_factory_test, create_notification_test)
+{
+ ASSERT_TRUE(notification_.get() == nullptr);
+ notification_ = vsomeip::runtime::get()->create_notification();
+
+ // check that returned shared_ptr is not null
+ ASSERT_TRUE(notification_.get() != nullptr);
+
+ // Check the protocol version
+ // this shall be set to 0x01 according to the spec. TR_SOMEIP_00052
+ ASSERT_EQ(notification_->get_protocol_version(), 0x01);
+ // Check the message type
+ // this shall be 0x02 (NOTIFICATION) according to the spec. TR_SOMEIP_00055
+ ASSERT_EQ(notification_->get_message_type(), vsomeip::message_type_e::MT_NOTIFICATION);
+ // Check the return code
+ // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058
+ ASSERT_EQ(notification_->get_return_code(), vsomeip::return_code_e::E_OK);
+}
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/header_factory_tests/header_factory_test_client.cpp b/test/header_factory_tests/header_factory_test_client.cpp
new file mode 100644
index 0000000..4cce67e
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_client.cpp
@@ -0,0 +1,171 @@
+// Copyright (C) 2015 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 "header_factory_test_client.hpp"
+
+header_factory_test_client::header_factory_test_client(bool _use_tcp) :
+ app_(vsomeip::runtime::get()->create_application()),
+ request_(vsomeip::runtime::get()->create_request(_use_tcp)),
+ sender_(std::bind(&header_factory_test_client::run, this)),
+ running_(true),
+ blocked_(false),
+ is_available_(false),
+ number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND),
+ number_of_sent_messages_(0),
+ number_of_acknowledged_messages_(0)
+{
+}
+
+void header_factory_test_client::init()
+{
+ app_->init();
+
+ app_->register_event_handler(
+ std::bind(&header_factory_test_client::on_event, this,
+ std::placeholders::_1));
+
+ app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID,
+ std::bind(&header_factory_test_client::on_availability, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3));
+
+ app_->register_message_handler(vsomeip::ANY_SERVICE,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD,
+ std::bind(&header_factory_test_client::on_message, this,
+ std::placeholders::_1));
+
+ 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);
+}
+
+void header_factory_test_client::start()
+{
+ VSOMEIP_INFO << "Starting...";
+ app_->start();
+}
+
+void header_factory_test_client::stop()
+{
+ VSOMEIP_INFO << "Stopping...";
+ app_->unregister_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+ app_->unregister_event_handler();
+ app_->unregister_message_handler(vsomeip::ANY_SERVICE,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD);
+
+ app_->stop();
+}
+
+void header_factory_test_client::join_sender_thread(){
+ sender_.join();
+
+ ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_);
+}
+
+void header_factory_test_client::on_event(vsomeip::event_type_e _event)
+{
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, false);
+ }
+}
+
+void header_factory_test_client::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.");
+
+ if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service
+ && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance)
+ {
+ if(is_available_ && !_is_available)
+ {
+ is_available_ = false;
+ }
+ else if(_is_available && !is_available_)
+ {
+ is_available_ = true;
+ send();
+ }
+ }
+}
+
+void header_factory_test_client::on_message(const std::shared_ptr<vsomeip::message>& _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() << "]";
+ number_of_acknowledged_messages_++;
+ ASSERT_EQ(_response->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID);
+ ASSERT_EQ(_response->get_instance(), vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+ ASSERT_EQ(_response->get_client(), vsomeip_test::TEST_CLIENT_CLIENT_ID);
+ ASSERT_EQ(_response->get_session(),
+ static_cast<vsomeip::session_t>(number_of_acknowledged_messages_));
+}
+
+void header_factory_test_client::send()
+{
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ blocked_ = true;
+ condition_.notify_one();
+}
+
+void header_factory_test_client::run()
+{
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ {
+ condition_.wait(its_lock);
+ }
+
+ for (int i = 0; i < number_of_messages_to_send_; i++)
+ {
+ app_->send(request_, true);
+ 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() << "]";
+ number_of_sent_messages_++;
+ }
+ blocked_ = false;
+ // wait until all send messages has been acknowledged, but a maximum of 5 sec.
+ int cnt = 0;
+ while (number_of_acknowledged_messages_ != number_of_messages_to_send_
+ && cnt < 5)
+ {
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ cnt++;
+ }
+ stop();
+}
+
+TEST(someip_header_factory_test, send_message_ten_times_test)
+{
+ bool use_tcp = false;
+ header_factory_test_client test_client_(use_tcp);
+ test_client_.init();
+ test_client_.start();
+ test_client_.join_sender_thread();
+}
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/header_factory_tests/header_factory_test_client.hpp b/test/header_factory_tests/header_factory_test_client.hpp
new file mode 100644
index 0000000..51803a1
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_client.hpp
@@ -0,0 +1,50 @@
+// Copyright (C) 2015 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 HEADERFACTORYTESTCLIENT_HPP_
+#define HEADERFACTORYTESTCLIENT_HPP_
+
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+
+#include "../someip_test_globals.hpp"
+
+class header_factory_test_client
+{
+public:
+ header_factory_test_client(bool _use_tcp);
+ void init();
+ void start();
+ void stop();
+ void join_sender_thread();
+ void on_event(vsomeip::event_type_e _event);
+ void on_availability(vsomeip::service_t _service,
+ vsomeip::instance_t _instance, bool _is_available);
+ void on_message(const std::shared_ptr<vsomeip::message> &_response);
+ void send();
+ void run();
+
+private:
+ std::shared_ptr<vsomeip::application> app_;
+ std::shared_ptr<vsomeip::message> request_;
+ bool use_tcp_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::thread sender_;
+ bool running_;
+ bool blocked_;
+ bool is_available_;
+ std::uint32_t number_of_messages_to_send_;
+ std::uint32_t number_of_sent_messages_;
+ std::uint32_t number_of_acknowledged_messages_;
+};
+
+#endif /* HEADERFACTORYTESTCLIENT_HPP_ */
diff --git a/test/header_factory_tests/header_factory_test_client.json b/test/header_factory_tests/header_factory_test_client.json
new file mode 100644
index 0000000..d0523b3
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_client.json
@@ -0,0 +1,98 @@
+{
+ "unicast" : "127.0.0.1",
+ "netmask" : "255.255.255.0",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "true",
+ "path" : "/var/log/vsomeip.log"
+ },
+
+ "dlt" : "true"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "header_factory_test_client",
+ "id" : "0x1343"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "remote",
+ "unicast" : "127.0.0.1",
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678",
+ "unreliable" : "30509",
+ "events" :
+ [
+ {
+ "event" : "0x0777",
+ "is_field" : "true"
+ },
+
+ {
+ "event" : "0x0778",
+ "is_field" : "false"
+ },
+
+ {
+ "event" : "0x0779",
+ "is_field" : "true"
+ }
+ ],
+
+ "eventgroups" :
+ [
+ {
+ "eventgroup" : "0x4455",
+ "events" :
+ [
+ "0x777",
+ "0x778"
+ ]
+ },
+
+ {
+ "eventgroup" : "0x4465",
+ "events" :
+ [
+ "0x778",
+ "0x779"
+ ],
+
+ "is_multicast" : "true"
+ },
+
+ {
+ "eventgroup" : "0x4555",
+ "events" :
+ [
+ "0x777",
+ "0x779"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+
+ "routing" : "header_factory_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30491",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/header_factory_tests/header_factory_test_client_start.sh b/test/header_factory_tests/header_factory_test_client_start.sh
new file mode 100755
index 0000000..d8696cb
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_client_start.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=header_factory_test_client
+export VSOMEIP_CONFIGURATION_FILE=header_factory_test_client.json
+./header_factory_test_client
diff --git a/test/header_factory_tests/header_factory_test_send_receive_starter.sh b/test/header_factory_tests/header_factory_test_send_receive_starter.sh
new file mode 100755
index 0000000..094dfd4
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_send_receive_starter.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Copyright (C) 2015 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_FILE=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_FILE=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/header_factory_tests/header_factory_test_service.cpp b/test/header_factory_tests/header_factory_test_service.cpp
new file mode 100644
index 0000000..cbdc5a6
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_service.cpp
@@ -0,0 +1,158 @@
+// Copyright (C) 2015 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 "header_factory_test_service.hpp"
+
+#include <cstdlib>
+
+header_factory_test_service::header_factory_test_service(bool _use_static_routing) :
+ app_(vsomeip::runtime::get()->create_application()),
+ is_registered_(false),
+ blocked_(false),
+ use_static_routing_(_use_static_routing),
+ offer_thread_(std::bind(&header_factory_test_service::run, this)),
+ number_of_received_messages_(0)
+{
+}
+
+void header_factory_test_service::init()
+{
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ app_->init();
+ app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
+ std::bind(&header_factory_test_service::on_message, this,
+ std::placeholders::_1));
+
+ app_->register_event_handler(
+ std::bind(&header_factory_test_service::on_event, this,
+ std::placeholders::_1));
+
+ VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF");
+}
+
+void header_factory_test_service::start()
+{
+ VSOMEIP_INFO << "Starting...";
+ app_->start();
+}
+
+void header_factory_test_service::stop()
+{
+ VSOMEIP_INFO << "Stopping...";
+ app_->unregister_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID);
+ app_->unregister_event_handler();
+ app_->stop();
+}
+
+void header_factory_test_service::join_offer_thread()
+{
+ offer_thread_.join();
+}
+
+void header_factory_test_service::offer()
+{
+ app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void header_factory_test_service::stop_offer()
+{
+ app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void header_factory_test_service::on_event(vsomeip::event_type_e _event)
+{
+ VSOMEIP_INFO << "Application " << app_->get_name() << " is "
+ << (_event == vsomeip::event_type_e::ET_REGISTERED ? "registered." :
+ "deregistered.");
+
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ if(!is_registered_)
+ {
+ is_registered_ = true;
+ blocked_ = true;
+ // "start" the run method thread
+ condition_.notify_one();
+ }
+ }
+ else
+ {
+ is_registered_ = false;
+ }
+}
+
+void header_factory_test_service::on_message(const std::shared_ptr<vsomeip::message>& _request)
+{
+ 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() << "]";
+
+ number_of_received_messages_++;
+
+ ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID);
+ ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID);
+
+ // Check the protocol version this shall be set to 0x01 according to the spec.
+ // TR_SOMEIP_00052
+ ASSERT_EQ(_request->get_protocol_version(), 0x01);
+ // Check the message type this shall be 0xx (REQUEST) according to the spec.
+ // TR_SOMEIP_00055
+ ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST);
+
+ // make sure the message was sent from the service
+ ASSERT_EQ(_request->get_client(), vsomeip_test::TEST_CLIENT_CLIENT_ID);
+
+ // check the session id.
+ ASSERT_EQ(_request->get_session(), static_cast<vsomeip::session_t>(number_of_received_messages_));
+
+
+ // send response
+ std::shared_ptr<vsomeip::message> its_response =
+ vsomeip::runtime::get()->create_response(_request);
+
+ app_->send(its_response, true);
+
+ if(number_of_received_messages_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND)
+ {
+ app_->stop();
+ }
+ ASSERT_LT(number_of_received_messages_,
+ vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1);
+}
+
+void header_factory_test_service::run()
+{
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ condition_.wait(its_lock);
+
+ if(use_static_routing_)
+ {
+ offer();
+ }
+}
+
+TEST(someip_header_factory_test, reveice_message_ten_times_test)
+{
+ bool use_static_routing = true;
+ header_factory_test_service test_service(use_static_routing);
+ test_service.init();
+ test_service.start();
+ test_service.join_offer_thread();
+}
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/header_factory_tests/header_factory_test_service.hpp b/test/header_factory_tests/header_factory_test_service.hpp
new file mode 100644
index 0000000..0c2df1c
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_service.hpp
@@ -0,0 +1,45 @@
+// Copyright (C) 2015 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 HEADERFACTORYTESTSERVICE_HPP_
+#define HEADERFACTORYTESTSERVICE_HPP_
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+
+#include "../someip_test_globals.hpp"
+
+class header_factory_test_service
+{
+public:
+ header_factory_test_service(bool _use_static_routing);
+ void init();
+ void start();
+ void stop();
+ void offer();
+ void stop_offer();
+ void join_offer_thread();
+ void on_event(vsomeip::event_type_e _event);
+ void on_message(const std::shared_ptr<vsomeip::message> &_request);
+ void run();
+
+private:
+ std::shared_ptr<vsomeip::application> app_;
+ bool is_registered_;
+ bool use_static_routing_;
+
+ std::thread offer_thread_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool blocked_;
+ std::uint32_t number_of_received_messages_;
+};
+
+#endif /* HEADERFACTORYTESTSERVICE_HPP_ */
diff --git a/test/header_factory_tests/header_factory_test_service.json b/test/header_factory_tests/header_factory_test_service.json
new file mode 100644
index 0000000..cb403cb
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_service.json
@@ -0,0 +1,118 @@
+{
+ "unicast" : "127.0.0.1",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "false",
+ "path" : "/tmp/vsomeip.log"
+ },
+
+ "dlt" : "false"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "header_factory_test_service",
+ "id" : "0x1277"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "default",
+ "delays" :
+ {
+ "initial" :
+ {
+ "minimum" : "10",
+ "maximum" : "100"
+ },
+
+ "repetition-base" : "200",
+ "repetition-max" : "3",
+ "cyclic-offer" : "2000",
+ "cyclic-request" : "2001"
+ },
+
+ "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"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+
+ "routing" : "header_factory_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30490",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/header_factory_tests/header_factory_test_service_start.sh b/test/header_factory_tests/header_factory_test_service_start.sh
new file mode 100755
index 0000000..e0e4c2d
--- /dev/null
+++ b/test/header_factory_tests/header_factory_test_service_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=header_factory_test_service
+export VSOMEIP_CONFIGURATION_FILE=header_factory_test_service.json
+./header_factory_test_service
diff --git a/test/magic-cookies-test-client.cpp b/test/magic-cookies-test-client.cpp
index b3b273e..a2f7681 100644
--- a/test/magic-cookies-test-client.cpp
+++ b/test/magic-cookies-test-client.cpp
@@ -1,5 +1,4 @@
-// Copyright (C) 2014 BMW Group
-// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// Copyright (C) 2015 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/.
@@ -58,9 +57,9 @@ public:
}
void on_event(vsomeip::event_type_e _event) {
- if (_event == vsomeip::event_type_e::REGISTERED) {
+ if (_event == vsomeip::event_type_e::ET_REGISTERED) {
VSOMEIP_INFO << "Client registration done.";
- app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
+ app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, false,
vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR,
vsomeip::ANY_TTL);
}
@@ -84,7 +83,7 @@ public:
}
}
- void on_message(std::shared_ptr< vsomeip::message > &_response) {
+ void on_message(const std::shared_ptr< vsomeip::message > &_response) {
VSOMEIP_INFO << "Received a response from Service ["
<< std::setw(4) << std::setfill('0') << std::hex << _response->get_service()
<< "."
diff --git a/test/magic_cookies_test_client_start.sh b/test/magic_cookies_test_client_start.sh
new file mode 100755
index 0000000..45ee754
--- /dev/null
+++ b/test/magic_cookies_test_client_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=client-sample
+export VSOMEIP_CONFIGURATION_FILE=vsomeip-magic-cookies-client.json
+./magic-cookies-test-client
diff --git a/test/magic_cookies_test_service_start.sh b/test/magic_cookies_test_service_start.sh
new file mode 100755
index 0000000..0d946ab
--- /dev/null
+++ b/test/magic_cookies_test_service_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=service-sample
+export VSOMEIP_CONFIGURATION_FILE=vsomeip-magic-cookies-service.json
+.././response-sample --tcp --static-routing
diff --git a/test/magic_cookies_test_starter.sh b/test/magic_cookies_test_starter.sh
new file mode 100755
index 0000000..c7ec3f7
--- /dev/null
+++ b/test/magic_cookies_test_starter.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# Copyright (C) 2015 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
+}
+
+# Display a message to show the user that he must now call the external service
+# to finish the test successfully
+cat <<End-of-message
+*******************************************************************************
+*******************************************************************************
+** Please now run:
+** magic_cookies_test_service_start.sh
+** from an external host to successfully complete this test.
+**
+** You probably will need to adapt the 'unicast' settings in
+** vsomeip-magic-cookies-client.json and
+** vsomeip-magic-cookies-service.json to your personal setup.
+**
+** As soon as the service is started please press any key to continue this test
+*******************************************************************************
+*******************************************************************************
+End-of-message
+read
+
+# Start the client for magic-cookies test
+export VSOMEIP_APPLICATION_NAME=client-sample
+export VSOMEIP_CONFIGURATION_FILE=vsomeip-magic-cookies-client.json
+./magic-cookies-test-client &
+CLIENT_PID=$!
+
+# Wait until client is 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 server exited sucessfully
+if [ $FAIL -eq 0 ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/test/payload_tests/external_local_payload_test_client_external.json b/test/payload_tests/external_local_payload_test_client_external.json
new file mode 100644
index 0000000..0f76ec0
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_client_external.json
@@ -0,0 +1,54 @@
+{
+ "unicast" : "172.16.100.131",
+ "netmask" : "255.255.255.0",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "true",
+ "path" : "/var/log/vsomeip.log"
+ },
+
+ "dlt" : "true"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "external_local_payload_test_client_external",
+ "id" : "0x1343"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "remote",
+ "unicast" : "134.86.56.183",
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678",
+ "unreliable" : "30509",
+ "reliable" :
+ {
+ "port" : "30510",
+ "enable-magic-cookies" : "false"
+ }
+ }
+ ]
+ }
+ ],
+
+ "routing" : "external_local_payload_test_client_external",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30491",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/payload_tests/external_local_payload_test_client_external_start.sh b/test/payload_tests/external_local_payload_test_client_external_start.sh
new file mode 100755
index 0000000..87d403a
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_client_external_start.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=external_local_payload_test_client_external
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_client_external.json
+./payload_test_client --udp --max-payload-size UDP
+# We sleep to let the service restart with --tcp option so we can test
+# communication via TCP.
+sleep 5
+./payload_test_client --tcp --max-payload-size TCP
diff --git a/test/payload_tests/external_local_payload_test_client_external_starter.sh b/test/payload_tests/external_local_payload_test_client_external_starter.sh
new file mode 100755
index 0000000..f5c6ca5
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_client_external_starter.sh
@@ -0,0 +1,116 @@
+#!/bin/bash
+# Copyright (C) 2015 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 for payload test with UDP
+export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_service.json
+./payload_test_service --udp &
+SERIVCE_PID=$!
+
+# Display a message to show the user that he must now call the external client
+# to finish the test successfully
+cat <<End-of-message
+*******************************************************************************
+*******************************************************************************
+** Please now run:
+** external_local_payload_test_client_external_start.sh
+** from an external host to successfully complete this test.
+**
+** You probably will need to adapt the 'unicast' settings in
+** external_local_payload_test_client_external.json and
+** external_local_payload_test_service.json to your personal setup.
+*******************************************************************************
+*******************************************************************************
+End-of-message
+
+# The service should listen on a TCP and UDP socket now
+sleep 1
+check_tcp_udp_sockets_are_open $SERIVCE_PID 2
+
+# Wait until service is finished
+# The client remotely shuts down the service if he has successfully transmitted
+# all the packets with different payloads. Therefore we can assume that everything
+# went well, even if we can only check the exit code of the service here.
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ wait $job || ((FAIL+=1))
+done
+
+# Start the service for payload test with tcp
+export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_service.json
+./payload_test_service --tcp &
+SERIVCE_PID=$!
+
+# The service should listen on a TCP and UDP socket now
+sleep 1
+check_tcp_udp_sockets_are_open $SERIVCE_PID 2
+
+
+# Wait until service is finished
+# The client remotely shuts down the service if he has successfully transmitted
+# all the packets with different payloads. Therefore we can assume that everything
+# went well, even if we can only check the exit code of the service here.
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ wait $job || ((FAIL+=1))
+done
+
+# Check if server exited sucessfully
+if [ $FAIL -eq 0 ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/test/payload_tests/external_local_payload_test_client_local.json b/test/payload_tests/external_local_payload_test_client_local.json
new file mode 100644
index 0000000..78ae45a
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_client_local.json
@@ -0,0 +1,54 @@
+{
+ "unicast" : "134.86.56.183",
+ "netmask" : "255.255.255.0",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "true",
+ "path" : "/var/log/vsomeip.log"
+ },
+
+ "dlt" : "true"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "external_local_payload_test_client_local",
+ "id" : "0x1343"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "remote",
+ "unicast" : "134.86.56.183",
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678",
+ "unreliable" : "30509",
+ "reliable" :
+ {
+ "port" : "30510",
+ "enable-magic-cookies" : "false"
+ }
+ }
+ ]
+ }
+ ],
+
+ "routing" : "external_local_payload_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30491",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh b/test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh
new file mode 100755
index 0000000..038ada5
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+# Copyright (C) 2015 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_FILE=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 which sends messages over local UDS
+export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_client_local.json
+./payload_test_client --dont-shutdown-service &
+CLIENT_PID=$!
+sleep 1
+
+check_tcp_udp_sockets_are_open $SERIVCE_PID 2
+check_tcp_udp_sockets_are_closed $CLIENT_PID
+
+# Wait until client is finished
+wait $CLIENT_PID || ((FAIL+=1))
+
+# Display a message to show the user that he must now call the external client
+# to finish the test successfully
+cat <<End-of-message
+*******************************************************************************
+*******************************************************************************
+** Please now run:
+** external_local_payload_test_client_external_start.sh
+** from an external host to successfully complete this test.
+**
+** You probably will need to adapt the 'unicast' settings in
+** external_local_payload_test_client_external.json and
+** external_local_payload_test_service.json to your personal setup.
+*******************************************************************************
+*******************************************************************************
+End-of-message
+
+# The service should still listen on a TCP and UDP socket
+sleep 1
+check_tcp_udp_sockets_are_open $SERIVCE_PID 2
+
+# Wait until service is finished
+# The client remotely shuts down the service if he has successfully transmitted
+# all the packets with different payloads. Therefore we can assume that everything
+# went well, even if we can only check the exit code of the service here.
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ wait $job || ((FAIL+=1))
+done
+
+# Start the service for payload test with tcp
+export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_service.json
+./payload_test_service --tcp &
+SERIVCE_PID=$!
+
+# The service should listen on a TCP and UDP socket now
+sleep 1
+check_tcp_udp_sockets_are_open $SERIVCE_PID 2
+
+
+# Wait until service is finished
+# The client remotely shuts down the service if he has successfully transmitted
+# all the packets with different payloads. Therefore we can assume that everything
+# went well, even if we can only check the exit code of the service here.
+for job in $(jobs -p)
+do
+ # Fail gets incremented if either client or service exit
+ # with a non-zero exit code
+ wait $job || ((FAIL+=1))
+done
+
+# Check if client and server both exited sucessfully and the service didnt't
+# have any open TCP/UDP sockets
+if [ $FAIL -eq 0 ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/test/payload_tests/external_local_payload_test_client_local_start.sh b/test/payload_tests/external_local_payload_test_client_local_start.sh
new file mode 100755
index 0000000..fbf2633
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_client_local_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=external_local_payload_test_client_local
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_client_local.json
+./payload_test_client
diff --git a/test/payload_tests/external_local_payload_test_client_local_starter.sh b/test/payload_tests/external_local_payload_test_client_local_starter.sh
new file mode 100755
index 0000000..1c0ecbe
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_client_local_starter.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+# Copyright (C) 2015 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_FILE=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_FILE=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
+
+# 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/payload_tests/external_local_payload_test_service.json b/test/payload_tests/external_local_payload_test_service.json
new file mode 100644
index 0000000..517b897
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_service.json
@@ -0,0 +1,67 @@
+{
+ "unicast" : "134.86.56.183",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "false",
+ "path" : "/tmp/vsomeip.log"
+ },
+
+ "dlt" : "false"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "external_local_payload_test_service",
+ "id" : "0x1277"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "default",
+ "unicast" : "local",
+ "delays" :
+ {
+ "initial" :
+ {
+ "minimum" : "10",
+ "maximum" : "100"
+ },
+
+ "repetition-base" : "200",
+ "repetition-max" : "3",
+ "cyclic-offer" : "2000",
+ "cyclic-request" : "2001"
+ },
+
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678",
+ "unreliable" : "30509",
+ "reliable" :
+ {
+ "port" : "30510",
+ "enable-magic-cookies" : "false"
+ }
+ }
+ ]
+ }
+ ],
+
+ "routing" : "external_local_payload_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30490",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/payload_tests/external_local_payload_test_service_client_external_start.sh b/test/payload_tests/external_local_payload_test_service_client_external_start.sh
new file mode 100755
index 0000000..4230216
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_service_client_external_start.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=external_local_payload_test_service
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_service.json
+./payload_test_service --udp
+# After payload was measured with UDP the client will restart and measure
+# throughput with TCP
+./payload_test_service --tcp \ No newline at end of file
diff --git a/test/payload_tests/external_local_payload_test_service_start.sh b/test/payload_tests/external_local_payload_test_service_start.sh
new file mode 100755
index 0000000..e1dc27d
--- /dev/null
+++ b/test/payload_tests/external_local_payload_test_service_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=external_local_payload_test_service
+export VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_service.json
+./payload_test_service
diff --git a/test/payload_tests/local_payload_test_client.json b/test/payload_tests/local_payload_test_client.json
new file mode 100644
index 0000000..8ac8e79
--- /dev/null
+++ b/test/payload_tests/local_payload_test_client.json
@@ -0,0 +1,45 @@
+{
+ "unicast" : "127.0.0.1",
+ "netmask" : "255.255.255.0",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "true",
+ "path" : "/var/log/vsomeip.log"
+ },
+
+ "dlt" : "true"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "local_payload_test_client",
+ "id" : "0x1343"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "remote",
+ "unicast" : "127.0.0.1",
+ "services" :
+ [
+
+ ]
+ }
+ ],
+
+ "routing" : "local_payload_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30491",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/payload_tests/local_payload_test_client_start.sh b/test/payload_tests/local_payload_test_client_start.sh
new file mode 100755
index 0000000..38c6e2a
--- /dev/null
+++ b/test/payload_tests/local_payload_test_client_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=local_payload_test_client
+export VSOMEIP_CONFIGURATION_FILE=local_payload_test_client.json
+./payload_test_client
diff --git a/test/payload_tests/local_payload_test_service.json b/test/payload_tests/local_payload_test_service.json
new file mode 100644
index 0000000..776881c
--- /dev/null
+++ b/test/payload_tests/local_payload_test_service.json
@@ -0,0 +1,61 @@
+{
+ "unicast" : "134.86.56.183",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "false",
+ "path" : "/tmp/vsomeip.log"
+ },
+
+ "dlt" : "false"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "local_payload_test_service",
+ "id" : "0x1277"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "default",
+ "unicast" : "local",
+ "delays" :
+ {
+ "initial" :
+ {
+ "minimum" : "10",
+ "maximum" : "100"
+ },
+
+ "repetition-base" : "200",
+ "repetition-max" : "3",
+ "cyclic-offer" : "2000",
+ "cyclic-request" : "2001"
+ },
+
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678"
+ }
+ ]
+ }
+ ],
+
+ "routing" : "local_payload_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30490",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/payload_tests/local_payload_test_service_start.sh b/test/payload_tests/local_payload_test_service_start.sh
new file mode 100755
index 0000000..a514e3a
--- /dev/null
+++ b/test/payload_tests/local_payload_test_service_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=local_payload_test_service
+export VSOMEIP_CONFIGURATION_FILE=local_payload_test_service.json
+./payload_test_service
diff --git a/test/payload_tests/local_payload_test_starter.sh b/test/payload_tests/local_payload_test_starter.sh
new file mode 100755
index 0000000..930da96
--- /dev/null
+++ b/test/payload_tests/local_payload_test_starter.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# Copyright (C) 2015 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_FILE=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_FILE=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/payload_tests/payload_test_client.cpp b/test/payload_tests/payload_test_client.cpp
new file mode 100644
index 0000000..6151452
--- /dev/null
+++ b/test/payload_tests/payload_test_client.cpp
@@ -0,0 +1,391 @@
+// Copyright (C) 2015 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 "payload_test_client.hpp"
+
+enum class payloadsize
+ : std::uint8_t
+ {
+ UDS, TCP, UDP
+};
+
+// this variables are changed via cmdline parameters
+static bool use_tcp = false;
+static bool call_service_sync = true;
+static std::uint32_t sliding_window_size = vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS;
+static payloadsize max_payload_size = payloadsize::UDS;
+static bool shutdown_service_at_end = true;
+
+
+payload_test_client::payload_test_client(
+ bool _use_tcp,
+ bool _call_service_sync,
+ std::uint32_t _sliding_window_size) :
+ app_(vsomeip::runtime::get()->create_application()),
+ request_(vsomeip::runtime::get()->create_request(_use_tcp)),
+ call_service_sync_(_call_service_sync),
+ sliding_window_size_(_sliding_window_size),
+ sender_(std::bind(&payload_test_client::run, this)),
+ blocked_(false),
+ is_available_(false),
+ number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS),
+ number_of_sent_messages_(0),
+ number_of_sent_messages_total_(0),
+ number_of_acknowledged_messages_(0),
+ current_payload_size_(1),
+ all_msg_acknowledged_(false)
+{
+}
+
+void payload_test_client::init()
+{
+ app_->init();
+
+ app_->register_event_handler(
+ std::bind(&payload_test_client::on_event, this,
+ std::placeholders::_1));
+
+ app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID,
+ std::bind(&payload_test_client::on_availability, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3));
+
+ app_->register_message_handler(vsomeip::ANY_SERVICE,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD,
+ std::bind(&payload_test_client::on_message, this,
+ std::placeholders::_1));
+
+ 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);
+}
+
+void payload_test_client::start()
+{
+ VSOMEIP_INFO << "Starting...";
+ app_->start();
+}
+
+void payload_test_client::stop()
+{
+ VSOMEIP_INFO << "Stopping...";
+ // shutdown the service
+ if(shutdown_service_at_end)
+ {
+ shutdown_service();
+ }
+ app_->unregister_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+ app_->unregister_event_handler();
+ app_->unregister_message_handler(vsomeip::ANY_SERVICE,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD);
+
+ app_->stop();
+}
+
+void payload_test_client::shutdown_service()
+{
+ 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_SHUTDOWN);
+ app_->send(request_,true);
+}
+
+void payload_test_client::join_sender_thread()
+{
+ sender_.join();
+}
+
+void payload_test_client::on_event(vsomeip::event_type_e _event)
+{
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, false);
+ }
+}
+
+void payload_test_client::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.");
+
+ if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service
+ && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance)
+ {
+ if(is_available_ && !_is_available)
+ {
+ is_available_ = false;
+ }
+ else if(_is_available && !is_available_)
+ {
+ is_available_ = true;
+ send();
+ }
+ }
+}
+
+void payload_test_client::on_message(const std::shared_ptr<vsomeip::message>& _response)
+{
+ number_of_acknowledged_messages_++;
+
+ ASSERT_EQ(_response->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID);
+ ASSERT_EQ(_response->get_instance(), vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+ ASSERT_EQ(_response->get_client(), vsomeip_test::TEST_CLIENT_CLIENT_ID);
+
+ if(call_service_sync_)
+ {
+ // We notify the sender thread every time a message was acknowledged
+ {
+ std::lock_guard<std::mutex> lk(all_msg_acknowledged_mutex_);
+ all_msg_acknowledged_ = true;
+ }
+ all_msg_acknowledged_cv_.notify_one();
+ }
+ else
+ {
+ // We notify the sender thread only if all sent messages have been acknowledged
+ if(number_of_acknowledged_messages_ % sliding_window_size == 0)
+ {
+ std::lock_guard<std::mutex> lk(all_msg_acknowledged_mutex_);
+ all_msg_acknowledged_ = true;
+ all_msg_acknowledged_cv_.notify_one();
+ }
+ if(number_of_acknowledged_messages_ == number_of_messages_to_send_)
+ {
+ std::lock_guard<std::mutex> lk(all_msg_acknowledged_mutex_);
+ number_of_acknowledged_messages_ = 0;
+ all_msg_acknowledged_ = true;
+ all_msg_acknowledged_cv_.notify_one();
+ }
+ }
+}
+
+void payload_test_client::send()
+{
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ blocked_ = true;
+ condition_.notify_one();
+}
+
+void payload_test_client::run()
+{
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ {
+ condition_.wait(its_lock);
+ }
+
+ // lock the mutex
+ std::unique_lock<std::mutex> lk(all_msg_acknowledged_mutex_);
+
+ std::uint32_t max_allowed_payload = get_max_allowed_payload();
+
+ std::shared_ptr<vsomeip::payload> payload = vsomeip::runtime::get()->create_payload();
+ std::vector<vsomeip::byte_t> payload_data;
+ bool lastrun = false;
+ while (current_payload_size_ <= max_allowed_payload)
+ {
+ payload_data.assign(current_payload_size_ , vsomeip_test::PAYLOAD_TEST_DATA);
+ payload->set_data(payload_data);
+ request_->set_payload(payload);
+
+ watch_.reset();
+ watch_.start();
+
+ call_service_sync_ ? send_messages_sync(lk) : send_messages_async(lk);
+
+ watch_.stop();
+ print_throughput();
+
+ // Increase array size for next iteration
+ current_payload_size_ *= 2;
+
+ //special case to test the biggest payload possible as last test
+ // 16 Bytes are reserved for the SOME/IP header
+ if(current_payload_size_ > max_allowed_payload - 16 && !lastrun)
+ {
+ current_payload_size_ = max_allowed_payload - 16;
+ lastrun = true;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(500));
+ }
+ blocked_ = false;
+
+ stop();
+}
+
+
+std::uint32_t payload_test_client::get_max_allowed_payload()
+{
+ std::uint32_t payload;
+ switch (max_payload_size)
+ {
+ case payloadsize::UDS:
+ payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
+ break;
+ case payloadsize::TCP:
+ payload = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+ break;
+ case payloadsize::UDP:
+ payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
+ break;
+ default:
+ payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
+ break;
+ }
+ return payload;
+}
+
+void payload_test_client::send_messages_sync(std::unique_lock<std::mutex>& lk)
+{
+ for (number_of_sent_messages_ = 0;
+ number_of_sent_messages_ < number_of_messages_to_send_;
+ number_of_sent_messages_++, number_of_sent_messages_total_++)
+ {
+ app_->send(request_, true);
+ // wait until the send messages has been acknowledged
+ // as long we wait lk is released; after wait returns lk is reacquired
+ all_msg_acknowledged_cv_.wait(lk, [&]
+ { return all_msg_acknowledged_;});
+ // Reset condition variable (lk is locked again here)
+ all_msg_acknowledged_ = false;
+ }
+}
+
+void payload_test_client::send_messages_async(std::unique_lock<std::mutex>& lk)
+{
+ for (number_of_sent_messages_ = 0;
+ number_of_sent_messages_ < number_of_messages_to_send_;
+ number_of_sent_messages_++, number_of_sent_messages_total_++)
+ {
+ app_->send(request_, true);
+
+ if((number_of_sent_messages_+1) % sliding_window_size == 0)
+ {
+ // wait until all send messages have been acknowledged
+ // as long we wait lk is released; after wait returns lk is reacquired
+ all_msg_acknowledged_cv_.wait(lk, [&]
+ { return all_msg_acknowledged_;});
+
+ // Reset condition variable
+ all_msg_acknowledged_ = false;
+ }
+ }
+}
+
+void payload_test_client::print_throughput()
+{
+ constexpr std::uint32_t usec_per_sec = 1000000;
+ stop_watch::usec_t time_needed = watch_.get_total_elapsed_microseconds();
+ stop_watch::usec_t time_per_message = time_needed / number_of_sent_messages_;
+ std::double_t calls_per_sec = number_of_sent_messages_
+ * (usec_per_sec / static_cast<double>(time_needed));
+ std::double_t kbyte_per_sec = ((number_of_sent_messages_
+ * current_payload_size_)
+ / (static_cast<double>(time_needed) / usec_per_sec)) / 1024;
+
+ VSOMEIP_INFO<< "[ Payload Test ] : :"
+ << "Payload size [byte]: " << std::setw(8) << std::setfill('0') << current_payload_size_
+ << " Messages sent: " << std::setw(8) << std::setfill('0') << number_of_sent_messages_
+ << " Meantime/message [usec]: " << std::setw(8) << std::setfill('0') << time_per_message
+ << " Calls/sec: " << std::setw(8) << std::setfill('0') << calls_per_sec
+ << " KiB/sec: " << std::setw(8) << std::setfill('0') << kbyte_per_sec;
+}
+
+TEST(someip_payload_test, send_different_payloads)
+{
+ payload_test_client test_client_(use_tcp, call_service_sync, sliding_window_size);
+ test_client_.init();
+ test_client_.start();
+ test_client_.join_sender_thread();
+}
+
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ std::string tcp_enable("--tcp");
+ std::string udp_enable("--udp");
+ std::string sync_enable("--sync");
+ std::string async_enable("--async");
+ std::string sliding_window_size_param("--sliding-window-size");
+ std::string max_payload_size_param("--max-payload-size");
+ std::string shutdown_service_disable_param("--dont-shutdown-service");
+ std::string help("--help");
+
+ int i = 1;
+ while (i < argc)
+ {
+ if(tcp_enable == argv[i])
+ {
+ use_tcp = true;
+ }
+ else if(udp_enable == argv[i])
+ {
+ use_tcp = false;
+ }
+ else if(sync_enable == argv[i])
+ {
+ call_service_sync = true;
+ }
+ else if(async_enable == argv[i])
+ {
+ call_service_sync = false;
+ }
+ else if(sliding_window_size_param == argv[i] && i + 1 < argc)
+ {
+ i++;
+ std::stringstream converter(argv[i]);
+ converter >> sliding_window_size;
+ }
+ else if(max_payload_size_param == argv[i] && i + 1 < argc)
+ {
+ i++;
+ if(std::string("UDS") == argv[i])
+ {
+ max_payload_size = payloadsize::UDS;
+ }
+ else if(std::string("TCP") == argv[i])
+ {
+ max_payload_size = payloadsize::TCP;
+ }
+ else if(std::string("UDP") == argv[i])
+ {
+ max_payload_size = payloadsize::UDP;
+ }
+ }
+ else if(shutdown_service_disable_param == argv[i])
+ {
+ shutdown_service_at_end = false;
+ }
+ else if(help == argv[i])
+ {
+ VSOMEIP_INFO << "Parameters:\n"
+ << "--tcp: Send messages via TCP\n"
+ << "--udp: Send messages via UDP (default)\n"
+ << "--sync: Wait for acknowledge before sending next message (default)\n"
+ << "--async: Send multiple messages w/o waiting for"
+ " acknowledge of service\n"
+ << "--sliding-window-size: Number of messages to send before waiting "
+ "for acknowledge of service. Default: " << sliding_window_size << "\n"
+ << "--max-payload-size: limit the maximum payloadsize of send requests. One of {"
+ "UDS (=" << VSOMEIP_MAX_LOCAL_MESSAGE_SIZE << "byte), "
+ "UDP (=" << VSOMEIP_MAX_UDP_MESSAGE_SIZE << "byte), "
+ "TCP (=" << VSOMEIP_MAX_TCP_MESSAGE_SIZE << "byte)}, default: UDS\n"
+ << "--dont-shutdown-service: Don't shutdown the service upon "
+ "finishing of the payload test\n"
+ << "--help: print this help";
+ }
+ i++;
+ }
+
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/payload_tests/payload_test_client.hpp b/test/payload_tests/payload_test_client.hpp
new file mode 100644
index 0000000..9511560
--- /dev/null
+++ b/test/payload_tests/payload_test_client.hpp
@@ -0,0 +1,69 @@
+// Copyright (C) 2015 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 PAYLOADTESTCLIENT_HPP_
+#define PAYLOADTESTCLIENT_HPP_
+
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+
+#include "../someip_test_globals.hpp"
+
+#include "stopwatch.hpp"
+
+class payload_test_client
+{
+public:
+ payload_test_client(bool _use_tcp, bool _call_service_sync, std::uint32_t _sliding_window_size);
+ void init();
+ void start();
+ void stop();
+ void join_sender_thread();
+ void on_event(vsomeip::event_type_e _event);
+ void on_availability(vsomeip::service_t _service,
+ vsomeip::instance_t _instance, bool _is_available);
+ void on_message(const std::shared_ptr<vsomeip::message> &_response);
+ void send();
+ void run();
+
+private:
+ void print_throughput();
+ void send_messages_sync(std::unique_lock<std::mutex>& lk);
+ void send_messages_async(std::unique_lock<std::mutex>& lk);
+ void shutdown_service();
+ std::uint32_t get_max_allowed_payload();
+
+private:
+ std::shared_ptr<vsomeip::application> app_;
+ std::shared_ptr<vsomeip::message> request_;
+ bool call_service_sync_;
+ std::uint32_t sliding_window_size_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::thread sender_;
+ bool blocked_;
+ bool is_available_;
+ const std::uint32_t number_of_messages_to_send_;
+ std::uint32_t number_of_sent_messages_;
+ std::uint32_t number_of_sent_messages_total_;
+ std::uint32_t number_of_acknowledged_messages_;
+
+ std::uint32_t current_payload_size_;
+
+ stop_watch watch_;
+
+ bool all_msg_acknowledged_;
+ std::mutex all_msg_acknowledged_mutex_;
+ std::condition_variable all_msg_acknowledged_cv_;
+
+};
+
+#endif /* PAYLOADTESTCLIENT_HPP_ */
diff --git a/test/payload_tests/payload_test_service.cpp b/test/payload_tests/payload_test_service.cpp
new file mode 100644
index 0000000..b8ae72f
--- /dev/null
+++ b/test/payload_tests/payload_test_service.cpp
@@ -0,0 +1,177 @@
+// Copyright (C) 2015 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 "payload_test_service.hpp"
+
+// this variables are changed via cmdline parameters
+static bool use_tcp = false;
+
+payload_test_service::payload_test_service(bool _use_tcp) :
+ app_(vsomeip::runtime::get()->create_application()),
+ is_registered_(false),
+ use_tcp_(_use_tcp),
+ offer_thread_(std::bind(&payload_test_service::run, this)),
+ blocked_(false),
+ number_of_received_messages_(0)
+{
+}
+
+void payload_test_service::init()
+{
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ app_->init();
+ app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
+ std::bind(&payload_test_service::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_METHOD_ID_SHUTDOWN,
+ std::bind(&payload_test_service::on_message_shutdown, this,
+ std::placeholders::_1));
+
+ app_->register_event_handler(
+ std::bind(&payload_test_service::on_event, this,
+ std::placeholders::_1));
+}
+
+void payload_test_service::start()
+{
+ VSOMEIP_INFO << "Starting...";
+ app_->start();
+}
+
+void payload_test_service::stop()
+{
+ VSOMEIP_INFO << "Stopping...";
+ app_->unregister_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID);
+ app_->unregister_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN);
+ app_->unregister_event_handler();
+ app_->stop();
+}
+
+void payload_test_service::join_offer_thread()
+{
+ offer_thread_.join();
+}
+
+void payload_test_service::offer()
+{
+ app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void payload_test_service::stop_offer()
+{
+ app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void payload_test_service::on_event(vsomeip::event_type_e _event)
+{
+ VSOMEIP_INFO << "Application " << app_->get_name() << " is "
+ << (_event == vsomeip::event_type_e::ET_REGISTERED ? "registered." :
+ "deregistered.");
+
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ if(!is_registered_)
+ {
+ is_registered_ = true;
+ blocked_ = true;
+ // "start" the run method thread
+ condition_.notify_one();
+ }
+ }
+ else
+ {
+ is_registered_ = false;
+ }
+}
+
+void payload_test_service::on_message(const std::shared_ptr<vsomeip::message>& _request)
+{
+ number_of_received_messages_++;
+ if(number_of_received_messages_ % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS == 0)
+ {
+ 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() << "]";
+ }
+
+ ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID);
+ ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID);
+
+ // Check the protocol version this shall be set to 0x01 according to the spec.
+ // TR_SOMEIP_00052
+ ASSERT_EQ(_request->get_protocol_version(), 0x01);
+ // Check the message type this shall be 0xx (REQUEST) according to the spec.
+ // TR_SOMEIP_00055
+ ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST);
+
+ // make sure the message was sent from the service
+ ASSERT_EQ(_request->get_client(), vsomeip_test::TEST_CLIENT_CLIENT_ID);
+
+ std::shared_ptr<vsomeip::payload> pl = _request->get_payload();
+ vsomeip::byte_t* pl_ptr = pl->get_data();
+ for (int i = 0; i < pl->get_length(); i++)
+ {
+ ASSERT_EQ(*(pl_ptr+i), vsomeip_test::PAYLOAD_TEST_DATA);
+ }
+
+ // send response
+ std::shared_ptr<vsomeip::message> its_response =
+ vsomeip::runtime::get()->create_response(_request);
+
+ app_->send(its_response, true);
+}
+
+void payload_test_service::on_message_shutdown(
+ const std::shared_ptr<vsomeip::message>& _request)
+{
+ VSOMEIP_INFO << "Shutdown method was called, going down now.";
+ stop();
+}
+
+void payload_test_service::run()
+{
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ condition_.wait(its_lock);
+
+ offer();
+}
+
+TEST(someip_payload_test, send_response_for_every_request)
+{
+ payload_test_service test_service(use_tcp);
+ test_service.init();
+ test_service.start();
+ test_service.join_offer_thread();
+}
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ std::string help("--help");
+
+ int i = 1;
+ while (i < argc)
+ {
+ if(help == argv[i])
+ {
+ VSOMEIP_INFO << "Parameters:\n"
+ << "--help: print this help";
+ }
+ i++;
+ }
+
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/payload_tests/payload_test_service.hpp b/test/payload_tests/payload_test_service.hpp
new file mode 100644
index 0000000..4255fc3
--- /dev/null
+++ b/test/payload_tests/payload_test_service.hpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2015 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 PAYLOADTESTSERVICE_HPP_
+#define PAYLOADTESTSERVICE_HPP_
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+
+#include "../someip_test_globals.hpp"
+
+class payload_test_service
+{
+public:
+ payload_test_service(bool _use_tcp);
+ void init();
+ void start();
+ void stop();
+ void offer();
+ void stop_offer();
+ void join_offer_thread();
+ void on_event(vsomeip::event_type_e _event);
+ void on_message(const std::shared_ptr<vsomeip::message> &_request);
+ void on_message_shutdown(const std::shared_ptr<vsomeip::message> &_request);
+ void run();
+
+private:
+ std::shared_ptr<vsomeip::application> app_;
+ bool is_registered_;
+ bool use_tcp_;
+ bool use_static_routing_;
+
+ std::thread offer_thread_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool blocked_;
+ std::uint32_t number_of_received_messages_;
+};
+
+#endif /* PAYLOADTESTSERVICE_HPP_ */
diff --git a/test/payload_tests/stopwatch.cpp b/test/payload_tests/stopwatch.cpp
new file mode 100644
index 0000000..13701a3
--- /dev/null
+++ b/test/payload_tests/stopwatch.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2015 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 "stopwatch.hpp"
+
+#include <cassert>
+#include <ctime>
+
+
+#define USEC_PER_SEC 1000000ULL
+#define NSEC_PER_USEC 1000ULL
+
+
+stop_watch::usec_t stop_watch::get_total_elapsed_microseconds() const {
+ usec_t elapsed = total_elapsed_;
+
+ if (started_)
+ elapsed += get_elapsed();
+
+ return elapsed;
+}
+
+stop_watch::usec_t stop_watch::get_total_elapsed_seconds() const {
+ return get_total_elapsed_microseconds() / USEC_PER_SEC;
+}
+
+stop_watch::usec_t stop_watch::now() {
+ struct timespec ts;
+
+ assert(!clock_gettime(CLOCK_MONOTONIC_RAW, &ts));
+
+ return (usec_t) ts.tv_sec * USEC_PER_SEC + (usec_t) ts.tv_nsec / NSEC_PER_USEC;
+}
+
diff --git a/test/payload_tests/stopwatch.hpp b/test/payload_tests/stopwatch.hpp
new file mode 100644
index 0000000..fa6bbe8
--- /dev/null
+++ b/test/payload_tests/stopwatch.hpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2015 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 STOP_WATCH_H_
+#define STOP_WATCH_H_
+
+#include <cstdint>
+
+
+class stop_watch
+{
+public:
+ typedef uint64_t usec_t;
+
+ stop_watch() :
+ started_(false),
+ total_elapsed_(0),
+ start_time_point_(0)
+ {
+ }
+
+ inline void reset()
+ {
+ started_ = false;
+ total_elapsed_ = 0;
+ }
+
+ inline void start()
+ {
+ start_time_point_ = now();
+ started_ = true;
+ }
+
+ inline void stop()
+ {
+ total_elapsed_ += get_elapsed();
+ started_ = false;
+ }
+
+ usec_t get_total_elapsed_microseconds() const;
+ usec_t get_total_elapsed_seconds() const;
+
+private:
+ inline usec_t get_elapsed() const
+ {
+ return now() - start_time_point_;
+ }
+
+ static usec_t now();
+
+ bool started_;
+ usec_t start_time_point_;
+ usec_t total_elapsed_;
+};
+
+#endif // STOP_WATCH_H_
diff --git a/test/readme.txt b/test/readme.txt
index b69cea9..3aa1da0 100644
--- a/test/readme.txt
+++ b/test/readme.txt
@@ -84,3 +84,173 @@ The expected result is an output like this on service side:
2015-02-10 08:42:07.361558 [info] Received a message with Client/Session [1343/000d]
2015-02-10 08:42:07.361672 [error] Detected Magic Cookie within message data. Resyncing.
2015-02-10 08:42:07.361761 [info] Received a message with Client/Session [1343/000f]
+
+Header Factory Tests
+--------------------
+
+The following things are tested:
+a) create request
+ --> check "Protocol Version" / "Message Type" / "Return Type" fields
+b) create request, fill header, create response
+ --> compare header fields of request & response
+c) create notification
+ --> check "Protocol Version" / "Message Type" / "Return Type" fields
+d) create message, fill header (service/instance/method/interface version/message type)
+ --> send message 10 times
+ --> receive message and check client id / session id
+
+a) to c) are combined in one binary. d) is composed out of a client and service.
+
+To start the header factory tests from the build directory do:
+
+Automatic start from build directory:
+ctest -V -R header_factory_test
+
+Manual start from build directory:
+cd test
+./header_factory_test
+# Start client and service separately
+./header_factory_test_service_start.sh &
+./header_factory_test_client_start.sh
+# Alternatively start client and service with one script
+./header_factory_test_send_receive_starter.sh
+
+All tests should be marked as "passed".
+
+Routing Tests
+-------------
+
+The following things are tested:
+a) create a service instance
+ - check that it is accessible from a local client but invisible for an external client
+b) create a service instance, configure it to be externally visible
+ - check that it is accessible from a local client and from a external client
+
+a) and b) are composed out of a service each and one common client binary which is used
+with different configuration files.
+
+Automatic start from build directory:
+
+ctest -V -R local_routing_test
+
+A message will be shown when the external client should be started.
+
+Manual start from build directory:
+cd test
+# First part with local client
+# Start client and service with one script
+./local_routing_test_starter.sh
+
+# Alternatively start client and service separately
+# Warning some checks are done within the *_starter.sh script.
+# This should only be used for debugging
+# Start the service
+./local_routing_test_service_start.sh &
+# Start the client
+./local_routing_test_client_start.sh
+
+# Second part with external client
+# Start client and service with one script
+./external_local_routing_test_starter.sh
+# Start the external client from an external host when the message is displayed to start it
+./external_local_routing_test_client_external_start.sh
+
+# Alternatively start client and service separately
+# Warning some checks are done within the *_starter.sh script.
+# This should only be used for debugging
+# Start the service
+./external_local_routing_test_service_start.sh &
+# Start the client
+./local_routing_test_client_start.sh
+# Start the external client from an external host after local client has finished
+./external_local_routing_test_client_external_start.sh
+
+
+All tests should be marked as "passed".
+
+Payload Tests
+-------------
+
+The following things are tested:
+a) create a local service
+ - send messages with payloads of different size from a local client to the service
+ - check that the messages are received correctly
+ - measure the throughput
+b) create a service instance, configure it to be externally visible
+ - send messages with payloads of different size from a local client to the service
+ - check that the messages are received correctly
+ - measure the throughput
+c) create a service instance, configure it to be externally visible
+ - send messages with payloads of different size from an external client to the service
+ - check that the messages are received correctly
+ - measure the throughput
+d) create a service instance, configure it to be externally visible
+ - send messages with payloads of different size from a local client to the service
+ - send messages with payloads of different size from an external client to the service
+ - check that the messages are received correctly
+ - measure the throughput
+
+The tests a) to d) are composed out of a service and a client binary which are called
+with different configuration files and parameters.
+
+Automatic start from build directory:
+
+ctest -V -R payload_test
+
+A message will be shown when the external clients should be started.
+
+Manual start from build directory:
+cd test
+
+# First part with local client
+# start client and service with one script
+./local_payload_test_starter.sh
+
+# Alternatively start client and service separately
+# Warning some checks are done within the *_starter.sh script.
+# This should only be used for debugging
+./local_payload_test_service_start.sh &
+./local_payload_test_client_start.sh
+
+# Second part with external visible service and local client
+# start client and service with one script
+./external_local_payload_test_client_local_starter.sh
+
+# Alternatively start client and service separately
+# Warning some checks are done within the *_starter.sh script.
+# This should only be used for debugging
+./external_local_payload_test_service_start.sh &
+./external_local_payload_test_client_local_start.sh
+
+# Third part with external visible service and external client
+# start client and service with one script
+./external_local_payload_test_client_external_starter.sh
+# Start the external client from an external host if asked to
+./external_local_payload_test_client_external_start.sh
+
+# Alternatively start client and service separately
+# Warning some checks are done within the *_starter.sh script.
+# This should only be used for debugging
+./external_local_payload_test_service_client_external_start.sh
+# Start the external client from an external host
+./external_local_payload_test_client_external_start.sh
+
+# Fourth part with external visible service and local and external client
+# start client and service with one script
+./external_local_payload_test_client_local_and_external_starter.sh
+# Start the external client from an external host if asked to
+./external_local_payload_test_client_external_start.sh
+
+# Alternatively start client and service separately
+# Warning some checks are done within the *_starter.sh script.
+# This should only be used for debugging
+./external_local_payload_test_service_client_external_start.sh &
+# Start the local client
+VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local \
+VSOMEIP_CONFIGURATION_FILE=external_local_payload_test_client_local.json \
+./payload_test_client --dont-shutdown-service
+# Start the external client after the local client is finished from an
+# external host
+./external_local_payload_test_client_external_start.sh
+
+All tests should be marked as "passed".
diff --git a/test/routing_tests/external_local_routing_test_client_external.json b/test/routing_tests/external_local_routing_test_client_external.json
new file mode 100644
index 0000000..fb33ae8
--- /dev/null
+++ b/test/routing_tests/external_local_routing_test_client_external.json
@@ -0,0 +1,49 @@
+{
+ "unicast" : "172.16.100.131",
+ "netmask" : "255.255.255.0",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "true",
+ "path" : "/var/log/vsomeip.log"
+ },
+
+ "dlt" : "true"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "external_local_routing_test_client_external",
+ "id" : "0x1344"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "remote",
+ "unicast" : "134.86.56.183",
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678",
+ "unreliable" : "30509"
+ }
+ ]
+ }
+ ],
+
+ "routing" : "external_local_routing_test_client_external",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30491",
+ "protocol" : "udp"
+ }
+}
diff --git a/test/routing_tests/external_local_routing_test_client_external_start.sh b/test/routing_tests/external_local_routing_test_client_external_start.sh
new file mode 100755
index 0000000..44b5187
--- /dev/null
+++ b/test/routing_tests/external_local_routing_test_client_external_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=external_local_routing_test_client_external
+export VSOMEIP_CONFIGURATION_FILE=external_local_routing_test_client_external.json
+./local_routing_test_client
diff --git a/test/routing_tests/external_local_routing_test_service.cpp b/test/routing_tests/external_local_routing_test_service.cpp
new file mode 100644
index 0000000..2553898
--- /dev/null
+++ b/test/routing_tests/external_local_routing_test_service.cpp
@@ -0,0 +1,171 @@
+// Copyright (C) 2014 BMW Group
+// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// 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 "external_local_routing_test_service.hpp"
+
+external_local_routing_test_service::external_local_routing_test_service(bool _use_static_routing) :
+ app_(vsomeip::runtime::get()->create_application()),
+ is_registered_(false),
+ blocked_(false),
+ use_static_routing_(_use_static_routing),
+ offer_thread_(std::bind(&external_local_routing_test_service::run, this)),
+ number_received_messages_local_(0),
+ number_received_messages_external_(0)
+{
+}
+
+void external_local_routing_test_service::init()
+{
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ app_->init();
+ app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
+ std::bind(&external_local_routing_test_service::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_METHOD_ID,
+ std::bind(&external_local_routing_test_service::on_message, this,
+ std::placeholders::_1));
+
+ app_->register_event_handler(
+ std::bind(&external_local_routing_test_service::on_event, this,
+ std::placeholders::_1));
+
+ VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF");
+}
+
+void external_local_routing_test_service::start()
+{
+ VSOMEIP_INFO << "Starting...";
+ app_->start();
+}
+
+void external_local_routing_test_service::stop()
+{
+ VSOMEIP_INFO << "Stopping...";
+ app_->unregister_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID);
+ app_->unregister_event_handler();
+ app_->stop();
+}
+
+void external_local_routing_test_service::join_offer_thread()
+{
+ offer_thread_.join();
+}
+
+void external_local_routing_test_service::offer()
+{
+ app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void external_local_routing_test_service::stop_offer()
+{
+ app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void external_local_routing_test_service::on_event(vsomeip::event_type_e _event)
+{
+ VSOMEIP_INFO << "Application " << app_->get_name() << " is "
+ << (_event == vsomeip::event_type_e::ET_REGISTERED ? "registered." :
+ "deregistered.");
+
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ if(!is_registered_)
+ {
+ is_registered_ = true;
+ blocked_ = true;
+ // "start" the run method thread
+ condition_.notify_one();
+ }
+ }
+ else
+ {
+ is_registered_ = false;
+ }
+}
+
+void external_local_routing_test_service::on_message(
+ const std::shared_ptr<vsomeip::message>& _request)
+{
+ 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() << "]";
+
+ ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID);
+ ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID);
+
+ // Check the protocol version this shall be set to 0x01 according to the spec.
+ // TR_SOMEIP_00052
+ ASSERT_EQ(_request->get_protocol_version(), 0x01);
+ // Check the message type this shall be 0xx (REQUEST) according to the spec.
+ // TR_SOMEIP_00055
+ ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST);
+
+ if(_request->get_client() == vsomeip_test::TEST_CLIENT_CLIENT_ID)
+ {
+ number_received_messages_local_++;
+ // check the session id.
+ ASSERT_EQ(_request->get_session(),
+ static_cast<vsomeip::session_t>(number_received_messages_local_));
+ }
+ else if (_request->get_client() == vsomeip_test::TEST_CLIENT_EXTERNAL_CLIENT_ID)
+ {
+ number_received_messages_external_++;
+ // check the session id.
+ ASSERT_EQ(_request->get_session(),
+ static_cast<vsomeip::session_t>(number_received_messages_external_));
+ }
+
+ // send response
+ std::shared_ptr<vsomeip::message> its_response =
+ vsomeip::runtime::get()->create_response(_request);
+
+ app_->send(its_response, true);
+
+ if(number_received_messages_local_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND
+ && number_received_messages_external_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND)
+ {
+ app_->stop();
+ }
+ ASSERT_LT(number_received_messages_local_,
+ vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1);
+ ASSERT_LT(number_received_messages_external_,
+ vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1);
+}
+
+void external_local_routing_test_service::run()
+{
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ condition_.wait(its_lock);
+
+ if(use_static_routing_)
+ {
+ offer();
+ }
+}
+
+TEST(someip_external_local_routing_test, receive_ten_messages_over_local_and_external_socket)
+{
+ bool use_static_routing = true;
+ external_local_routing_test_service test_service(use_static_routing);
+ test_service.init();
+ test_service.start();
+ test_service.join_offer_thread();
+}
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/routing_tests/external_local_routing_test_service.hpp b/test/routing_tests/external_local_routing_test_service.hpp
new file mode 100644
index 0000000..d5b767e
--- /dev/null
+++ b/test/routing_tests/external_local_routing_test_service.hpp
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 BMW Group
+// Author: Lutz Bichler (lutz.bichler@bmw.de)
+// 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 EXTERNALLOCALROUTINGTESTSERVICE_HPP_
+#define EXTERNALLOCALROUTINGTESTSERVICE_HPP_
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+
+#include "../someip_test_globals.hpp"
+
+class external_local_routing_test_service
+{
+public:
+ external_local_routing_test_service(bool _use_static_routing);
+ void init();
+ void start();
+ void stop();
+ void offer();
+ void stop_offer();
+ void join_offer_thread();
+ void on_event(vsomeip::event_type_e _event);
+ void on_message(const std::shared_ptr<vsomeip::message> &_request);
+ void run();
+
+private:
+ std::shared_ptr<vsomeip::application> app_;
+ bool is_registered_;
+ bool use_static_routing_;
+
+ std::thread offer_thread_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool blocked_;
+ std::uint32_t number_received_messages_local_;
+ std::uint32_t number_received_messages_external_;
+};
+
+#endif /* EXTERNALLOCALROUTINGTESTSERVICE_HPP_ */
diff --git a/test/routing_tests/external_local_routing_test_service.json b/test/routing_tests/external_local_routing_test_service.json
new file mode 100644
index 0000000..d48a33a
--- /dev/null
+++ b/test/routing_tests/external_local_routing_test_service.json
@@ -0,0 +1,62 @@
+{
+ "unicast" : "134.86.56.183",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "false",
+ "path" : "/tmp/vsomeip.log"
+ },
+
+ "dlt" : "false"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "external_local_routing_test_service",
+ "id" : "0x1277"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "default",
+ "unicast" : "local",
+ "delays" :
+ {
+ "initial" :
+ {
+ "minimum" : "10",
+ "maximum" : "100"
+ },
+
+ "repetition-base" : "200",
+ "repetition-max" : "3",
+ "cyclic-offer" : "2000",
+ "cyclic-request" : "2001"
+ },
+
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678",
+ "unreliable" : "30509"
+ }
+ ]
+ }
+ ],
+
+ "routing" : "external_local_routing_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30490",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/routing_tests/external_local_routing_test_service_start.sh b/test/routing_tests/external_local_routing_test_service_start.sh
new file mode 100755
index 0000000..b28b6cf
--- /dev/null
+++ b/test/routing_tests/external_local_routing_test_service_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=external_local_routing_test_service
+export VSOMEIP_CONFIGURATION_FILE=external_local_routing_test_service.json
+./external_local_routing_test_service
diff --git a/test/routing_tests/external_local_routing_test_starter.sh b/test/routing_tests/external_local_routing_test_starter.sh
new file mode 100755
index 0000000..dc0a2c3
--- /dev/null
+++ b/test/routing_tests/external_local_routing_test_starter.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+# Copyright (C) 2015 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_open ()
+{
+ # Check that the service 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 1 ]
+ then
+ ((FAIL+=1))
+ fi
+}
+
+# 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=external_local_routing_test_service
+export VSOMEIP_CONFIGURATION_FILE=external_local_routing_test_service.json
+./external_local_routing_test_service &
+SERIVCE_PID=$!
+sleep 1;
+
+check_tcp_udp_sockets_are_open $SERIVCE_PID
+
+# Start the client (we reuse the one from the local_routing_test to check
+# the local routing functionality).
+export VSOMEIP_APPLICATION_NAME=local_routing_test_client
+export VSOMEIP_CONFIGURATION_FILE=local_routing_test_client.json
+./local_routing_test_client &
+CLIENT_PID=$!
+
+check_tcp_udp_sockets_are_open $SERIVCE_PID
+sleep 1
+check_tcp_udp_sockets_are_closed $CLIENT_PID
+
+# wait that local client finishes
+sleep 2
+
+# Display a message to show the user that he must now call the external client
+# to finish the test successfully
+kill -0 $CLIENT_PID &> /dev/null
+CLIENT_STILL_THERE=$?
+if [ $CLIENT_STILL_THERE -ne 0 ]
+then
+cat <<End-of-message
+*******************************************************************************
+*******************************************************************************
+** Please now run:
+** external_local_routing_test_client_external_start.sh
+** from an external host to successfully complete this test.
+**
+** You probably will need to adapt the 'unicast' settings in
+** external_local_routing_test_client_external.json and
+** external_local_routing_test_service.json to your personal setup.
+*******************************************************************************
+*******************************************************************************
+End-of-message
+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 and the service didnt't
+# have any open
+if [ $FAIL -eq 0 ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/test/routing_tests/local_routing_test_client.cpp b/test/routing_tests/local_routing_test_client.cpp
new file mode 100644
index 0000000..a9a11f5
--- /dev/null
+++ b/test/routing_tests/local_routing_test_client.cpp
@@ -0,0 +1,166 @@
+// Copyright (C) 2015 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 "local_routing_test_client.hpp"
+
+local_routing_test_client::local_routing_test_client(bool _use_tcp) :
+ app_(vsomeip::runtime::get()->create_application()),
+ request_(vsomeip::runtime::get()->create_request(_use_tcp)),
+ sender_(std::bind(&local_routing_test_client::run, this)),
+ running_(true),
+ blocked_(false),
+ is_available_(false),
+ number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND),
+ number_of_sent_messages_(0),
+ number_of_acknowledged_messages_(0)
+{
+}
+
+void local_routing_test_client::init()
+{
+ app_->init();
+
+ app_->register_event_handler(
+ std::bind(&local_routing_test_client::on_event, this,
+ std::placeholders::_1));
+
+ app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID,
+ std::bind(&local_routing_test_client::on_availability, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3));
+
+ app_->register_message_handler(vsomeip::ANY_SERVICE,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD,
+ std::bind(&local_routing_test_client::on_message, this,
+ std::placeholders::_1));
+
+ 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);
+}
+
+void local_routing_test_client::start()
+{
+ VSOMEIP_INFO << "Starting...";
+ app_->start();
+}
+
+void local_routing_test_client::stop()
+{
+ VSOMEIP_INFO << "Stopping...";
+ app_->unregister_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+ app_->unregister_event_handler();
+ app_->unregister_message_handler(vsomeip::ANY_SERVICE,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD);
+
+ app_->stop();
+}
+
+void local_routing_test_client::join_sender_thread(){
+ sender_.join();
+
+ ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_);
+}
+
+void local_routing_test_client::on_event(vsomeip::event_type_e _event)
+{
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, false);
+ }
+}
+
+void local_routing_test_client::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.");
+
+ if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service
+ && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance)
+ {
+ if(is_available_ && !_is_available)
+ {
+ is_available_ = false;
+ }
+ else if(_is_available && !is_available_)
+ {
+ is_available_ = true;
+ send();
+ }
+ }
+}
+
+void local_routing_test_client::on_message(const std::shared_ptr<vsomeip::message>& _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() << "]";
+ number_of_acknowledged_messages_++;
+}
+
+void local_routing_test_client::send()
+{
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ blocked_ = true;
+ condition_.notify_one();
+}
+
+void local_routing_test_client::run()
+{
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ {
+ condition_.wait(its_lock);
+ }
+
+ for (int i = 0; i < number_of_messages_to_send_; i++)
+ {
+ app_->send(request_, true);
+ 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() << "]";
+ number_of_sent_messages_++;
+ }
+ blocked_ = false;
+ // wait until all send messages have been acknowledged, but a maximum of 5 sec.
+ int cnt = 0;
+ while (number_of_acknowledged_messages_ != number_of_messages_to_send_
+ && cnt < 5)
+ {
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+ cnt++;
+ }
+ stop();
+}
+
+TEST(someip_header_factory_test, send_ten_messages_over_local_uds_socket)
+{
+ bool use_tcp = false;
+ local_routing_test_client test_client_(use_tcp);
+ test_client_.init();
+ test_client_.start();
+ test_client_.join_sender_thread();
+}
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/routing_tests/local_routing_test_client.hpp b/test/routing_tests/local_routing_test_client.hpp
new file mode 100644
index 0000000..1eedc8a
--- /dev/null
+++ b/test/routing_tests/local_routing_test_client.hpp
@@ -0,0 +1,49 @@
+// Copyright (C) 2015 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 LOCALROUTINGTESTCLIENT_HPP_
+#define LOCALROUTINGTESTCLIENT_HPP_
+
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+
+#include "../someip_test_globals.hpp"
+
+class local_routing_test_client
+{
+public:
+ local_routing_test_client(bool _use_tcp);
+ void init();
+ void start();
+ void stop();
+ void join_sender_thread();
+ void on_event(vsomeip::event_type_e _event);
+ void on_availability(vsomeip::service_t _service,
+ vsomeip::instance_t _instance, bool _is_available);
+ void on_message(const std::shared_ptr<vsomeip::message> &_response);
+ void send();
+ void run();
+
+private:
+ std::shared_ptr<vsomeip::application> app_;
+ std::shared_ptr<vsomeip::message> request_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::thread sender_;
+ bool running_;
+ bool blocked_;
+ bool is_available_;
+ std::uint32_t number_of_messages_to_send_;
+ std::uint32_t number_of_sent_messages_;
+ std::uint32_t number_of_acknowledged_messages_;
+};
+
+#endif /* LOCALROUTINGTESTCLIENT_HPP_ */
diff --git a/test/routing_tests/local_routing_test_client.json b/test/routing_tests/local_routing_test_client.json
new file mode 100644
index 0000000..fa8d46a
--- /dev/null
+++ b/test/routing_tests/local_routing_test_client.json
@@ -0,0 +1,45 @@
+{
+ "unicast" : "127.0.0.1",
+ "netmask" : "255.255.255.0",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "true",
+ "path" : "/var/log/vsomeip.log"
+ },
+
+ "dlt" : "true"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "local_routing_test_client",
+ "id" : "0x1343"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "remote",
+ "unicast" : "127.0.0.1",
+ "services" :
+ [
+
+ ]
+ }
+ ],
+
+ "routing" : "local_routing_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30491",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/routing_tests/local_routing_test_client_start.sh b/test/routing_tests/local_routing_test_client_start.sh
new file mode 100755
index 0000000..ebe1bf9
--- /dev/null
+++ b/test/routing_tests/local_routing_test_client_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=local_routing_test_client
+export VSOMEIP_CONFIGURATION_FILE=local_routing_test_client.json
+./local_routing_test_client
diff --git a/test/routing_tests/local_routing_test_service.cpp b/test/routing_tests/local_routing_test_service.cpp
new file mode 100644
index 0000000..36dbe72
--- /dev/null
+++ b/test/routing_tests/local_routing_test_service.cpp
@@ -0,0 +1,154 @@
+// Copyright (C) 2015 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 "local_routing_test_service.hpp"
+
+local_routing_test_service::local_routing_test_service(bool _use_static_routing) :
+ app_(vsomeip::runtime::get()->create_application()),
+ is_registered_(false),
+ blocked_(false),
+ use_static_routing_(_use_static_routing),
+ offer_thread_(std::bind(&local_routing_test_service::run, this)),
+ number_of_received_messages_(0)
+{
+}
+
+void local_routing_test_service::init()
+{
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ app_->init();
+ app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
+ std::bind(&local_routing_test_service::on_message, this,
+ std::placeholders::_1));
+
+ app_->register_event_handler(
+ std::bind(&local_routing_test_service::on_event, this,
+ std::placeholders::_1));
+
+ VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF");
+}
+
+void local_routing_test_service::start()
+{
+ VSOMEIP_INFO << "Starting...";
+ app_->start();
+}
+
+void local_routing_test_service::stop()
+{
+ VSOMEIP_INFO << "Stopping...";
+ app_->unregister_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
+ vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID);
+ app_->unregister_event_handler();
+ app_->stop();
+}
+
+void local_routing_test_service::join_offer_thread()
+{
+ offer_thread_.join();
+}
+
+void local_routing_test_service::offer()
+{
+ app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void local_routing_test_service::stop_offer()
+{
+ app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
+}
+
+void local_routing_test_service::on_event(vsomeip::event_type_e _event)
+{
+ VSOMEIP_INFO << "Application " << app_->get_name() << " is "
+ << (_event == vsomeip::event_type_e::ET_REGISTERED ? "registered." :
+ "deregistered.");
+
+ if(_event == vsomeip::event_type_e::ET_REGISTERED)
+ {
+ if(!is_registered_)
+ {
+ is_registered_ = true;
+ blocked_ = true;
+ // "start" the run method thread
+ condition_.notify_one();
+ }
+ }
+ else
+ {
+ is_registered_ = false;
+ }
+}
+
+void local_routing_test_service::on_message(const std::shared_ptr<vsomeip::message>& _request)
+{
+ 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() << "]";
+
+ number_of_received_messages_++;
+
+ ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID);
+ ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID);
+
+ // Check the protocol version this shall be set to 0x01 according to the spec.
+ // TR_SOMEIP_00052
+ ASSERT_EQ(_request->get_protocol_version(), 0x01);
+ // Check the message type this shall be 0xx (REQUEST) according to the spec.
+ // TR_SOMEIP_00055
+ ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST);
+
+ // make sure the message was sent from the service
+ ASSERT_EQ(_request->get_client(), vsomeip_test::TEST_CLIENT_CLIENT_ID);
+
+ // check the session id.
+ ASSERT_EQ(_request->get_session(), static_cast<vsomeip::session_t>(number_of_received_messages_));
+
+
+ // send response
+ std::shared_ptr<vsomeip::message> its_response =
+ vsomeip::runtime::get()->create_response(_request);
+
+ app_->send(its_response, true);
+
+ if(number_of_received_messages_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND)
+ {
+ app_->stop();
+ }
+ ASSERT_LT(number_of_received_messages_,
+ vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1);
+}
+
+void local_routing_test_service::run()
+{
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (!blocked_)
+ condition_.wait(its_lock);
+
+ if(use_static_routing_)
+ {
+ offer();
+ }
+}
+
+TEST(someip_local_routing_test, receive_ten_messages_over_local_uds_socket)
+{
+ bool use_static_routing = true;
+ local_routing_test_service test_service(use_static_routing);
+ test_service.init();
+ test_service.start();
+ test_service.join_offer_thread();
+}
+
+#ifndef WIN32
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/routing_tests/local_routing_test_service.hpp b/test/routing_tests/local_routing_test_service.hpp
new file mode 100644
index 0000000..8ee00b4
--- /dev/null
+++ b/test/routing_tests/local_routing_test_service.hpp
@@ -0,0 +1,45 @@
+// Copyright (C) 2015 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 LOCALROUTINGTESTSERVICE_HPP_
+#define LOCALROUTINGTESTSERVICE_HPP_
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include <functional>
+
+#include "../someip_test_globals.hpp"
+
+class local_routing_test_service
+{
+public:
+ local_routing_test_service(bool _use_static_routing);
+ void init();
+ void start();
+ void stop();
+ void offer();
+ void stop_offer();
+ void join_offer_thread();
+ void on_event(vsomeip::event_type_e _event);
+ void on_message(const std::shared_ptr<vsomeip::message> &_request);
+ void run();
+
+private:
+ std::shared_ptr<vsomeip::application> app_;
+ bool is_registered_;
+ bool use_static_routing_;
+
+ std::thread offer_thread_;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ bool blocked_;
+ std::uint32_t number_of_received_messages_;
+};
+
+#endif /* LOCALROUTINGTESTSERVICE_HPP_ */
diff --git a/test/routing_tests/local_routing_test_service.json b/test/routing_tests/local_routing_test_service.json
new file mode 100644
index 0000000..6726f0e
--- /dev/null
+++ b/test/routing_tests/local_routing_test_service.json
@@ -0,0 +1,61 @@
+{
+ "unicast" : "134.86.56.183",
+ "logging" :
+ {
+ "level" : "debug",
+ "console" : "true",
+ "file" :
+ {
+ "enable" : "false",
+ "path" : "/tmp/vsomeip.log"
+ },
+
+ "dlt" : "false"
+ },
+
+ "applications" :
+ [
+ {
+ "name" : "local_routing_test_service",
+ "id" : "0x1277"
+ }
+ ],
+
+ "servicegroups" :
+ [
+ {
+ "name" : "default",
+ "unicast" : "local",
+ "delays" :
+ {
+ "initial" :
+ {
+ "minimum" : "10",
+ "maximum" : "100"
+ },
+
+ "repetition-base" : "200",
+ "repetition-max" : "3",
+ "cyclic-offer" : "2000",
+ "cyclic-request" : "2001"
+ },
+
+ "services" :
+ [
+ {
+ "service" : "0x1234",
+ "instance" : "0x5678"
+ }
+ ]
+ }
+ ],
+
+ "routing" : "local_routing_test_service",
+ "service-discovery" :
+ {
+ "enable" : "false",
+ "multicast" : "224.0.0.1",
+ "port" : "30490",
+ "protocol" : "udp"
+ }
+} \ No newline at end of file
diff --git a/test/routing_tests/local_routing_test_service_start.sh b/test/routing_tests/local_routing_test_service_start.sh
new file mode 100755
index 0000000..fef108e
--- /dev/null
+++ b/test/routing_tests/local_routing_test_service_start.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright (C) 2015 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_APPLICATION_NAME=local_routing_test_service
+export VSOMEIP_CONFIGURATION_FILE=local_routing_test_service.json
+./local_routing_test_service
diff --git a/test/routing_tests/local_routing_test_starter.sh b/test/routing_tests/local_routing_test_starter.sh
new file mode 100755
index 0000000..6c803b9
--- /dev/null
+++ b/test/routing_tests/local_routing_test_starter.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# Copyright (C) 2015 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
+export VSOMEIP_CONFIGURATION_FILE=local_routing_test_service.json
+./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
+export VSOMEIP_CONFIGURATION_FILE=local_routing_test_client.json
+./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 sucessfully and the service didnt't
+# have any open
+if [ $FAIL -eq 0 ]
+then
+ exit 0
+else
+ exit 1
+fi
diff --git a/test/someip_test_globals.hpp b/test/someip_test_globals.hpp
new file mode 100644
index 0000000..99cbe3f
--- /dev/null
+++ b/test/someip_test_globals.hpp
@@ -0,0 +1,38 @@
+// Copyright (C) 2015 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 SOMEIP_TEST_GLOBALS_HPP_
+#define SOMEIP_TEST_GLOBALS_HPP_
+
+#include <vsomeip/vsomeip.hpp>
+
+namespace vsomeip_test
+{
+
+// Service
+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::client_t TEST_SERVICE_CLIENT_ID = 0x1277;
+
+// Client local
+constexpr vsomeip::client_t TEST_CLIENT_CLIENT_ID = 0x1343;
+
+// Client external
+constexpr vsomeip::client_t TEST_CLIENT_EXTERNAL_CLIENT_ID = 0x1344;
+
+
+constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND = 10;
+constexpr vsomeip::session_t TEST_INITIAL_SESSION_ID = 0x1;
+
+constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS = 1000;
+constexpr vsomeip::byte_t PAYLOAD_TEST_DATA = 0xDD;
+constexpr std::uint32_t MAX_PAYLOADSIZE = 1024*128;
+// TR_SOMEIP_00061
+constexpr std::uint32_t MAX_PAYLOADSIZE_UDP = 1400;
+}
+
+#endif /* SOMEIP_TEST_GLOBALS_HPP_ */
diff --git a/vsomeip.xml b/vsomeip.xml
new file mode 100644
index 0000000..022d625
--- /dev/null
+++ b/vsomeip.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="1">
+<profile kind="CodeFormatterProfile" name="CommonAPI" version="1">
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.lineSplit" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_member_access" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment" value="1"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_enumerator_list" value="48"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_declarator_list" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.join_wrapped_lines" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_expression_list" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="34"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces" value="0"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_assignment" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain" value="18"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration" value="80"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain" value="16"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters" value="insert"/>
+<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments" value="do not insert"/>
+</profile>
+</profiles>
diff --git a/vSomeIPConfig.cmake.in b/vsomeipConfig.cmake.in
index 516f54e..e2c03cf 100644
--- a/vSomeIPConfig.cmake.in
+++ b/vsomeipConfig.cmake.in
@@ -7,9 +7,9 @@ get_filename_component (VSOMEIP_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set (VSOMEIP_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
# Our library dependencies (contains definitions for IMPORTED targets)
-if (NOT TARGET vsomeip AND NOT vSomeIP_BINARY_DIR)
- include ("${VSOMEIP_CMAKE_DIR}/vSomeIPTargets.cmake")
+if (NOT TARGET vsomeip AND NOT vsomeip_BINARY_DIR)
+ include ("${VSOMEIP_CMAKE_DIR}/vsomeipTargets.cmake")
endif ()
-# These are IMPORTED targets created by vSomeIPTargets.cmake
+# These are IMPORTED targets created by vsomeipTargets.cmake
set (VSOMEIP_LIBRARIES vsomeip)
diff --git a/vSomeIPConfigVersion.cmake.in b/vsomeipConfigVersion.cmake.in
index 69988bd..69988bd 100644
--- a/vSomeIPConfigVersion.cmake.in
+++ b/vsomeipConfigVersion.cmake.in