From 2b7442a4c2452f8f3bd9e0f09f829478256d39af Mon Sep 17 00:00:00 2001 From: Dirk Huss Date: Wed, 9 Dec 2015 14:50:34 +0100 Subject: vSomeIP 2.0.1 --- CMakeLists.txt | 22 ++- README | 90 +++++----- examples/hello_world/hello_world_service.cpp | 26 ++- .../configuration/include/configuration_impl.hpp | 86 +++++----- .../configuration/include/internal.hpp.in | 2 +- .../endpoints/include/tcp_server_endpoint_impl.hpp | 1 + .../endpoints/include/udp_server_endpoint_impl.hpp | 1 + .../endpoints/src/local_client_endpoint_impl.cpp | 11 +- .../endpoints/src/tcp_server_endpoint_impl.cpp | 20 +++ .../endpoints/src/udp_server_endpoint_impl.cpp | 11 ++ .../logging/include/dlt_sink_backend.hpp | 44 +++++ implementation/logging/include/logger_impl.hpp | 5 +- implementation/logging/src/dlt_sink_backend.cpp | 66 +++++++ implementation/logging/src/logger_impl.cpp | 9 +- implementation/routing/include/event.hpp | 6 +- implementation/routing/include/routing_manager.hpp | 4 +- .../routing/include/routing_manager_impl.hpp | 8 +- .../routing/include/routing_manager_proxy.hpp | 12 +- .../routing/include/routing_manager_stub_host.hpp | 4 +- implementation/routing/src/event.cpp | 16 +- .../routing/src/routing_manager_impl.cpp | 130 ++++++++++++-- .../routing/src/routing_manager_proxy.cpp | 43 ++++- .../routing/src/routing_manager_stub.cpp | 6 +- .../runtime/include/application_impl.hpp | 7 +- implementation/runtime/src/application_impl.cpp | 12 +- implementation/runtime/src/runtime_impl.cpp | 3 + .../include/service_discovery.hpp | 8 +- .../include/service_discovery_host.hpp | 3 + .../include/service_discovery_impl.hpp | 25 ++- .../service_discovery/include/subscription.hpp | 8 +- .../src/configuration_option_impl.cpp | 47 +++-- .../service_discovery/src/option_impl.cpp | 8 +- .../service_discovery/src/runtime_impl.cpp | 2 + .../src/service_discovery_impl.cpp | 191 ++++++++++++++++----- .../service_discovery/src/subscription.cpp | 10 +- implementation/utility/include/utility.hpp | 2 +- interface/vsomeip/application.hpp | 7 +- interface/vsomeip/enumeration_types.hpp | 8 + .../conf/magic_cookies_test_client.json.in | 4 +- .../conf/magic_cookies_test_service.json.in | 2 +- .../magic_cookies_test_starter.sh | 65 +------ 41 files changed, 732 insertions(+), 303 deletions(-) create mode 100644 implementation/logging/include/dlt_sink_backend.hpp create mode 100644 implementation/logging/src/dlt_sink_backend.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 877273c..bf03c16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project (vsomeip) set (VSOMEIP_MAJOR_VERSION 2) set (VSOMEIP_MINOR_VERSION 0) -set (VSOMEIP_PATCH_VERSION 0) +set (VSOMEIP_PATCH_VERSION 1) set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION}) set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentatin/doxygen.in set (CMAKE_VERBOSE_MAKEFILE off) @@ -69,6 +69,22 @@ find_package(Threads REQUIRED) find_package( Boost 1.54 COMPONENTS system thread log REQUIRED ) include_directories( ${Boost_INCLUDE_DIR} ) +# DLT +find_package(PkgConfig) +pkg_check_modules(DLT "automotive-dlt >= 2.11") +IF(DLT_FOUND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_DLT") +ENDIF(DLT_FOUND) + +include_directories( + include + ${DLT_INCLUDE_DIRS} +) + +link_directories( + ${DLT_LIBDIR} +) + # Base library file(GLOB vsomeip_SRC "implementation/configuration/src/*.cpp" @@ -98,7 +114,7 @@ set_target_properties (vsomeip PROPERTIES VERSION ${VSOMEIP_VERSION} SOVERSION $ # them (which shouldn't be required). ${Boost_LIBRARIES} includes absolute # build host paths as of writing, which also makes this important as it breaks # the build. -target_link_libraries(vsomeip PRIVATE ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY}) +target_link_libraries(vsomeip PRIVATE ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${DLT_LIBRARIES}) file(GLOB vsomeip-sd_SRC "implementation/service_discovery/src/*.cpp" @@ -275,7 +291,7 @@ endif() # create pkg-config file if(NOT WIN32) configure_file(vsomeip.pc.in ${PROJECT_BINARY_DIR}/vsomeip.pc @ONLY) - install(FILES ${PROJECT_BINARY_DIR}/vsomeip.pc DESTINATION lib/pkconfig) + install(FILES ${PROJECT_BINARY_DIR}/vsomeip.pc DESTINATION lib/pkgconfig) endif() ############################################################################## diff --git a/README b/README index 86dcaa1..893d004 100644 --- a/README +++ b/README @@ -601,17 +601,17 @@ The service example results in the following program execution: Main ^^^^^ -. __main()__ (line 101-107) +. __main()__ + -First the application is initialized (line 104). After the initialization is -finished the application is started (line 105). +First the application is initialized. After the initialization is +finished the application is started. [float] Initialization ^^^^^^^^^^^^^^ [start=2] -. __init()__ (line 26-42) +. __init()__ + The initialization contains the registration of a message handler and an event handler. @@ -628,7 +628,7 @@ Start ^^^^^ [start=3] -. __start()__ (line 44-49) +. __start()__ + The application will be started. This function only returns when the application will be stopped. @@ -638,35 +638,33 @@ Callbacks ^^^^^^^^^ [start=4] -. __on_event_cbk()__ (line 64-71) +. __on_state_cbk()__ + -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. +This function is called by the application when an state change occurred. If +the application was successfully registered at the runtime then the specific +service is offered. -. __on_message_cbk()__ (line 73-94) +. __on_message_cbk()__ + -This function is called when a message/request -from a client for the specified service was received. +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). +First a response based upon the request is created. 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). +client's request. +After that the payload of the response is created. The payload data is set with +the previously concatenated string. +Finally the response is sent back to the client and the application is stopped. [float] Stop ^^^^ [start=6] -. __stop()__ (line 51-62) +. __stop()__ + -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). +This function stops offering the service, unregister the message and the event +handler and shuts down the application. :numbered: @@ -685,23 +683,23 @@ The client example results in the following program execution: Main ^^^^^ -. __main()__ (line 130-136) +. __main()__ + -First the application is initialized (line 133). After the initialization is -finished the application is started (line 134). +First the application is initialized. After the initialization is finished the +application is started. [float] Initialization ^^^^^^^^^^^^^^ [start=2] -. __init()__ (line 27-48) +. __init()__ + The initialization contains the registration of a message handler, an event handler and an availability handler. + -The event handler declares again a callback (__on_event_cbk__) for events that -occur. +The event handler declares again a callback (__on_state_cbk__) for state changes +that occur. + The message handler declares a callback (__on_message_cbk__) for messages that are received from any service, any service instance and any method. @@ -715,7 +713,7 @@ Start ^^^^^ [start=3] -. __start()__ (line 50-55) +. __start()__ + The application will be started. This function only returns when the application will be stopped. @@ -725,13 +723,14 @@ Callbacks ^^^^^^^^^ [start=4] -. __on_event_cbk()__ (line 57-65) +. __on_state_cbk()__ + -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 by the application when an state change occurred. If the +application was successfully registered at the runtime then the specific service +is requested. + +. __on_availability_cbk()__ + This function is called when the requested service is available or no longer available. @@ -739,26 +738,27 @@ 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. +service information are set (service id, service instance id, service method +id). +After that the payload of the request is created. The data of the payload is +'World' and will be set afterwards. +Finally the request is sent to the service. -. __on_message_cbk()__ (line 73-94) +. __on_message_cbk()__ + This function is called when a message/response was received. -If the response is from the requested service, of type -'RESPONSE' and the return code is 'OK' (line 98-103) then the payload of the -response is printed (line 105-109). Finally the application is stopped. +If the response is from the requested service, of type 'RESPONSE' and the return +code is 'OK' then the payload of the response is printed. Finally the +application is stopped. [float] Stop ^^^^ [start=7] -. __stop()__ (line 114-123) +. __stop()__ + -This function unregister the event and the message handler (line 117-120) and -shuts down the application (line 122). +This function unregister the event and the message handler and shuts down the +application. :numbered: diff --git a/examples/hello_world/hello_world_service.cpp b/examples/hello_world/hello_world_service.cpp index eece51c..78b895f 100644 --- a/examples/hello_world/hello_world_service.cpp +++ b/examples/hello_world/hello_world_service.cpp @@ -4,6 +4,10 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include +#include +#include +#include static vsomeip::service_t service_id = 0x1111; static vsomeip::instance_t service_instance_id = 0x2222; @@ -17,10 +21,17 @@ public: // environment variable is used hello_world_service() : rtm_(vsomeip::runtime::get()), - app_(rtm_->create_application()) + app_(rtm_->create_application()), + stop_(false), + stop_thread_(std::bind(&hello_world_service::stop, this)) { } + ~hello_world_service() + { + stop_thread_.join(); + } + void init() { // init the application @@ -48,6 +59,11 @@ public: void stop() { + std::unique_lock its_lock(mutex_); + while(!stop_) { + condition_.wait(its_lock); + } + std::this_thread::sleep_for(std::chrono::seconds(5)); // Stop offering the service app_->stop_offer_service(service_id, service_instance_id); // unregister the state handler @@ -88,12 +104,18 @@ public: // Send the response back app_->send(resp, true); // we're finished stop now - stop(); + std::lock_guard its_lock(mutex_); + stop_ = true; + condition_.notify_one(); } private: std::shared_ptr rtm_; std::shared_ptr app_; + bool stop_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread stop_thread_; }; int main(int argc, char **argv) diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index 04f4a22..a6ca21c 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -21,69 +21,69 @@ namespace cfg { struct service; struct servicegroup; -class VSOMEIP_EXPORT configuration_impl: public configuration { +class configuration_impl: public configuration { public: - static std::shared_ptr get( + VSOMEIP_EXPORT static std::shared_ptr get( const std::set &_input); - static void reset(); + VSOMEIP_EXPORT static void reset(); - configuration_impl(); - configuration_impl(const configuration_impl &_cfg); - virtual ~configuration_impl(); + VSOMEIP_EXPORT configuration_impl(); + VSOMEIP_EXPORT configuration_impl(const configuration_impl &_cfg); + VSOMEIP_EXPORT virtual ~configuration_impl(); - void load(const boost::property_tree::ptree &_tree); - void load_log(const std::vector &_trees); + VSOMEIP_EXPORT void load(const boost::property_tree::ptree &_tree); + VSOMEIP_EXPORT void load_log(const std::vector &_trees); - const boost::asio::ip::address & get_unicast_address() const; - bool is_v4() const; - bool is_v6() const; + VSOMEIP_EXPORT const boost::asio::ip::address & get_unicast_address() const; + VSOMEIP_EXPORT bool is_v4() const; + VSOMEIP_EXPORT 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; + VSOMEIP_EXPORT bool has_console_log() const; + VSOMEIP_EXPORT bool has_file_log() const; + VSOMEIP_EXPORT bool has_dlt_log() const; + VSOMEIP_EXPORT const std::string & get_logfile() const; + VSOMEIP_EXPORT boost::log::trivial::severity_level get_loglevel() const; - std::string get_unicast_address(service_t _service, instance_t _instance) const; - std::string get_multicast_address(service_t _service, + VSOMEIP_EXPORT std::string get_unicast_address(service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT std::string get_multicast_address(service_t _service, instance_t _instance) const; - uint16_t get_multicast_port(service_t _service, + VSOMEIP_EXPORT uint16_t get_multicast_port(service_t _service, instance_t _instance) const; - uint16_t get_multicast_group(service_t _service, + VSOMEIP_EXPORT 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, + VSOMEIP_EXPORT uint16_t get_reliable_port(service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const; + VSOMEIP_EXPORT uint16_t get_unreliable_port(service_t _service, instance_t _instance) const; - bool is_someip(service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT bool is_someip(service_t _service, instance_t _instance) const; - const std::string & get_routing_host() const; + VSOMEIP_EXPORT const std::string & get_routing_host() const; - client_t get_id(const std::string &_name) const; - std::size_t get_num_dispatchers(const std::string &_name) const; + VSOMEIP_EXPORT client_t get_id(const std::string &_name) const; + VSOMEIP_EXPORT std::size_t get_num_dispatchers(const std::string &_name) const; - std::set > get_remote_services() const; + VSOMEIP_EXPORT std::set > get_remote_services() const; - std::uint32_t get_max_message_size_local() const; - std::uint32_t get_message_size_reliable(const std::string& _address, + VSOMEIP_EXPORT std::uint32_t get_max_message_size_local() const; + VSOMEIP_EXPORT std::uint32_t get_message_size_reliable(const std::string& _address, std::uint16_t _port) const; // Service Discovery configuration - bool is_sd_enabled() const; - - const std::string & get_sd_multicast() const; - uint16_t get_sd_port() const; - const std::string & get_sd_protocol() const; - - int32_t get_sd_initial_delay_min() const; - int32_t get_sd_initial_delay_max() const; - int32_t get_sd_repetitions_base_delay() const; - uint8_t get_sd_repetitions_max() const; - ttl_t get_sd_ttl() const; - int32_t get_sd_cyclic_offer_delay() const; - int32_t get_sd_request_response_delay() const; + VSOMEIP_EXPORT bool is_sd_enabled() const; + + VSOMEIP_EXPORT const std::string & get_sd_multicast() const; + VSOMEIP_EXPORT uint16_t get_sd_port() const; + VSOMEIP_EXPORT const std::string & get_sd_protocol() const; + + VSOMEIP_EXPORT int32_t get_sd_initial_delay_min() const; + VSOMEIP_EXPORT int32_t get_sd_initial_delay_max() const; + VSOMEIP_EXPORT int32_t get_sd_repetitions_base_delay() const; + VSOMEIP_EXPORT uint8_t get_sd_repetitions_max() const; + VSOMEIP_EXPORT ttl_t get_sd_ttl() const; + VSOMEIP_EXPORT int32_t get_sd_cyclic_offer_delay() const; + VSOMEIP_EXPORT int32_t get_sd_request_response_delay() const; private: void get_logging_configuration(const boost::property_tree::ptree &_tree); diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index 3700a89..64b7105 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -72,7 +72,7 @@ #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_SUBSCRIBE_COMMAND_SIZE 19 #define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 13 #define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 15 #define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 13 diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index 57f0566..7295868 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -36,6 +36,7 @@ public: void send_queued(queue_iterator_type _queue_iterator); endpoint_type get_remote() const; + bool get_remote_address(boost::asio::ip::address &_address) const; bool get_multicast(service_t, event_t, endpoint_type &) const; unsigned short get_local_port() const; diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index d7e2b62..c03a7b4 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -36,6 +36,7 @@ public: void send_queued(queue_iterator_type _queue_iterator); endpoint_type get_remote() const; + bool get_remote_address(boost::asio::ip::address &_address) const; bool get_multicast(service_t _service, event_t _event, endpoint_type &_target) const; diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp index 323c414..116287f 100644 --- a/implementation/endpoints/src/local_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp @@ -38,14 +38,9 @@ void local_client_endpoint_impl::start() { 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 - ) - ); + boost::system::error_code error; + error = socket_.connect(remote_, error); + connect_cbk(error); } void local_client_endpoint_impl::receive() { diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index 20391a0..0084d8e 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -70,6 +70,26 @@ tcp_server_endpoint_impl::get_remote() const { return current_->get_socket().remote_endpoint(); } +bool tcp_server_endpoint_impl::get_remote_address( + boost::asio::ip::address &_address) const { + + if (current_) { + boost::system::error_code its_error; + tcp_server_endpoint_impl::endpoint_type its_endpoint = + current_->get_socket().remote_endpoint(its_error); + if (its_error) { + return false; + } else { + boost::asio::ip::address its_address = its_endpoint.address(); + if (!its_address.is_unspecified()) { + _address = its_address; + return true; + } + } + } + return false; +} + bool tcp_server_endpoint_impl::get_multicast(service_t, event_t, tcp_server_endpoint_impl::endpoint_type &) const { return false; diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index f29dfba..4593c1f 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -123,6 +123,17 @@ udp_server_endpoint_impl::get_remote() const { return remote_; } +bool udp_server_endpoint_impl::get_remote_address( + boost::asio::ip::address &_address) const { + boost::asio::ip::address its_address = remote_.address(); + if (its_address.is_unspecified()) { + return false; + } else { + _address = its_address; + } + return true; +} + 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); diff --git a/implementation/logging/include/dlt_sink_backend.hpp b/implementation/logging/include/dlt_sink_backend.hpp new file mode 100644 index 0000000..1b7fd09 --- /dev/null +++ b/implementation/logging/include/dlt_sink_backend.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef LOGGING_INCLUDE_DLT_SINK_BACKEND_HPP_ +#define LOGGING_INCLUDE_DLT_SINK_BACKEND_HPP_ + +#ifdef USE_DLT +#include +#endif + +#include +#include +#include + +namespace logging = boost::log; +namespace sinks = boost::log::sinks; + +namespace vsomeip +{ + +class dlt_sink_backend : + public sinks::basic_sink_backend< + sinks::combine_requirements< + sinks::synchronized_feeding + >::type + > { +public: + dlt_sink_backend(); + virtual ~dlt_sink_backend(); + + void consume(const logging::record_view &rec); + +private: +#ifdef USE_DLT + DltLogLevelType level_as_dlt(logging::trivial::severity_level _level); + DLT_DECLARE_CONTEXT(dlt_); +#endif +}; + +} /* namespace vsomeip */ + +#endif /* LOGGING_INCLUDE_DLT_SINK_BACKEND_HPP_ */ diff --git a/implementation/logging/include/logger_impl.hpp b/implementation/logging/include/logger_impl.hpp index 56c2397..ddc4eb2 100644 --- a/implementation/logging/include/logger_impl.hpp +++ b/implementation/logging/include/logger_impl.hpp @@ -15,6 +15,7 @@ #include #include "logger.hpp" +#include "dlt_sink_backend.hpp" namespace vsomeip { @@ -26,6 +27,8 @@ BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", typedef boost::log::sinks::synchronous_sink< boost::log::sinks::text_ostream_backend> sink_t; +typedef boost::log::sinks::synchronous_sink< + dlt_sink_backend> dlt_sink_t; class logger_impl: public logger { public: @@ -49,7 +52,7 @@ private: boost::shared_ptr console_sink_; boost::shared_ptr file_sink_; - //boost::shared_ptr< dlt_sink > dlt_sink_; + boost::shared_ptr dlt_sink_; private: void use_null_logger(); diff --git a/implementation/logging/src/dlt_sink_backend.cpp b/implementation/logging/src/dlt_sink_backend.cpp new file mode 100644 index 0000000..b4d2864 --- /dev/null +++ b/implementation/logging/src/dlt_sink_backend.cpp @@ -0,0 +1,66 @@ +// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/dlt_sink_backend.hpp" + +#ifdef USE_DLT +#include +#endif + +#include + +namespace expressions = boost::log::expressions; + +namespace vsomeip +{ + +dlt_sink_backend::dlt_sink_backend() { +#ifdef USE_DLT + DLT_REGISTER_APP("vSIP", "vSomeIP application"); + DLT_REGISTER_CONTEXT(dlt_, "vSIP", "vSomeIP context"); +#endif +} + +dlt_sink_backend::~dlt_sink_backend() { +#ifdef USE_DLT + DLT_UNREGISTER_CONTEXT(dlt_); + DLT_UNREGISTER_APP(); +#endif +} + +BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", logging::trivial::severity_level) + +void dlt_sink_backend::consume(const logging::record_view &rec) { +#ifdef USE_DLT + std::string message = *rec[expressions::smessage]; + logging::trivial::severity_level severity_level = *rec[severity]; + DLT_LOG_STRING(dlt_, level_as_dlt(severity_level), message.c_str()); +#else + (void)rec; +#endif +} + +#ifdef USE_DLT +DltLogLevelType dlt_sink_backend::level_as_dlt(logging::trivial::severity_level _level) { + switch (_level) { + case logging::trivial::fatal: + return DLT_LOG_FATAL; + case logging::trivial::error: + return DLT_LOG_ERROR; + case logging::trivial::warning: + return DLT_LOG_WARN; + case logging::trivial::info: + return DLT_LOG_INFO; + case logging::trivial::debug: + return DLT_LOG_DEBUG; + case logging::trivial::trace: + return DLT_LOG_VERBOSE; + default: + return DLT_LOG_DEFAULT; + } +} +#endif + +} /* namespace vsomeip */ diff --git a/implementation/logging/src/logger_impl.cpp b/implementation/logging/src/logger_impl.cpp index ef98749..6bf4e08 100644 --- a/implementation/logging/src/logger_impl.cpp +++ b/implementation/logging/src/logger_impl.cpp @@ -124,7 +124,14 @@ void logger_impl::enable_file(const std::string &_path) { } void logger_impl::enable_dlt() { - // TODO: implement +#ifdef USE_DLT + if (dlt_sink_) + return; + + boost::shared_ptr backend = boost::make_shared(); + dlt_sink_ = boost::make_shared(backend); + logging::core::get()->add_sink(dlt_sink_); +#endif } void logger_impl::use_null_logger() { diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp index 89153ad..2036636 100644 --- a/implementation/routing/include/event.hpp +++ b/implementation/routing/include/event.hpp @@ -35,6 +35,9 @@ public: instance_t get_instance() const; void set_instance(instance_t _instance); + major_version_t get_version() const; + void set_version(major_version_t _major); + event_t get_event() const; void set_event(event_t _event); @@ -51,9 +54,6 @@ public: bool is_field() const; void set_field(bool _is_field); - bool is_reliable() const; - void set_reliable(bool _is_reliable); - bool is_provided() const; void set_provided(bool _is_provided); diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp index 7791add..2642677 100644 --- a/implementation/routing/include/routing_manager.hpp +++ b/implementation/routing/include/routing_manager.hpp @@ -50,7 +50,7 @@ public: virtual void subscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major) = 0; + major_version_t _major, subscription_type_e _subscription_type) = 0; virtual void unsubscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup) = 0; @@ -68,7 +68,7 @@ public: const byte_t *_data, uint32_t _size) = 0; virtual void register_event(client_t _client, service_t _service, instance_t _instance, - event_t _event, std::set _eventgroups, + event_t _event, const std::set &_eventgroups, bool _is_field, bool _is_provided) = 0; virtual void unregister_event(client_t _client, service_t _service, instance_t _instance, diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index a0d692c..9741f3e 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -76,7 +76,8 @@ public: instance_t _instance); void subscribe(client_t _client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major); + eventgroup_t _eventgroup, major_version_t _major, + subscription_type_e _subscription_type); void unsubscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup); @@ -94,7 +95,7 @@ public: void register_event(client_t _client, service_t _service, instance_t _instance, event_t _event, - std::set _eventgroups, + const std::set &_eventgroups, bool _is_field, bool _is_provided); void unregister_event(client_t _client, service_t _service, @@ -158,6 +159,9 @@ public: void on_subscribe_ack(service_t _service, instance_t _instance, const boost::asio::ip::address &_address, uint16_t _port); + void expire_subscriptions(const boost::asio::ip::address &_address); + void expire_services(const boost::asio::ip::address &_address); + private: bool deliver_message(const byte_t *_data, length_t _length, instance_t _instance, bool _reliable); diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp index 852ca19..0577597 100644 --- a/implementation/routing/include/routing_manager_proxy.hpp +++ b/implementation/routing/include/routing_manager_proxy.hpp @@ -13,6 +13,7 @@ #include "routing_manager.hpp" #include "../../endpoints/include/endpoint_host.hpp" +#include namespace vsomeip { @@ -52,7 +53,8 @@ public: instance_t _instance); void subscribe(client_t _client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major); + eventgroup_t _eventgroup, major_version_t _major, + subscription_type_e _subscription_type); void unsubscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup); @@ -70,7 +72,7 @@ public: void register_event(client_t _client, service_t _service, instance_t _instance, event_t _event, - std::set _eventgroups, + const std::set &_eventgroups, bool _is_field, bool _is_provided); void unregister_event(client_t _client, service_t _service, @@ -112,11 +114,11 @@ private: minor_version_t _minor, bool _use_exclusive_proxy); void send_register_event(client_t _client, service_t _service, instance_t _instance, event_t _event, - std::set _eventgroup, + const std::set &_eventgroup, bool _is_field, bool _is_provided); void send_subscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major); + major_version_t _major, subscription_type_e _subscription_type); bool is_field(service_t _service, instance_t _instance, event_t _event) const; @@ -139,6 +141,7 @@ private: std::map > local_endpoints_; std::map > local_services_; + std::map > service_versions_; std::mutex local_services_mutex_; struct service_data_t { @@ -181,6 +184,7 @@ private: instance_t instance_; eventgroup_t eventgroup_; major_version_t major_; + subscription_type_e subscription_type_; bool operator<(const eventgroup_data_t &_other) const { return (service_ < _other.service_ diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp index f25eef2..d56f2d3 100644 --- a/implementation/routing/include/routing_manager_stub_host.hpp +++ b/implementation/routing/include/routing_manager_stub_host.hpp @@ -31,7 +31,7 @@ public: virtual void register_event(client_t _client, service_t _service, instance_t _instance, event_t _event, - std::set _eventgroups, + const std::set &_eventgroups, bool _is_field, bool _is_provided) = 0; virtual void unregister_event(client_t _client, service_t _service, @@ -39,7 +39,7 @@ public: virtual void subscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major) = 0; + major_version_t _major, subscription_type_e _subscription_type) = 0; virtual void unsubscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup) = 0; diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp index 4572632..b553415 100644 --- a/implementation/routing/src/event.cpp +++ b/implementation/routing/src/event.cpp @@ -41,6 +41,14 @@ void event::set_instance(instance_t _instance) { message_->set_instance(_instance); } +major_version_t event::get_version() const { + return message_->get_interface_version(); +} + +void event::set_version(major_version_t _major) { + message_->set_interface_version(_major); +} + event_t event::get_event() const { return (message_->get_method()); } @@ -65,14 +73,6 @@ void event::set_provided(bool _is_provided) { is_provided_ = _is_provided; } -bool event::is_reliable() const { - return message_->is_reliable(); -} - -void event::set_reliable(bool _is_reliable) { - message_->set_reliable(_is_reliable); -} - const std::shared_ptr event::get_payload() const { return (message_->get_payload()); } diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index ff1c67e..13ec332 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -175,7 +175,8 @@ void routing_manager_impl::release_service(client_t _client, service_t _service, } void routing_manager_impl::subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, major_version_t _major) { + instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, + subscription_type_e _subscription_type) { if (discovery_) { if (!host_->on_subscription(_service, _instance, _eventgroup, _client, true)) { VSOMEIP_INFO << "Subscription request for eventgroup " << _eventgroup @@ -192,7 +193,7 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service, subscriber = _client; } discovery_->subscribe(_service, _instance, _eventgroup, - _major, DEFAULT_TTL, subscriber); + _major, DEFAULT_TTL, subscriber, _subscription_type); } else { send_subscribe(_client, _service, _instance, _eventgroup, _major); @@ -323,7 +324,6 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } else { std::shared_ptr 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]); @@ -347,19 +347,26 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, send_local(its_local_target, _client, _data, _size, _instance, _flush, _reliable); } } - - if (its_target) { + // we need both endpoints as clients can subscribe to events via TCP and UDP + std::shared_ptr its_unreliable_target = its_info->get_endpoint(false); + std::shared_ptr its_reliable_target = its_info->get_endpoint(true); + if (its_unreliable_target || its_reliable_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); + if(its_remote->is_reliable() && its_reliable_target) { + its_reliable_target->send_to(its_remote, _data, _size); + } else if(its_unreliable_target) { + its_unreliable_target->send_to(its_remote, _data, _size); + } } } } } } } else { + its_target = its_info->get_endpoint(_reliable); if (its_target) { is_sent = its_target->send(_data, _size, _flush); } else { @@ -437,7 +444,7 @@ bool routing_manager_impl::send_to( void routing_manager_impl::register_event(client_t _client, service_t _service, instance_t _instance, - event_t _event, std::set _eventgroups, + event_t _event, const std::set &_eventgroups, bool _is_field, bool _is_provided) { (void)_client; @@ -461,12 +468,18 @@ void routing_manager_impl::register_event(client_t _client, its_event->set_event(_event); its_event->set_field(_is_field); its_event->set_provided(_is_provided); + std::shared_ptr its_service = find_service(_service, _instance); + if (its_service) { + its_event->set_version(its_service->get_major()); + } if (_eventgroups.size() == 0) { // No eventgroup specified - _eventgroups.insert(_event); + std::set its_eventgroups; + its_eventgroups.insert(_event); + its_event->set_eventgroups(its_eventgroups); + } else { + its_event->set_eventgroups(_eventgroups); } - - its_event->set_eventgroups(_eventgroups); } its_event->add_ref(); @@ -578,8 +591,14 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _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); + if (discovery_) { + boost::asio::ip::address its_address; + if (_receiver->get_remote_address(its_address)) { + discovery_->on_message(_data, _size, its_address); + } else { + VSOMEIP_ERROR << "Ignored SD message from unknown address."; + } + } } else { instance_t its_instance = find_instance(its_service, _receiver); return_code_e return_code = check_error(_data, _size, its_instance); @@ -661,11 +680,13 @@ void routing_manager_impl::on_message( its_session = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_SESSION_POS_MIN], _data[VSOMEIP_SESSION_POS_MAX]); + major_version_t its_version = _data[VSOMEIP_INTERFACE_VERSION_POS]; its_response->set_service(_service); its_response->set_method(its_method); its_response->set_client(its_client); its_response->set_session(its_session); + its_response->set_interface_version(its_version); if (its_event->is_field()) { its_response->set_message_type( @@ -677,10 +698,13 @@ void routing_manager_impl::on_message( std::lock_guard its_lock(serialize_mutex_); if (serializer_->serialize(its_response.get())) { + // always pass reliable = false, but this won't be used, as + // the event is sent out via TCP or UDP dependent on which + // L4Proto the subscriber passed in the endpoint option in + // its subscription to the eventgroup send(its_client, serializer_->get_data(), serializer_->get_size(), - _instance, - true, its_event->is_reliable()); + _instance, true, false); } else { VSOMEIP_ERROR << "routing_manager_impl::on_message: serialization error."; } @@ -1167,7 +1191,9 @@ std::shared_ptr routing_manager_impl::create_server_endpoint( configuration_->get_message_size_reliable( its_unicast.to_string(), _port)); if (configuration_->has_enabled_magic_cookies( - its_unicast.to_string(), _port)) { + its_unicast.to_string(), _port) || + configuration_->has_enabled_magic_cookies( + "local", _port)) { its_endpoint->enable_magic_cookies(); } } else { @@ -1637,6 +1663,65 @@ ttl_t routing_manager_impl::update_routing_info(ttl_t _elapsed) { return its_smallest_ttl; } +void routing_manager_impl::expire_services(const boost::asio::ip::address &_address) { + std::map > > its_expired_offers; + + for (auto &s : services_) { + for (auto &i : s.second) { + bool is_gone(false); + boost::asio::ip::address its_address; + std::shared_ptr its_endpoint = i.second->get_endpoint(true); + if (its_endpoint) { + if (its_endpoint->get_remote_address(its_address)) { + is_gone = (its_address == _address); + } + } else { + its_endpoint = i.second->get_endpoint(false); + if (its_endpoint) { + if (its_endpoint->get_remote_address(its_address)) { + is_gone = (its_address == _address); + } + } + } + + if (is_gone) { + if (discovery_) + discovery_->unsubscribe_all(s.first, i.first); + its_expired_offers[s.first][i.first] = { + i.second->get_endpoint(true) != nullptr, + i.second->get_endpoint(false) != nullptr + }; + } + } + } + + for (auto &s : its_expired_offers) { + for (auto &i : s.second) { + del_routing_info(s.first, i.first, i.second.first, i.second.second); + } + } +} + +void routing_manager_impl::expire_subscriptions(const boost::asio::ip::address &_address) { + for (auto &its_service : eventgroups_) { + for (auto &its_instance : its_service.second) { + for (auto &its_eventgroup : its_instance.second) { + std::set> its_invalid_targets; + for (auto &its_target : its_eventgroup.second->get_targets()) { + if (its_target->get_address() == _address) + its_invalid_targets.insert(its_target); + } + + for (auto &its_target : its_invalid_targets) { + its_eventgroup.second->remove_target(its_target); + } + } + } + } +} + void routing_manager_impl::init_routing_info() { VSOMEIP_INFO<< "Service Discovery disabled. Using static routing information."; for (auto i : configuration_->get_remote_services()) { @@ -2089,10 +2174,17 @@ return_code_e routing_manager_impl::check_error(const byte_t *_data, length_t _s << std::hex << its_service; return return_code_e::E_UNKNOWN_SERVICE; } - // TODO: Check interface version handling?! - if (_data[VSOMEIP_INTERFACE_VERSION_POS] != 0x0) { - // Interface is currently set to zero always! - return return_code_e::E_WRONG_INTERFACE_VERSION; + // Check interface version of service/instance + auto found_service = services_.find(its_service); + if (found_service != services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto its_info = found_instance->second; + major_version_t its_version = _data[VSOMEIP_INTERFACE_VERSION_POS]; + if (its_version != its_info->get_major()) { + return return_code_e::E_WRONG_INTERFACE_VERSION; + } + } } if (_data[VSOMEIP_RETURN_CODE_POS] != static_cast (return_code_e::E_OK)) { // Request calls must to have return code E_OK set! diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index cbf14ff..45346bf 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -113,6 +113,7 @@ void routing_manager_proxy::stop() { void routing_manager_proxy::offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { + service_versions_[_service][_instance] = _major; if (is_connected_) { send_offer_service(_client, _service, _instance, _major, _minor); } else { @@ -151,6 +152,14 @@ void routing_manager_proxy::stop_offer_service(client_t _client, service_t _service, instance_t _instance) { (void)_client; + auto its_service = service_versions_.find(_service); + if (its_service != service_versions_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + its_service->second.clear(); + } + } + if (is_connected_) { byte_t its_command[VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE]; uint32_t its_size = VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE @@ -198,7 +207,7 @@ void routing_manager_proxy::release_service(client_t _client, void routing_manager_proxy::register_event(client_t _client, service_t _service, instance_t _instance, - event_t _event, std::set _eventgroups, + event_t _event, const std::set &_eventgroups, bool _is_field, bool _is_provided) { (void)_client; @@ -273,18 +282,22 @@ bool routing_manager_proxy::is_field(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) { + instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, + subscription_type_e _subscription_type) { if (is_connected_) { - send_subscribe(_client, _service, _instance, _eventgroup, _major); + send_subscribe(_client, _service, _instance, _eventgroup, _major, + _subscription_type); } else { - eventgroup_data_t subscription = { _service, _instance, _eventgroup, _major }; + eventgroup_data_t subscription = { _service, _instance, _eventgroup, _major, + _subscription_type}; std::lock_guard 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) { + instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, + subscription_type_e _subscription_type) { (void)_client; byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE]; @@ -303,6 +316,8 @@ void routing_manager_proxy::send_subscribe(client_t _client, service_t _service, 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], &_subscription_type, + sizeof(_subscription_type)); sender_->send(its_command, sizeof(its_command)); } @@ -436,6 +451,13 @@ void routing_manager_proxy::notify( its_notification->set_instance(_instance); its_notification->set_method(_event); its_notification->set_payload(_payload); + auto its_service = service_versions_.find(_service); + if (its_service != service_versions_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + its_notification->set_interface_version(its_instance->second); + } + } if (is_connected_) { send(VSOMEIP_ROUTING_CLIENT, its_notification, true); } else if (is_field(_service, _instance, _event)) { @@ -454,6 +476,13 @@ void routing_manager_proxy::notify_one(service_t _service, instance_t _instance, its_notification->set_method(_event); its_notification->set_payload(_payload); its_notification->set_client(_client); + auto its_service = service_versions_.find(_service); + if (its_service != service_versions_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + its_notification->set_interface_version(its_instance->second); + } + } send(VSOMEIP_ROUTING_CLIENT, its_notification, true); } @@ -713,7 +742,7 @@ void routing_manager_proxy::register_application() { std::lock_guard its_lock(pending_mutex_); for (auto &ps : pending_subscriptions_) send_subscribe(client_, ps.service_, ps.instance_, - ps.eventgroup_, ps.major_); + ps.eventgroup_, ps.major_, ps.subscription_type_); pending_offers_.clear(); pending_requests_.clear(); @@ -850,7 +879,7 @@ void routing_manager_proxy::send_request_service(client_t _client, service_t _se void routing_manager_proxy::send_register_event(client_t _client, service_t _service, instance_t _instance, - event_t _event, std::set _eventgroups, + event_t _event, const std::set &_eventgroups, bool _is_field, bool _is_provided) { if (is_connected_) { uint32_t its_eventgroups_size = uint32_t(_eventgroups.size() * sizeof(eventgroup_t)); diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index dfca76f..7f8aad8 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -124,6 +124,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, uint32_t its_size; bool its_reliable(false); bool use_exclusive_proxy(false); + subscription_type_e its_subscription_type; its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], @@ -186,9 +187,10 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, sizeof(its_eventgroup)); std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], sizeof(its_major)); - + std::memcpy(&its_subscription_type, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], + sizeof(its_subscription_type)); host_->subscribe(its_client, its_service, - its_instance, its_eventgroup, its_major); + its_instance, its_eventgroup, its_major, its_subscription_type); break; case VSOMEIP_UNSUBSCRIBE: diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index 76d316e..fea635e 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -52,7 +52,7 @@ public: VSOMEIP_EXPORT void offer_event(service_t _service, instance_t _instance, event_t _event, - std::set _eventgroups, + const std::set &_eventgroups, bool _is_field); VSOMEIP_EXPORT void stop_offer_event(service_t _service, instance_t _instance, event_t _event); @@ -66,13 +66,14 @@ public: VSOMEIP_EXPORT void request_event(service_t _service, instance_t _instance, event_t _event, - std::set _eventgroups, + const std::set &_eventgroups, bool _is_field); VSOMEIP_EXPORT void release_event(service_t _service, instance_t _instance, event_t _event); VSOMEIP_EXPORT void subscribe(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major); + eventgroup_t _eventgroup, major_version_t _major, + subscription_type_e _subscription_type); VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup); diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index f713e28..c9efed4 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -245,7 +245,9 @@ void application_impl::start() { } void application_impl::stop() { +#ifndef WIN32 // Gives serious problems under Windows. VSOMEIP_INFO << "Stopping vsomeip application \"" << name_ << "\""; +#endif std::lock_guard its_lock(start_stop_mutex_); is_dispatching_ = false; dispatch_condition_.notify_all(); @@ -293,9 +295,11 @@ void application_impl::release_service(service_t _service, } void application_impl::subscribe(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major) { + eventgroup_t _eventgroup, major_version_t _major, + subscription_type_e _subscription_type) { if (routing_) - routing_->subscribe(client_, _service, _instance, _eventgroup, _major); + routing_->subscribe(client_, _service, _instance, _eventgroup, _major, + _subscription_type); } void application_impl::unsubscribe(service_t _service, instance_t _instance, @@ -441,7 +445,7 @@ void application_impl::unregister_message_handler(service_t _service, } void application_impl::offer_event(service_t _service, instance_t _instance, - event_t _event, std::set _eventgroups, bool _is_field) { + event_t _event, const std::set &_eventgroups, bool _is_field) { if (routing_) routing_->register_event(client_, _service, _instance, _event, _eventgroups, _is_field, true); @@ -454,7 +458,7 @@ void application_impl::stop_offer_event(service_t _service, instance_t _instance } void application_impl::request_event(service_t _service, instance_t _instance, - event_t _event, std::set _eventgroups, bool _is_field) { + event_t _event, const std::set &_eventgroups, bool _is_field) { if (routing_) routing_->register_event(client_, _service, _instance, _event, _eventgroups, _is_field, false); diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp index e50ceca..2131da5 100644 --- a/implementation/runtime/src/runtime_impl.cpp +++ b/implementation/runtime/src/runtime_impl.cpp @@ -34,6 +34,7 @@ std::shared_ptr runtime_impl::create_message(bool _reliable) const { its_message->set_protocol_version(VSOMEIP_PROTOCOL_VERSION); its_message->set_return_code(return_code_e::E_OK); its_message->set_reliable(_reliable); + its_message->set_interface_version(DEFAULT_MAJOR); return (its_message); } @@ -44,6 +45,7 @@ std::shared_ptr runtime_impl::create_request(bool _reliable) const { 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); + its_request->set_interface_version(DEFAULT_MAJOR); return (its_request); } @@ -71,6 +73,7 @@ std::shared_ptr runtime_impl::create_notification( 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); + its_notification->set_interface_version(DEFAULT_MAJOR); return (its_notification); } diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index 38b414f..894de0c 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -7,8 +7,10 @@ #define VSOMEIP_SERVICE_DISCOVERY_HPP #include +#include #include +#include namespace vsomeip { @@ -33,14 +35,16 @@ public: 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, client_t _client) = 0; + eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client, + subscription_type_e _subscription_type) = 0; virtual void unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, client_t _client) = 0; virtual void unsubscribe_all(service_t _service, instance_t _instance) = 0; virtual void send(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, + const boost::asio::ip::address &_sender) = 0; virtual void on_offer_change() = 0; }; diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index de1dd93..27d8007 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -69,6 +69,9 @@ public: virtual std::shared_ptr find_or_create_remote_client(service_t _service, instance_t _instance, bool _reliable, client_t _client) = 0; + + virtual void expire_subscriptions(const boost::asio::ip::address &_address) = 0; + virtual void expire_services(const boost::asio::ip::address &_address) = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index 0aceb02..7efb6eb 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -12,7 +12,6 @@ #include #include -#include #include "service_discovery.hpp" #include "../../routing/include/types.hpp" @@ -54,21 +53,26 @@ public: 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); + eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client, + subscription_type_e _subscription_type); void unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, client_t _client); void unsubscribe_all(service_t _service, instance_t _instance); void send(bool _is_announcing); - void on_message(const byte_t *_data, length_t _length); + void on_message(const byte_t *_data, length_t _length, + const boost::asio::ip::address &_sender); void on_offer_change(); private: - session_t get_session(const boost::asio::ip::address &_address); + std::pair get_session(const boost::asio::ip::address &_address); void increment_session(const boost::asio::ip::address &_address); + bool is_reboot(const boost::asio::ip::address &_address, + bool _reboot_flag, session_t _session); + void insert_option(std::shared_ptr &_message, std::shared_ptr _entry, const boost::asio::ip::address &_address, uint16_t _port, @@ -134,6 +138,13 @@ private: major_version_t _major); bool check_layer_four_protocol( const std::shared_ptr _ip_option) const; + void get_subscription_endpoints(subscription_type_e _subscription_type, + std::shared_ptr& _unreliable, + std::shared_ptr& _reliable, + boost::asio::ip::address* _address, + bool* _has_address, + service_t _service, instance_t _instance, + client_t _client) const; private: boost::asio::io_service &io_; @@ -160,7 +171,11 @@ private: std::mutex serialize_mutex_; // Sessions - std::map sessions_; + std::map > sessions_; + std::map sessions_receiving_; + + // Reboots + std::set reboots_; // Runtime std::weak_ptr runtime_; diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp index bda9698..25df7b3 100644 --- a/implementation/service_discovery/include/subscription.hpp +++ b/implementation/service_discovery/include/subscription.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace vsomeip { @@ -20,7 +21,8 @@ class subscription { public: subscription(major_version_t _major, ttl_t _ttl, std::shared_ptr _reliable, - std::shared_ptr _unreliable); + std::shared_ptr _unreliable, + subscription_type_e _subscription_type); ~subscription(); major_version_t get_major() const; @@ -32,6 +34,8 @@ public: bool is_acknowledged() const; void set_acknowledged(bool _is_acknowledged); + subscription_type_e get_subscription_type() const; + private: major_version_t major_; ttl_t ttl_; @@ -40,6 +44,8 @@ private: std::shared_ptr unreliable_; bool is_acknowledged_; + + subscription_type_e subscription_type_; }; } // namespace sd diff --git a/implementation/service_discovery/src/configuration_option_impl.cpp b/implementation/service_discovery/src/configuration_option_impl.cpp index 67a9d4c..793ec95 100755 --- a/implementation/service_discovery/src/configuration_option_impl.cpp +++ b/implementation/service_discovery/src/configuration_option_impl.cpp @@ -92,29 +92,38 @@ bool configuration_option_impl::serialize(vsomeip::serializer *_to) const { bool configuration_option_impl::deserialize(vsomeip::deserializer *_from) { bool is_successful = option_impl::deserialize(_from); - uint8_t l_length = 0; + uint16_t l_length = 0; + uint8_t l_itemLength; 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(l_length); + if (l_length > _from->get_remaining()) { + _from->set_remaining(0); + return false; + } + + if (l_length > 0) { + do { + is_successful = is_successful && _from->deserialize(l_itemLength); + if (l_itemLength == 0) + break; + + l_length = uint16_t(l_length - l_itemLength); + 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; - } - } - } + && _from->deserialize((uint8_t*) &l_item[0], l_itemLength); + + size_t l_eqPos = l_item.find('='); + l_key = l_item.substr(0, l_eqPos); + l_value = l_item.substr(l_eqPos + 1); - } while (is_successful && l_length > 0); + if (configuration_.end() == configuration_.find(l_key)) { + configuration_[l_key] = l_value; + } else { + is_successful = false; + } + } while (l_length > 0); + } return is_successful; } diff --git a/implementation/service_discovery/src/option_impl.cpp b/implementation/service_discovery/src/option_impl.cpp index 71bbc6a..cff6d61 100755 --- a/implementation/service_discovery/src/option_impl.cpp +++ b/implementation/service_discovery/src/option_impl.cpp @@ -56,12 +56,8 @@ bool option_impl::deserialize(vsomeip::deserializer *_from) { break; default: type_ = option_type_e::UNKNOWN; - // reduce remaining bytes of the deserializer by the length of - // the unknown option to make it look like it was deserialized. - // - 1 because the reserved byte which is included in the length - // was already deserialized (s. above) - std::size_t remaining = _from->get_remaining(); - _from->set_remaining(remaining - (length_ - 1)); + // No valid option type --> ignore the remaining parts of the message! + _from->set_remaining(0); } } diff --git a/implementation/service_discovery/src/runtime_impl.cpp b/implementation/service_discovery/src/runtime_impl.cpp index f626cb3..2cc25d2 100644 --- a/implementation/service_discovery/src/runtime_impl.cpp +++ b/implementation/service_discovery/src/runtime_impl.cpp @@ -41,6 +41,8 @@ std::shared_ptr runtime_impl::create_message() const { its_message->set_interface_version(interface_version); its_message->set_message_type(message_type); its_message->set_return_code(return_code); + // reboot flag must be set dynamically + its_message->set_unicast_flag(true); return its_message; } diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index 38975fb..b5493b8 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -124,7 +124,8 @@ void service_discovery_impl::release_service(service_t _service, } void service_discovery_impl::subscribe(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client) { + eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client, + subscription_type_e _subscription_type) { std::lock_guard its_lock(subscribed_mutex_); auto found_service = subscribed_.find(_service); @@ -148,31 +149,18 @@ void service_discovery_impl::subscribe(service_t _service, instance_t _instance, } } - // New subscription - 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); - subscribed_[_service][_instance][_eventgroup][_client] = its_subscription; - + std::shared_ptr < endpoint > its_unreliable; + std::shared_ptr < endpoint > its_reliable; bool has_address(false); boost::asio::ip::address its_address; - std::shared_ptr its_endpoint - = host_->find_or_create_remote_client(_service, _instance, false, _client); + get_subscription_endpoints(_subscription_type, its_unreliable, its_reliable, + &its_address, &has_address, _service, _instance, _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); - } + // New subscription + std::shared_ptr < subscription > its_subscription = std::make_shared + < subscription > (_major, _ttl, its_reliable, its_unreliable, _subscription_type); + subscribed_[_service][_instance][_eventgroup][_client] = its_subscription; if (has_address) { std::shared_ptr its_runtime = runtime_.lock(); @@ -191,6 +179,69 @@ void service_discovery_impl::subscribe(service_t _service, instance_t _instance, } } +void service_discovery_impl::get_subscription_endpoints( + subscription_type_e _subscription_type, + std::shared_ptr& _unreliable, + std::shared_ptr& _reliable, boost::asio::ip::address* _address, + bool* _has_address, + service_t _service, instance_t _instance, client_t _client) const { + switch (_subscription_type) { + case subscription_type_e::SU_RELIABLE_AND_UNRELIABLE: + _reliable = host_->find_or_create_remote_client(_service, _instance, + true, _client); + _unreliable = host_->find_or_create_remote_client(_service, + _instance, false, _client); + if (_unreliable) { + *_has_address = _unreliable->get_remote_address(*_address); + } + if (_reliable) { + *_has_address = *_has_address + || _reliable->get_remote_address(*_address); + } + break; + case subscription_type_e::SU_PREFER_UNRELIABLE: + _unreliable = host_->find_or_create_remote_client(_service, + _instance, false, _client); + if (_unreliable) { + *_has_address = _unreliable->get_remote_address(*_address); + } else { + _reliable = host_->find_or_create_remote_client(_service, + _instance, true, _client); + if (_reliable) { + *_has_address = _reliable->get_remote_address(*_address); + } + } + break; + case subscription_type_e::SU_PREFER_RELIABLE: + _reliable = host_->find_or_create_remote_client(_service, + _instance, true, _client); + if (_reliable) { + *_has_address = _reliable->get_remote_address(*_address); + } else { + _unreliable = host_->find_or_create_remote_client(_service, + _instance, false, _client); + if (_unreliable) { + *_has_address = _unreliable->get_remote_address(*_address); + } + } + break; + case subscription_type_e::SU_UNRELIABLE: + _unreliable = host_->find_or_create_remote_client(_service, + _instance, + false, _client); + if (_unreliable) { + *_has_address = _unreliable->get_remote_address(*_address); + } + break; + case subscription_type_e::SU_RELIABLE: + _reliable = host_->find_or_create_remote_client(_service, _instance, + true, _client); + if (_reliable) { + *_has_address = _reliable->get_remote_address(*_address); + } + } +} + void service_discovery_impl::unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, client_t _client) { @@ -234,7 +285,10 @@ void service_discovery_impl::unsubscribe(service_t _service, insert_subscription(its_message, _service, _instance, _eventgroup, its_subscription); - its_message->set_session(get_session(its_address)); + + std::pair its_session = get_session(its_address); + its_message->set_session(its_session.first); + its_message->set_reboot_flag(its_session.second); serialize_and_send(its_message, its_address); } @@ -256,12 +310,12 @@ void service_discovery_impl::unsubscribe_all(service_t _service, instance_t _ins } } -session_t service_discovery_impl::get_session( +std::pair service_discovery_impl::get_session( const boost::asio::ip::address &_address) { - session_t its_session; + std::pair its_session; auto found_session = sessions_.find(_address); if (found_session == sessions_.end()) { - its_session = sessions_[_address] = 1; + its_session = sessions_[_address] = { 1, true }; } else { its_session = found_session->second; } @@ -272,14 +326,44 @@ 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? + found_session->second.first++; + if (found_session->second.first == 0) { // Wrap + found_session->second = { 1, false }; } } } +bool service_discovery_impl::is_reboot( + const boost::asio::ip::address &_address, + bool _reboot_flag, session_t _session) { + + bool result(false); +#ifdef VSOMEIP_TODO + // Reboot detection: Either the flag has changed from false to true, + // or the session identifier overrun while the flag is true + if (reboots_.find(_address) == reboots_.end()) { + if (_reboot_flag) { + reboots_.insert(_address); + result = true; + } + } else { + auto its_last_session = sessions_receiving_.find(_address); + if(its_last_session != sessions_receiving_.end()) { + if (_reboot_flag && its_last_session->second >= _session) { + result = true; + } + } + } + + sessions_receiving_[_address] = _session; +#else + (void)_address; + (void)_reboot_flag; + (void)_session; +#endif + return result; +} + void service_discovery_impl::insert_option( std::shared_ptr &_message, std::shared_ptr _entry, @@ -319,6 +403,9 @@ void service_discovery_impl::insert_option( if (its_option) { its_option->set_address(its_address); its_option->set_port(_port); + its_option->set_layer_four_protocol( + _is_reliable ? layer_four_protocol_e::TCP : + layer_four_protocol_e::UDP); _entry->assign_option(its_option, 1); } } else { @@ -328,6 +415,9 @@ void service_discovery_impl::insert_option( if (its_option) { its_option->set_address(its_address); its_option->set_port(_port); + its_option->set_layer_four_protocol( + _is_reliable ? layer_four_protocol_e::TCP : + layer_four_protocol_e::UDP); _entry->assign_option(its_option, 1); } } @@ -456,7 +546,9 @@ void service_discovery_impl::send(bool _is_announcing) { // Serialize and send if (its_message->get_entries().size() > 0) { - its_message->set_session(get_session(unicast_)); + std::pair its_session = get_session(unicast_); + its_message->set_session(its_session.first); + its_message->set_reboot_flag(its_session.second); if (host_->send(VSOMEIP_SD_CLIENT, its_message, true)) { increment_session (unicast_); } @@ -464,7 +556,8 @@ void service_discovery_impl::send(bool _is_announcing) { } // Interface endpoint_host -void service_discovery_impl::on_message(const byte_t *_data, length_t _length) { +void service_discovery_impl::on_message(const byte_t *_data, length_t _length, + const boost::asio::ip::address &_sender) { #if 0 std::stringstream msg; msg << "sdi::on_message: "; @@ -480,6 +573,13 @@ void service_discovery_impl::on_message(const byte_t *_data, length_t _length) { if(!check_static_header_fields(its_message)) { return; } + // Expire all subscriptions / services in case of reboot + if (is_reboot(_sender, + its_message->get_reboot_flag(), its_message->get_session())) { + host_->expire_subscriptions(_sender); + host_->expire_services(_sender); + } + ttl_t expired = stop_ttl_timer(); smallest_ttl_ = host_->update_routing_info(expired); @@ -637,12 +737,18 @@ void service_discovery_impl::process_offerservice_serviceentry( for (auto its_client : its_eventgroup.second) { std::shared_ptr its_subscription(its_client.second); if (its_subscription->is_acknowledged()) { - 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); + std::shared_ptr its_unreliable; + std::shared_ptr its_reliable; + bool has_address(false); + boost::asio::ip::address its_address; + get_subscription_endpoints( + its_client.second->get_subscription_type(), + its_unreliable, its_reliable, &its_address, + &has_address, _service, _instance, + its_client.first); + its_subscription->set_endpoint(its_reliable, true); + its_subscription->set_endpoint(its_unreliable, + false); // TODO: consume major & ttl insert_subscription(its_message, @@ -657,7 +763,7 @@ void service_discovery_impl::process_offerservice_serviceentry( if (0 < its_message->get_entries().size()) { std::shared_ptr its_target; - session_t its_session(0); + std::pair its_session; if (_reliable_port != ILLEGAL_PORT) { its_target = endpoint_definition::get( _reliable_address, port_, reliable_); @@ -669,7 +775,8 @@ void service_discovery_impl::process_offerservice_serviceentry( } if (its_target) { - its_message->set_session(its_session); + its_message->set_session(its_session.first); + its_message->set_reboot_flag(its_session.second); serializer_->serialize(its_message.get()); if (host_->send_to(its_target, serializer_->get_data(), @@ -1050,7 +1157,9 @@ void service_discovery_impl::handle_eventgroup_subscription_ack( void service_discovery_impl::serialize_and_send( std::shared_ptr _message, const boost::asio::ip::address &_address) { - _message->set_session(get_session(_address)); + std::pair its_session = get_session(_address); + _message->set_session(its_session.first); + _message->set_reboot_flag(its_session.second); if(!serializer_->serialize(_message.get())) { VSOMEIP_ERROR << "service_discovery_impl::serialize_and_send: serialization error."; return; diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp index 76b9c9f..dcb2461 100644 --- a/implementation/service_discovery/src/subscription.cpp +++ b/implementation/service_discovery/src/subscription.cpp @@ -10,10 +10,12 @@ namespace sd { subscription::subscription(major_version_t _major, ttl_t _ttl, std::shared_ptr _reliable, - std::shared_ptr _unreliable) + std::shared_ptr _unreliable, + subscription_type_e _subscription_type) : major_(_major), ttl_(_ttl), reliable_(_reliable), unreliable_(_unreliable), - is_acknowledged_(true) { + is_acknowledged_(true), + subscription_type_(_subscription_type) { } subscription::~subscription() { @@ -51,5 +53,9 @@ void subscription::set_acknowledged(bool _is_acknowledged) { is_acknowledged_ = _is_acknowledged; } +subscription_type_e subscription::get_subscription_type() const { + return subscription_type_; +} + } // namespace sd } // namespace vsomeip diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp index a366075..1b3f7eb 100644 --- a/implementation/utility/include/utility.hpp +++ b/implementation/utility/include/utility.hpp @@ -47,7 +47,7 @@ public: } static inline bool is_event(byte_t _data) { - return (0x80 & _data); + return (0x80 & _data) > 0; } static inline bool is_notification(byte_t _type) { diff --git a/interface/vsomeip/application.hpp b/interface/vsomeip/application.hpp index f08a91d..dc4784d 100644 --- a/interface/vsomeip/application.hpp +++ b/interface/vsomeip/application.hpp @@ -45,7 +45,7 @@ public: virtual void offer_event(service_t _service, instance_t _instance, event_t _event, - std::set _eventgroups, + const std::set &_eventgroups, bool _is_field) = 0; virtual void stop_offer_event(service_t _service, instance_t _instance, event_t _event) = 0; @@ -58,13 +58,14 @@ public: virtual void release_service(service_t _service, instance_t _instance) = 0; virtual void request_event(service_t _service, instance_t _instance, - event_t _event, std::set _eventgroups, + event_t _event, const std::set &_eventgroups, bool _is_field) = 0; virtual void release_event(service_t _service, instance_t _instance, event_t _event) = 0; virtual void subscribe(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major = DEFAULT_MAJOR) = 0; + eventgroup_t _eventgroup, major_version_t _major = DEFAULT_MAJOR, + subscription_type_e _subscription_type = subscription_type_e::SU_RELIABLE_AND_UNRELIABLE) = 0; virtual void unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup) = 0; diff --git a/interface/vsomeip/enumeration_types.hpp b/interface/vsomeip/enumeration_types.hpp index 8be8413..a71e677 100644 --- a/interface/vsomeip/enumeration_types.hpp +++ b/interface/vsomeip/enumeration_types.hpp @@ -46,6 +46,14 @@ enum class return_code_e : uint8_t { E_UNKNOWN = 0xFF }; +enum class subscription_type_e : uint8_t { + SU_RELIABLE_AND_UNRELIABLE = 0x00, + SU_PREFER_UNRELIABLE = 0x01, + SU_PREFER_RELIABLE = 0x02, + SU_UNRELIABLE = 0x03, + SU_RELIABLE = 0x04, +}; + } // namespace vsomeip #endif // VSOMEIP_ENUMERATION_TYPES_HPP diff --git a/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in b/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in index c95370b..bcb2e29 100644 --- a/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in +++ b/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in @@ -1,5 +1,5 @@ { - "unicast":"@TEST_IP_MASTER@", + "unicast":"@TEST_IP_SLAVE@", "netmask":"255.255.255.0", "logging": { @@ -24,7 +24,7 @@ { "service":"0x1234", "instance":"0x5678", - "unicast":"@TEST_IP_SLAVE@", + "unicast":"@TEST_IP_MASTER@", "reliable": { "port":"30509", diff --git a/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in b/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in index 629c99e..0e53c24 100644 --- a/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in +++ b/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in @@ -1,5 +1,5 @@ { - "unicast":"@TEST_IP_SLAVE@", + "unicast":"@TEST_IP_MASTER@", "logging": { "level":"debug", diff --git a/test/magic_cookies_tests/magic_cookies_test_starter.sh b/test/magic_cookies_tests/magic_cookies_test_starter.sh index ac97d61..e4308cd 100755 --- a/test/magic_cookies_tests/magic_cookies_test_starter.sh +++ b/test/magic_cookies_tests/magic_cookies_test_starter.sh @@ -10,81 +10,26 @@ # the testcase simply executes this script. This script then runs client # and service and checks that both exit successfully. -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 < to continue the test ******************************************************************************* ******************************************************************************* End-of-message -read # Start the client for magic-cookies test -export VSOMEIP_APPLICATION_NAME=magic_cookies_test_client -export VSOMEIP_CONFIGURATION=magic_cookies_test_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 +export VSOMEIP_APPLICATION_NAME=magic_cookies_test_service +export VSOMEIP_CONFIGURATION=magic_cookies_test_service.json +./magic_cookies_test_service --tcp --static-routing -# Check if server exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi +exit $? -- cgit v1.2.1