diff options
author | Jürgen Gehring <juergen.gehring@bmw.de> | 2015-07-29 00:39:43 -0700 |
---|---|---|
committer | Jürgen Gehring <juergen.gehring@bmw.de> | 2015-07-29 00:39:43 -0700 |
commit | 4792b52c653ab8cdba740a141ae808226b3ed2c1 (patch) | |
tree | 47ba024655b6491de0f8e3033ec99fc35080d5f4 | |
parent | a1082eaf77850fe213e30e9abc4ea709d0499681 (diff) | |
download | vSomeIP-4792b52c653ab8cdba740a141ae808226b3ed2c1.tar.gz |
vSomeIP 1.3.01.3.0
216 files changed, 16491 insertions, 7353 deletions
@@ -1,2 +1,5 @@ /build*/*
+/examples/hello_world/build
/.settings
+/doc
+/implementation/configuration/include/internal.hpp
@@ -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 )
@@ -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. @@ -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 |