summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDirk Huss <dirk_huss@mentor.com>2015-12-09 14:50:34 +0100
committerDirk Huss <dirk_huss@mentor.com>2015-12-09 14:50:34 +0100
commit2b7442a4c2452f8f3bd9e0f09f829478256d39af (patch)
treee857c964b2a0a5d7e539efa00d17e6dccec5990a
parent78be04b467566633318a277ccd2d968c1c4e46bf (diff)
downloadvSomeIP-2b7442a4c2452f8f3bd9e0f09f829478256d39af.tar.gz
vSomeIP 2.0.12.0.1
-rw-r--r--CMakeLists.txt22
-rw-r--r--README90
-rw-r--r--examples/hello_world/hello_world_service.cpp26
-rw-r--r--implementation/configuration/include/configuration_impl.hpp86
-rw-r--r--implementation/configuration/include/internal.hpp.in2
-rw-r--r--implementation/endpoints/include/tcp_server_endpoint_impl.hpp1
-rw-r--r--implementation/endpoints/include/udp_server_endpoint_impl.hpp1
-rw-r--r--implementation/endpoints/src/local_client_endpoint_impl.cpp11
-rw-r--r--implementation/endpoints/src/tcp_server_endpoint_impl.cpp20
-rw-r--r--implementation/endpoints/src/udp_server_endpoint_impl.cpp11
-rw-r--r--implementation/logging/include/dlt_sink_backend.hpp44
-rw-r--r--implementation/logging/include/logger_impl.hpp5
-rw-r--r--implementation/logging/src/dlt_sink_backend.cpp66
-rw-r--r--implementation/logging/src/logger_impl.cpp9
-rw-r--r--implementation/routing/include/event.hpp6
-rw-r--r--implementation/routing/include/routing_manager.hpp4
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp8
-rw-r--r--implementation/routing/include/routing_manager_proxy.hpp12
-rw-r--r--implementation/routing/include/routing_manager_stub_host.hpp4
-rw-r--r--implementation/routing/src/event.cpp16
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp130
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp43
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp6
-rw-r--r--implementation/runtime/include/application_impl.hpp7
-rw-r--r--implementation/runtime/src/application_impl.cpp12
-rw-r--r--implementation/runtime/src/runtime_impl.cpp3
-rw-r--r--implementation/service_discovery/include/service_discovery.hpp8
-rw-r--r--implementation/service_discovery/include/service_discovery_host.hpp3
-rw-r--r--implementation/service_discovery/include/service_discovery_impl.hpp25
-rw-r--r--implementation/service_discovery/include/subscription.hpp8
-rwxr-xr-ximplementation/service_discovery/src/configuration_option_impl.cpp47
-rwxr-xr-ximplementation/service_discovery/src/option_impl.cpp8
-rw-r--r--implementation/service_discovery/src/runtime_impl.cpp2
-rw-r--r--implementation/service_discovery/src/service_discovery_impl.cpp191
-rw-r--r--implementation/service_discovery/src/subscription.cpp10
-rw-r--r--implementation/utility/include/utility.hpp2
-rw-r--r--interface/vsomeip/application.hpp7
-rw-r--r--interface/vsomeip/enumeration_types.hpp8
-rw-r--r--test/magic_cookies_tests/conf/magic_cookies_test_client.json.in4
-rw-r--r--test/magic_cookies_tests/conf/magic_cookies_test_service.json.in2
-rwxr-xr-xtest/magic_cookies_tests/magic_cookies_test_starter.sh65
41 files changed, 732 insertions, 303 deletions
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 <vsomeip/vsomeip.hpp>
+#include <chrono>
+#include <thread>
+#include <condition_variable>
+#include <mutex>
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<std::mutex> 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<std::mutex> its_lock(mutex_);
+ stop_ = true;
+ condition_.notify_one();
}
private:
std::shared_ptr<vsomeip::runtime> rtm_;
std::shared_ptr<vsomeip::application> 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<configuration> get(
+ VSOMEIP_EXPORT static std::shared_ptr<configuration> get(
const std::set<std::string> &_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<boost::property_tree::ptree> &_trees);
+ VSOMEIP_EXPORT void load(const boost::property_tree::ptree &_tree);
+ VSOMEIP_EXPORT void load_log(const std::vector<boost::property_tree::ptree> &_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<std::pair<service_t, instance_t> > get_remote_services() const;
+ VSOMEIP_EXPORT std::set<std::pair<service_t, instance_t> > 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 <dlt/dlt.h>
+#endif
+
+#include <boost/log/core.hpp>
+#include <boost/log/sinks/basic_sink_backend.hpp>
+#include <boost/log/trivial.hpp>
+
+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 <boost/log/trivial.hpp>
#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<sink_t> console_sink_;
boost::shared_ptr<sink_t> file_sink_;
- //boost::shared_ptr< dlt_sink > dlt_sink_;
+ boost::shared_ptr<dlt_sink_t> 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 <dlt/dlt.h>
+#endif
+
+#include <boost/log/expressions.hpp>
+
+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<dlt_sink_backend> backend = boost::make_shared<dlt_sink_backend>();
+ dlt_sink_ = boost::make_shared<dlt_sink_t>(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<eventgroup_t> _eventgroups,
+ event_t _event, const std::set<eventgroup_t> &_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<eventgroup_t> _eventgroups,
+ const std::set<eventgroup_t> &_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 <vsomeip/enumeration_types.hpp>
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<eventgroup_t> _eventgroups,
+ const std::set<eventgroup_t> &_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_t> _eventgroup,
+ const std::set<eventgroup_t> &_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<client_t, std::shared_ptr<endpoint> > local_endpoints_;
std::map<service_t, std::map<instance_t, client_t> > local_services_;
+ std::map<service_t, std::map<instance_t, major_version_t> > 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<eventgroup_t> _eventgroups,
+ const std::set<eventgroup_t> &_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<payload> 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<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]);
@@ -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<endpoint> its_unreliable_target = its_info->get_endpoint(false);
+ std::shared_ptr<endpoint> 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<eventgroup_t> _eventgroups,
+ event_t _event, const std::set<eventgroup_t> &_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<serviceinfo> 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<eventgroup_t> 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<std::mutex> 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<endpoint> 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<service_t,
+ std::map<instance_t,
+ std::pair<bool, bool> > > 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<endpoint> 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<std::shared_ptr<endpoint_definition>> 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<byte_t> (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<eventgroup_t> _eventgroups,
+ event_t _event, const std::set<eventgroup_t> &_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<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) {
+ 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<std::mutex> 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<eventgroup_t> _eventgroups,
+ event_t _event, const std::set<eventgroup_t> &_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<eventgroup_t> _eventgroups,
+ const std::set<eventgroup_t> &_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<eventgroup_t> _eventgroups,
+ const std::set<eventgroup_t> &_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<std::mutex> 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<eventgroup_t> _eventgroups, bool _is_field) {
+ event_t _event, const std::set<eventgroup_t> &_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<eventgroup_t> _eventgroups, bool _is_field) {
+ event_t _event, const std::set<eventgroup_t> &_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<message> 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<message> 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<message> 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 <boost/asio/io_service.hpp>
+#include <boost/asio/ip/address.hpp>
#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/enumeration_types.hpp>
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<endpoint> 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 <set>
#include <boost/asio/system_timer.hpp>
-#include <boost/asio/ip/address.hpp>
#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<session_t, bool> 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_impl> &_message,
std::shared_ptr<entry_impl> _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<const ip_option_impl> _ip_option) const;
+ void get_subscription_endpoints(subscription_type_e _subscription_type,
+ std::shared_ptr<endpoint>& _unreliable,
+ std::shared_ptr<endpoint>& _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<boost::asio::ip::address, session_t> sessions_;
+ std::map<boost::asio::ip::address, std::pair<session_t, bool> > sessions_;
+ std::map<boost::asio::ip::address, session_t > sessions_receiving_;
+
+ // Reboots
+ std::set<boost::asio::ip::address> reboots_;
// Runtime
std::weak_ptr<runtime> 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 <memory>
#include <vsomeip/primitive_types.hpp>
+#include <vsomeip/enumeration_types.hpp>
namespace vsomeip {
@@ -20,7 +21,8 @@ class subscription {
public:
subscription(major_version_t _major, ttl_t _ttl,
std::shared_ptr<endpoint> _reliable,
- std::shared_ptr<endpoint> _unreliable);
+ std::shared_ptr<endpoint> _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<endpoint> 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<message_impl> 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<std::mutex> 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<endpoint> 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<runtime> 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<endpoint>& _unreliable,
+ std::shared_ptr<endpoint>& _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<session_t, bool> 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<session_t, bool> service_discovery_impl::get_session(
const boost::asio::ip::address &_address) {
- session_t its_session;
+ std::pair<session_t, bool> 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_impl> &_message,
std::shared_ptr<entry_impl> _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<session_t, bool> 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<subscription> 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<endpoint> its_unreliable;
+ std::shared_ptr<endpoint> 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<endpoint_definition> its_target;
- session_t its_session(0);
+ std::pair<session_t, bool> 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_impl> _message,
const boost::asio::ip::address &_address) {
- _message->set_session(get_session(_address));
+ std::pair<session_t, bool> 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<endpoint> _reliable,
- std::shared_ptr<endpoint> _unreliable)
+ std::shared_ptr<endpoint> _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<eventgroup_t> _eventgroups,
+ const std::set<eventgroup_t> &_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<eventgroup_t> _eventgroups,
+ event_t _event, const std::set<eventgroup_t> &_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 <<End-of-message
*******************************************************************************
*******************************************************************************
** Please now run:
-** magic_cookies_test_service_start.sh
+** magic_cookies_test_client_start.sh
** from an external host to successfully complete this test.
**
** You probably will need to adapt the 'unicast' settings in
** magic_cookies_client.json and
** magic_cookies_service.json to your personal setup.
**
-** As soon as the service is started please press <RETURN> 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 $?